Date: Thu, 9 Jul 2015 15:06:25 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285319 - head/sys/kern Message-ID: <201507091506.t69F6Pli098043@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mjg Date: Thu Jul 9 15:06:24 2015 New Revision: 285319 URL: https://svnweb.freebsd.org/changeset/base/285319 Log: vfs: plug a use-after-free of fd_rdir in namei fd_rdir vnode was stored in ni_rootdir without refing it in any way, after which the filedsc lock was being dropped. The vnode could have been freed by mountcheckdirs or another thread doing chroot. VREF the vnode while the lock is held. Reviewed by: kib MFC after: 1 week Modified: head/sys/kern/vfs_lookup.c Modified: head/sys/kern/vfs_lookup.c ============================================================================== --- head/sys/kern/vfs_lookup.c Thu Jul 9 14:14:44 2015 (r285318) +++ head/sys/kern/vfs_lookup.c Thu Jul 9 15:06:24 2015 (r285319) @@ -210,6 +210,7 @@ namei(struct nameidata *ndp) */ FILEDESC_SLOCK(fdp); ndp->ni_rootdir = fdp->fd_rdir; + VREF(ndp->ni_rootdir); ndp->ni_topdir = fdp->fd_jdir; /* @@ -260,6 +261,7 @@ namei(struct nameidata *ndp) } } if (error) { + vrele(ndp->ni_rootdir); namei_cleanup_cnp(cnp); return (error); } @@ -286,6 +288,7 @@ namei(struct nameidata *ndp) if (KTRPOINT(curthread, KTR_CAPFAIL)) ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL); #endif + vrele(ndp->ni_rootdir); namei_cleanup_cnp(cnp); return (ENOTCAPABLE); } @@ -299,6 +302,7 @@ namei(struct nameidata *ndp) ndp->ni_startdir = dp; error = lookup(ndp); if (error) { + vrele(ndp->ni_rootdir); namei_cleanup_cnp(cnp); SDT_PROBE(vfs, namei, lookup, return, error, NULL, 0, 0, 0); @@ -308,6 +312,7 @@ namei(struct nameidata *ndp) * If not a symbolic link, we're done. */ if ((cnp->cn_flags & ISSYMLINK) == 0) { + vrele(ndp->ni_rootdir); if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) { namei_cleanup_cnp(cnp); } else @@ -371,6 +376,7 @@ namei(struct nameidata *ndp) vput(ndp->ni_vp); dp = ndp->ni_dvp; } + vrele(ndp->ni_rootdir); namei_cleanup_cnp(cnp); vput(ndp->ni_vp); ndp->ni_vp = NULL;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507091506.t69F6Pli098043>