From owner-svn-src-all@freebsd.org Thu Jul 9 15:06:25 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BA8EC9974CA; Thu, 9 Jul 2015 15:06:25 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9149C149D; Thu, 9 Jul 2015 15:06:25 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.14.9/8.14.9) with ESMTP id t69F6P1v098044; Thu, 9 Jul 2015 15:06:25 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.14.9/8.14.9/Submit) id t69F6Pli098043; Thu, 9 Jul 2015 15:06:25 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201507091506.t69F6Pli098043@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Thu, 9 Jul 2015 15:06:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285319 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jul 2015 15:06:25 -0000 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;