summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-02-07 10:30:49 +0000
committerkib <kib@FreeBSD.org>2007-02-07 10:30:49 +0000
commit0e5b15d726fe05f6c5c50c0dc9f7d5aed285d3c9 (patch)
tree8ea493a77b12f3dc48651402856803c2d9de34b1
parent2eb15b506b7d7b69a41d0fcdf2d7a806d723e4c7 (diff)
downloadFreeBSD-src-0e5b15d726fe05f6c5c50c0dc9f7d5aed285d3c9.zip
FreeBSD-src-0e5b15d726fe05f6c5c50c0dc9f7d5aed285d3c9.tar.gz
Fix the race of dereferencing /proc/<pid>/file with execve(2) by caching
the value of p_textvp. This way, we always unlock the locked vnode. While there, vhold() the vnode around the vn_lock(). Reported and tested by: Guy Helmer (ghelmer palisadesys com) Approved by: des (procfs maintainer) MFC after: 1 week
-rw-r--r--sys/fs/procfs/procfs.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
index 90d8975..d311a98 100644
--- a/sys/fs/procfs/procfs.c
+++ b/sys/fs/procfs/procfs.c
@@ -69,10 +69,18 @@ procfs_doprocfile(PFS_FILL_ARGS)
{
char *fullpath = "unknown";
char *freepath = NULL;
-
- vn_lock(p->p_textvp, LK_EXCLUSIVE | LK_RETRY, td);
- vn_fullpath(td, p->p_textvp, &fullpath, &freepath);
- VOP_UNLOCK(p->p_textvp, 0, td);
+ struct vnode *textvp;
+ int err;
+
+ textvp = p->p_textvp;
+ VI_LOCK(textvp);
+ vholdl(textvp);
+ err = vn_lock(textvp, LK_EXCLUSIVE | LK_INTERLOCK, td);
+ vdrop(textvp);
+ if (err)
+ return (err);
+ vn_fullpath(td, textvp, &fullpath, &freepath);
+ VOP_UNLOCK(textvp, 0, td);
sbuf_printf(sb, "%s", fullpath);
if (freepath)
free(freepath, M_TEMP);
OpenPOWER on IntegriCloud