diff options
author | mjg <mjg@FreeBSD.org> | 2014-02-21 22:29:09 +0000 |
---|---|---|
committer | mjg <mjg@FreeBSD.org> | 2014-02-21 22:29:09 +0000 |
commit | 1c3ca2a367546ecfe8f196c7c9978e80a0f9e566 (patch) | |
tree | c81672ce7f32c1e7658b23b2396a697825b99f34 | |
parent | 25aa5dfa3c99035865f6fee952dac6ff716b2162 (diff) | |
download | FreeBSD-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.c | 4 |
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; |