summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2003-02-15 05:52:56 +0000
committeralfred <alfred@FreeBSD.org>2003-02-15 05:52:56 +0000
commitd9a7e5d6275ad9bb5fb49ed6879def1058777294 (patch)
treee6573e84f9435faccc517948a6e15ec04999d9b3 /sys/kern/kern_descrip.c
parent40ff51b25dfaa13508d632a1885e2773f419ff02 (diff)
downloadFreeBSD-src-d9a7e5d6275ad9bb5fb49ed6879def1058777294.zip
FreeBSD-src-d9a7e5d6275ad9bb5fb49ed6879def1058777294.tar.gz
Fix LOR with PROC/filedesc. Introduce fdesc_mtx that will be used as a
barrier between free'ing filedesc structures. Basically if you want to access another process's filedesc, you want to hold this mutex over the entire operation.
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index fe52ec1..5e2ac9b 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1366,6 +1366,10 @@ retry:
return (newfdp);
}
+/* A mutex to protect the association between a proc and filedesc. */
+struct mtx fdesc_mtx;
+MTX_SYSINIT(fdesc, &fdesc_mtx, "fdesc", MTX_DEF);
+
/*
* Release a filedesc structure.
*/
@@ -1382,6 +1386,10 @@ fdfree(td)
if (fdp == NULL)
return;
+ mtx_lock(&fdesc_mtx);
+ td->td_proc->p_fd = NULL;
+ mtx_unlock(&fdesc_mtx);
+
FILEDESC_LOCK(fdp);
if (--fdp->fd_refcnt > 0) {
FILEDESC_UNLOCK(fdp);
@@ -1398,7 +1406,6 @@ fdfree(td)
if (*fpp)
(void) closef(*fpp, td);
}
- td->td_proc->p_fd = NULL;
if (fdp->fd_nfiles > NDFILE)
FREE(fdp->fd_ofiles, M_FILEDESC);
if (fdp->fd_cdir)
@@ -2105,7 +2112,9 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
xf.xf_pid = p->p_pid;
xf.xf_uid = p->p_ucred->cr_uid;
PROC_UNLOCK(p);
+ mtx_lock(&fdesc_mtx);
if ((fdp = p->p_fd) == NULL) {
+ mtx_unlock(&fdesc_mtx);
continue;
}
FILEDESC_LOCK(fdp);
@@ -2125,6 +2134,7 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
break;
}
FILEDESC_UNLOCK(fdp);
+ mtx_unlock(&fdesc_mtx);
if (error)
break;
}
OpenPOWER on IntegriCloud