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:
parent
3055b7c6ff
commit
6b97c9f09a
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user