summaryrefslogtreecommitdiffstats
path: root/sys/rpc
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2013-04-08 19:03:01 +0000
committerjhb <jhb@FreeBSD.org>2013-04-08 19:03:01 +0000
commit4312ec3f0dd92a3dedf58a28ebc6f4ae3a1a7672 (patch)
tree13366d646862c52df55b1c45000dd9d3c0e08eed /sys/rpc
parent52f6f6d83eb2c4356b916617d45ecd58d775c3bd (diff)
downloadFreeBSD-src-4312ec3f0dd92a3dedf58a28ebc6f4ae3a1a7672.zip
FreeBSD-src-4312ec3f0dd92a3dedf58a28ebc6f4ae3a1a7672.tar.gz
Fix a potential socket leak in the NFS server. If a client closes its
connection after it was accepted by the userland nfsd process but before it was handled off to svc_vc_create() in the kernel, then svc_vc_create() would see it as a new listen socket and try to listen on it leaving a dangling reference to the socket. Instead, check for disconnected sockets and treat them like a connected socket. The call to pru_getaddr() should fail and cause svc_vc_create() to fail. Note that we need to lock the socket to get a consistent snapshot of so_state since there is a window in soisdisconnected() where both flags are clear. Reviewed by: dfr, rmacklem MFC after: 1 week
Diffstat (limited to 'sys/rpc')
-rw-r--r--sys/rpc/svc_vc.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 80824ef..54fa546 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -146,7 +146,9 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
struct sockaddr* sa;
int error;
- if (so->so_state & SS_ISCONNECTED) {
+ SOCK_LOCK(so);
+ if (so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED)) {
+ SOCK_UNLOCK(so);
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
if (error)
return (NULL);
@@ -154,6 +156,7 @@ svc_vc_create(SVCPOOL *pool, struct socket *so, size_t sendsize,
free(sa, M_SONAME);
return (xprt);
}
+ SOCK_UNLOCK(so);
xprt = svc_xprt_alloc();
sx_init(&xprt->xp_lock, "xprt->xp_lock");
OpenPOWER on IntegriCloud