Eliminate a couple of reference count and mutex leaks.

This commit is contained in:
ad 2007-02-11 17:16:08 +00:00
parent 6fa495aa59
commit c18c0d2eaa
1 changed files with 30 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs_vnops.c,v 1.145 2007/02/09 21:55:36 ad Exp $ */ /* $NetBSD: procfs_vnops.c,v 1.146 2007/02/11 17:16:08 ad Exp $ */
/*- /*-
* Copyright (c) 2006 The NetBSD Foundation, Inc. * Copyright (c) 2006 The NetBSD Foundation, Inc.
@ -112,7 +112,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.145 2007/02/09 21:55:36 ad Exp $"); __KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.146 2007/02/11 17:16:08 ad Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -647,7 +647,7 @@ procfs_getattr(v)
case PFSexe: case PFSexe:
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP, MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
M_WAITOK|M_CANFAIL); M_WAITOK|M_CANFAIL);
if (path == NULL) { if (path == NULL && procp != NULL) {
procfs_proc_unlock(procp); procfs_proc_unlock(procp);
return (ENOMEM); return (ENOMEM);
} }
@ -660,8 +660,10 @@ procfs_getattr(v)
if (procp != NULL) { if (procp != NULL) {
mutex_enter(&procp->p_mutex); mutex_enter(&procp->p_mutex);
if (kauth_authorize_process(kauth_cred_get(), error = kauth_authorize_process(kauth_cred_get(),
KAUTH_PROCESS_CANSEE, procp, NULL, NULL, NULL) != 0) { KAUTH_PROCESS_CANSEE, procp, NULL, NULL, NULL);
mutex_exit(&procp->p_mutex);
if (error != 0) {
procfs_proc_unlock(procp); procfs_proc_unlock(procp);
if (path != NULL) if (path != NULL)
free(path, M_TEMP); free(path, M_TEMP);
@ -880,11 +882,8 @@ procfs_getattr(v)
panic("procfs_getattr"); panic("procfs_getattr");
} }
if (procp != NULL) { if (procp != NULL)
mutex_exit(&procp->p_mutex);
procfs_proc_unlock(procp); procfs_proc_unlock(procp);
}
if (path != NULL) if (path != NULL)
free(path, M_TEMP); free(path, M_TEMP);
@ -971,11 +970,12 @@ procfs_lookup(v)
const char *pname = cnp->cn_nameptr; const char *pname = cnp->cn_nameptr;
const struct proc_target *pt = NULL; const struct proc_target *pt = NULL;
struct vnode *fvp; struct vnode *fvp;
pid_t pid; pid_t pid, vnpid;
struct pfsnode *pfs; struct pfsnode *pfs;
struct proc *p = NULL; struct proc *p = NULL;
struct lwp *l = NULL; struct lwp *l = NULL;
int i, error, iscurproc = 0, isself = 0; int i, error;
pfstype type;
*vpp = NULL; *vpp = NULL;
@ -997,15 +997,6 @@ procfs_lookup(v)
if (cnp->cn_flags & ISDOTDOT) if (cnp->cn_flags & ISDOTDOT)
return (EIO); return (EIO);
iscurproc = CNEQ(cnp, "curproc", 7);
isself = CNEQ(cnp, "self", 4);
if (iscurproc || isself) {
error = procfs_allocvp(dvp->v_mount, vpp, 0,
iscurproc ? PFScurproc : PFSself, -1, NULL);
return (error);
}
for (i = 0; i < nproc_root_targets; i++) { for (i = 0; i < nproc_root_targets; i++) {
pt = &proc_root_targets[i]; pt = &proc_root_targets[i];
if (cnp->cn_namelen == pt->pt_namlen && if (cnp->cn_namelen == pt->pt_namlen &&
@ -1021,12 +1012,23 @@ procfs_lookup(v)
return (error); return (error);
} }
pid = (pid_t)atoi(pname, cnp->cn_namelen); if (CNEQ(cnp, "curproc", 7)) {
pid = curproc->p_pid;
vnpid = 0;
type = PFScurproc;
} else if (CNEQ(cnp, "self", 4)) {
pid = curproc->p_pid;
vnpid = 0;
type = PFSself;
} else {
pid = (pid_t)atoi(pname, cnp->cn_namelen);
vnpid = pid;
type = PFSproc;
}
if (procfs_proc_lock(pid, &p, ESRCH) != 0) if (procfs_proc_lock(pid, &p, ESRCH) != 0)
break; break;
error = procfs_allocvp(dvp->v_mount, vpp, vnpid, type, -1, p);
error = procfs_allocvp(dvp->v_mount, vpp, pid, PFSproc, -1, p);
procfs_proc_unlock(p); procfs_proc_unlock(p);
return (error); return (error);
@ -1054,14 +1056,17 @@ procfs_lookup(v)
(*pt->pt_valid)(cnp->cn_lwp, dvp->v_mount))) (*pt->pt_valid)(cnp->cn_lwp, dvp->v_mount)))
break; break;
} }
if (i == nproc_targets) if (i == nproc_targets) {
procfs_proc_unlock(p);
break; break;
}
if (pt->pt_pfstype == PFSfile) { if (pt->pt_pfstype == PFSfile) {
fvp = p->p_textvp; fvp = p->p_textvp;
/* We already checked that it exists. */ /* We already checked that it exists. */
VREF(fvp); VREF(fvp);
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY); vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
*vpp = fvp; *vpp = fvp;
procfs_proc_unlock(p);
return (0); return (0);
} }
@ -1086,8 +1091,8 @@ procfs_lookup(v)
VOP_UNLOCK(dvp, 0); VOP_UNLOCK(dvp, 0);
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
PFSproc, -1, p); PFSproc, -1, p);
procfs_proc_unlock(p);
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
procfs_proc_unlock(p);
return (error); return (error);
} }
fd = atoi(pname, cnp->cn_namelen); fd = atoi(pname, cnp->cn_namelen);