From: Sascha Wildner Date: Tue, 21 Aug 2012 18:57:19 +0000 (+0200) Subject: kernel/linprocfs: Fix accessing files in /proc (such as /proc/meminfo). X-Git-Tag: v3.2.0~303 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/96a686f903f23302471b538c669c9b0cf3eff5e9 kernel/linprocfs: Fix accessing files in /proc (such as /proc/meminfo). It is the same fix that was applied to procfs with 198c0ff2. --- diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs.h b/sys/emulation/linux/i386/linprocfs/linprocfs.h index 488c5c2..aba5d72 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs.h +++ b/sys/emulation/linux/i386/linprocfs/linprocfs.h @@ -136,6 +136,7 @@ int linprocfs_freevp (struct vnode *); int linprocfs_allocvp (struct mount *, struct vnode **, long, pfstype); int linprocfs_sstep (struct proc *); void linprocfs_fix_sstep (struct proc *); +struct proc *linprocfs_pfind(pid_t pfs_pid); #if 0 int linprocfs_read_regs (struct proc *, struct reg *); int linprocfs_write_regs (struct proc *, struct reg *); diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c index 8dc4f8f..d2db8e3 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c @@ -251,6 +251,26 @@ linprocfs_freevp(struct vnode *vp) return (0); } +/* + * Try to find the calling pid. Note that pfind() + * now references the proc structure to be returned + * and needs to be released later with PRELE(). + */ +struct proc * +linprocfs_pfind(pid_t pfs_pid) +{ + struct proc *p = NULL; + + if (pfs_pid == 0) { + p = &proc0; + PHOLD(p); + } else { + p = pfind(pfs_pid); + } + + return p; +} + int linprocfs_rw(struct vop_read_args *ap) { @@ -266,12 +286,14 @@ linprocfs_rw(struct vop_read_args *ap) curp = td->td_proc; KKASSERT(curp); - p = pfind(pfs->pfs_pid); - if (p == NULL) - return (EINVAL); + p = linprocfs_pfind(pfs->pfs_pid); + if (p == NULL) { + rtval = EINVAL; + goto out; + } if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) { - PRELE(p); - return (EACCES); + rtval = EACCES; + goto out; } lp = FIRST_LWP_IN_PROC(p); LWPHOLD(lp); @@ -340,12 +362,14 @@ linprocfs_rw(struct vop_read_args *ap) break; } LWPRELE(lp); - PRELE(p); lwkt_gettoken(&pfs_token); pfs->pfs_lockowner = NULL; wakeup(&pfs->pfs_lockowner); lwkt_reltoken(&pfs_token); +out: + if (p) + PRELE(p); return rtval; } diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c index 77d1f3a..7ea3061 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c @@ -177,7 +177,7 @@ linprocfs_open(struct vop_open_args *ap) struct pfsnode *pfs = VTOPFS(ap->a_vp); struct proc *p2; - p2 = PFIND(pfs->pfs_pid); + p2 = linprocfs_pfind(pfs->pfs_pid); if (p2 == NULL) return (ENOENT); if (pfs->pfs_pid && !PRISON_CHECK(ap->a_cred, p2->p_ucred)) @@ -231,7 +231,7 @@ linprocfs_close(struct vop_close_args *ap) */ p = NULL; if ((ap->a_vp->v_opencount < 2) - && (p = pfind(pfs->pfs_pid)) + && (p = linprocfs_pfind(pfs->pfs_pid)) && !(p->p_pfsflags & PF_LINGER)) { p->p_stops = 0; p->p_step = 0; @@ -260,7 +260,7 @@ linprocfs_ioctl(struct vop_ioctl_args *ap) struct procfs_status *psp; unsigned char flags; - procp = pfind(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL) { return ENOTTY; } @@ -465,7 +465,7 @@ linprocfs_getattr(struct vop_getattr_args *ap) break; default: - procp = PFIND(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL || procp->p_ucred == NULL) return (ENOENT); } @@ -844,7 +844,7 @@ linprocfs_lookup(struct vop_old_lookup_args *ap) if (pid == NO_PID) break; - p = PFIND(pid); + p = linprocfs_pfind(pid); if (p == NULL) break; @@ -864,7 +864,7 @@ linprocfs_lookup(struct vop_old_lookup_args *ap) goto out; } - p = PFIND(pfs->pfs_pid); + p = linprocfs_pfind(pfs->pfs_pid); if (p == NULL) break; @@ -991,7 +991,7 @@ linprocfs_readdir_proc(struct vop_readdir_args *ap) struct uio *uio = ap->a_uio; pfs = VTOPFS(ap->a_vp); - p = PFIND(pfs->pfs_pid); + p = linprocfs_pfind(pfs->pfs_pid); if (p == NULL) return(0); if (!PRISON_CHECK(ap->a_cred, p->p_ucred)) @@ -1517,7 +1517,7 @@ linprocfs_readlink(struct vop_readlink_args *ap) * from under us... */ case Pexe: - procp = PFIND(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL || procp->p_ucred == NULL) { kprintf("linprocfs_readlink: pid %d disappeared\n", pfs->pfs_pid); @@ -1532,7 +1532,7 @@ linprocfs_readlink(struct vop_readlink_args *ap) kfree(freepath, M_TEMP); return (error); case Pcwd: - procp = PFIND(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL || procp->p_ucred == NULL) { kprintf("linprocfs_readlink: pid %d disappeared\n", pfs->pfs_pid); @@ -1547,7 +1547,7 @@ linprocfs_readlink(struct vop_readlink_args *ap) kfree(freepath, M_TEMP); return (error); case Pprocroot: - procp = PFIND(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL || procp->p_ucred == NULL) { kprintf("linprocfs_readlink: pid %d disappeared\n", pfs->pfs_pid); @@ -1563,7 +1563,7 @@ linprocfs_readlink(struct vop_readlink_args *ap) kfree(freepath, M_TEMP); return (error); case Pfd: - procp = PFIND(pfs->pfs_pid); + procp = linprocfs_pfind(pfs->pfs_pid); if (procp == NULL || procp->p_ucred == NULL) { kprintf("linprocfs_readlink: pid %d disappeared\n", pfs->pfs_pid);