From 9d0447413ec7291011056d7ab05a8e73a19b6997 Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Sat, 25 Aug 2007 23:27:02 +0000 Subject: [PATCH] Fix a bug in linprocfs and hold lwps to prevent a race condition. Linprocfs rolls its own prototype for procfs_domem. The function was changed to take a struct lwp *, but neither the private prototype, nor the procfs_domem call were changed accordingly. As a result any access to the linprocfs process memory file resulted in a panic. Procfs and linprocs perform potentially blocking calls, so HOLD and RELE the lwps so that they can't be destroyed while procfs is blocked. --- sys/emulation/linux/i386/linprocfs/linprocfs_subr.c | 10 +++++++--- sys/vfs/procfs/procfs_subr.c | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c index 4299e3cf87..6debe5761d 100644 --- a/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c +++ b/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c @@ -39,7 +39,7 @@ * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_subr.c,v 1.3.2.4 2001/06/25 19:46:47 pirzyk Exp $ - * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v 1.22 2007/05/06 19:23:28 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v 1.23 2007/08/25 23:27:02 corecode Exp $ */ #include @@ -57,7 +57,7 @@ static struct pfsnode *pfshead[PFSHSIZE]; static struct lwkt_token pfs_token; static int pfsvplock; -extern int procfs_domem (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio); +extern int procfs_domem (struct proc *, struct lwp *, struct pfsnode *pfsp, struct uio *uio); /* * allocate a pfsnode/vnode pair. the vnode is @@ -249,6 +249,7 @@ linprocfs_rw(struct vop_read_args *ap) struct pfsnode *pfs = VTOPFS(vp); struct proc *p; struct proc *curp; + struct lwp *lp; int rtval; curp = td->td_proc; @@ -259,6 +260,8 @@ linprocfs_rw(struct vop_read_args *ap) return (EINVAL); if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) return (EACCES); + lp = FIRST_LWP_IN_PROC(p); + LWPHOLD(lp); while (pfs->pfs_lockowner) { tsleep(&pfs->pfs_lockowner, 0, "pfslck", 0); @@ -267,7 +270,7 @@ linprocfs_rw(struct vop_read_args *ap) switch (pfs->pfs_type) { case Pmem: - rtval = procfs_domem(curp, p, pfs, uio); + rtval = procfs_domem(curp, lp, pfs, uio); break; case Pprocstat: rtval = linprocfs_doprocstat(curp, p, pfs, uio); @@ -297,6 +300,7 @@ linprocfs_rw(struct vop_read_args *ap) rtval = EOPNOTSUPP; break; } + LWPRELE(lp); pfs->pfs_lockowner = NULL; wakeup(&pfs->pfs_lockowner); return rtval; diff --git a/sys/vfs/procfs/procfs_subr.c b/sys/vfs/procfs/procfs_subr.c index 2e784915e8..0759570dae 100644 --- a/sys/vfs/procfs/procfs_subr.c +++ b/sys/vfs/procfs/procfs_subr.c @@ -37,7 +37,7 @@ * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * * $FreeBSD: src/sys/miscfs/procfs/procfs_subr.c,v 1.26.2.3 2002/02/18 21:28:04 des Exp $ - * $DragonFly: src/sys/vfs/procfs/procfs_subr.c,v 1.17 2007/05/06 19:23:35 dillon Exp $ + * $DragonFly: src/sys/vfs/procfs/procfs_subr.c,v 1.18 2007/08/25 23:27:02 corecode Exp $ */ #include @@ -279,6 +279,7 @@ procfs_rw(struct vop_read_args *ap) return (EACCES); /* XXX lwp */ lp = FIRST_LWP_IN_PROC(p); + LWPHOLD(lp); while (pfs->pfs_lockowner) { tsleep(&pfs->pfs_lockowner, 0, "pfslck", 0); @@ -335,6 +336,7 @@ procfs_rw(struct vop_read_args *ap) rtval = EOPNOTSUPP; break; } + LWPRELE(lp); pfs->pfs_lockowner = 0; wakeup(&pfs->pfs_lockowner); return rtval; -- 2.11.4.GIT