summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2014-02-21 22:29:09 +0000
committermjg <mjg@FreeBSD.org>2014-02-21 22:29:09 +0000
commit1c3ca2a367546ecfe8f196c7c9978e80a0f9e566 (patch)
treec81672ce7f32c1e7658b23b2396a697825b99f34
parent25aa5dfa3c99035865f6fee952dac6ff716b2162 (diff)
downloadFreeBSD-src-1c3ca2a367546ecfe8f196c7c9978e80a0f9e566.zip
FreeBSD-src-1c3ca2a367546ecfe8f196c7c9978e80a0f9e566.tar.gz
Fix a race between kern_proc_{o,}filedesc_out and fdescfree leading
to use-after-free. fdescfree proceeds to free file pointers once fd_refcnt reaches 0, but kern_proc_{o,}filedesc_out only checked for hold count. MFC after: 3 days
-rw-r--r--sys/kern/kern_descrip.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 314718f..985a5cf 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3056,7 +3056,7 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
if (fdp->fd_jdir != NULL)
export_vnode_for_osysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
fdp, req);
- for (i = 0; i < fdp->fd_nfiles; i++) {
+ for (i = 0; fdp->fd_refcnt > 0 && i < fdp->fd_nfiles; i++) {
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
continue;
bzero(kif, sizeof(*kif));
@@ -3424,7 +3424,7 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL,
FREAD, -1, -1, NULL, efbuf);
}
- for (i = 0; i < fdp->fd_nfiles; i++) {
+ for (i = 0; fdp->fd_refcnt > 0 && i < fdp->fd_nfiles; i++) {
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
continue;
data = NULL;
OpenPOWER on IntegriCloud