Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jun 2009 22:50:26 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r194407 - in head/sys: nfsserver nlm rpc
Message-ID:  <200906172250.n5HMoQZV090661@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Jun 17 22:50:26 2009
New Revision: 194407
URL: http://svn.freebsd.org/changeset/base/194407

Log:
  Since svc_[dg|vc|tli|tp]_create() did not hold a reference count on the
  SVCXPTR structure returned by them, it was possible for the structure
  to be free'd before svc_reg() had been completed using the structure.
  This patch acquires a reference count on the newly created structure
  that is returned by svc_[dg|vc|tli|tp]_create(). It also
  adds the appropriate SVC_RELEASE() calls to the callers, except the
  experimental nfs subsystem. The latter will be committed separately.
  
  Submitted by:	dfr
  Tested by:	pho
  Approved by:	kib (mentor)

Modified:
  head/sys/nfsserver/nfs_srvkrpc.c
  head/sys/nlm/nlm_prot_impl.c
  head/sys/rpc/svc.c
  head/sys/rpc/svc_generic.c
  head/sys/rpc/svc_vc.c

Modified: head/sys/nfsserver/nfs_srvkrpc.c
==============================================================================
--- head/sys/nfsserver/nfs_srvkrpc.c	Wed Jun 17 21:58:32 2009	(r194406)
+++ head/sys/nfsserver/nfs_srvkrpc.c	Wed Jun 17 22:50:26 2009	(r194407)
@@ -467,6 +467,7 @@ nfssvc_addsock(struct file *fp, struct t
 		fp->f_data = NULL;
 		svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL);
 		svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL);
+		SVC_RELEASE(xprt);
 	}
 
 	return (0);

Modified: head/sys/nlm/nlm_prot_impl.c
==============================================================================
--- head/sys/nlm/nlm_prot_impl.c	Wed Jun 17 21:58:32 2009	(r194406)
+++ head/sys/nlm/nlm_prot_impl.c	Wed Jun 17 22:50:26 2009	(r194407)
@@ -1389,7 +1389,7 @@ nlm_register_services(SVCPOOL *pool, int
 		return (EINVAL);
 	}
 
-	xprts = malloc(addr_count * sizeof(SVCXPRT *), M_NLM, M_WAITOK);
+	xprts = malloc(addr_count * sizeof(SVCXPRT *), M_NLM, M_WAITOK|M_ZERO);
 	for (i = 0; i < version_count; i++) {
 		for (j = 0; j < addr_count; j++) {
 			/*
@@ -1447,6 +1447,10 @@ nlm_register_services(SVCPOOL *pool, int
 	}
 	error = 0;
 out:
+	for (j = 0; j < addr_count; j++) {
+		if (xprts[j])
+			SVC_RELEASE(xprts[j]);
+	}
 	free(xprts, M_NLM);
 	return (error);
 }

Modified: head/sys/rpc/svc.c
==============================================================================
--- head/sys/rpc/svc.c	Wed Jun 17 21:58:32 2009	(r194406)
+++ head/sys/rpc/svc.c	Wed Jun 17 22:50:26 2009	(r194407)
@@ -276,6 +276,7 @@ xprt_register(SVCXPRT *xprt)
 {
 	SVCPOOL *pool = xprt->xp_pool;
 
+	SVC_ACQUIRE(xprt);
 	mtx_lock(&pool->sp_lock);
 	xprt->xp_registered = TRUE;
 	xprt->xp_active = FALSE;

Modified: head/sys/rpc/svc_generic.c
==============================================================================
--- head/sys/rpc/svc_generic.c	Wed Jun 17 21:58:32 2009	(r194406)
+++ head/sys/rpc/svc_generic.c	Wed Jun 17 22:50:26 2009	(r194407)
@@ -120,8 +120,10 @@ svc_create(
 			/* It was not found. Now create a new one */
 			xprt = svc_tp_create(pool, dispatch, prognum, versnum,
 			    NULL, nconf);
-			if (xprt)
+			if (xprt) {
 				num++;
+				SVC_RELEASE(xprt);
+			}
 		}
 	}
 	__rpc_endconf(handle);
@@ -179,6 +181,7 @@ svc_tp_create(
 				(unsigned)prognum, (unsigned)versnum,
 				nconf->nc_netid);
 		xprt_unregister(xprt);
+		SVC_RELEASE(xprt);
 		return (NULL);
 	}
 	return (xprt);

Modified: head/sys/rpc/svc_vc.c
==============================================================================
--- head/sys/rpc/svc_vc.c	Wed Jun 17 21:58:32 2009	(r194406)
+++ head/sys/rpc/svc_vc.c	Wed Jun 17 22:50:26 2009	(r194407)
@@ -324,6 +324,7 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, st
 	struct socket *so = NULL;
 	struct sockaddr *sa = NULL;
 	int error;
+	SVCXPRT *new_xprt;
 
 	/*
 	 * The socket upcall calls xprt_active() which will eventually
@@ -383,10 +384,14 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, st
 
 	/*
 	 * svc_vc_create_conn will call xprt_register - we don't need
-	 * to do anything with the new connection.
+	 * to do anything with the new connection except derefence it.
 	 */
-	if (!svc_vc_create_conn(xprt->xp_pool, so, sa))
+	new_xprt = svc_vc_create_conn(xprt->xp_pool, so, sa);
+	if (!new_xprt) {
 		soclose(so);
+	} else {
+		SVC_RELEASE(new_xprt);
+	}
 
 	free(sa, M_SONAME);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906172250.n5HMoQZV090661>