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)
This commit is contained in:
Rick Macklem 2009-06-17 22:50:26 +00:00
parent 3055b7c6ff
commit 6b97c9f09a
5 changed files with 18 additions and 4 deletions

View File

@ -467,6 +467,7 @@ nfssvc_addsock(struct file *fp, struct thread *td)
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);

View File

@ -1389,7 +1389,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs)
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 addr_count, char **addrs)
}
error = 0;
out:
for (j = 0; j < addr_count; j++) {
if (xprts[j])
SVC_RELEASE(xprts[j]);
}
free(xprts, M_NLM);
return (error);
}

View File

@ -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;

View File

@ -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);

View File

@ -324,6 +324,7 @@ svc_vc_rendezvous_recv(SVCXPRT *xprt, struct rpc_msg *msg,
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, struct rpc_msg *msg,
/*
* 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);