Author: kib Date: Thu Dec 14 13:41:11 2017 New Revision: 326851 URL: https://svnweb.freebsd.org/changeset/base/326851
Log: In devfs_lookupx() dotdot lookup case, avoid dereferencing dvp->v_mount after dvp is unlocked. The vnode might be reclaimed after unlock, so v_mount becomes NULL. Cache the struct mount pointer before the unlock, the struct is type-stable. Note that devfs_allocv() reads mp->mnt_data but does not operate on it further when dirent is doomed. The unmount cannot proceed until all dirents are reclaimed. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/fs/devfs/devfs_vnops.c Modified: head/sys/fs/devfs/devfs_vnops.c ============================================================================== --- head/sys/fs/devfs/devfs_vnops.c Thu Dec 14 13:19:43 2017 (r326850) +++ head/sys/fs/devfs/devfs_vnops.c Thu Dec 14 13:41:11 2017 (r326851) @@ -896,6 +896,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlo struct devfs_dirent *de, *dd; struct devfs_dirent **dde; struct devfs_mount *dmp; + struct mount *mp; struct cdev *cdev; int error, flags, nameiop, dvplocked; char specname[SPECNAMELEN + 1], *pname; @@ -907,7 +908,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlo td = cnp->cn_thread; flags = cnp->cn_flags; nameiop = cnp->cn_nameiop; - dmp = VFSTODEVFS(dvp->v_mount); + mp = dvp->v_mount; + dmp = VFSTODEVFS(mp); dd = dvp->v_data; *vpp = NULLVP; @@ -940,8 +942,8 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlo return (ENOENT); dvplocked = VOP_ISLOCKED(dvp); VOP_UNLOCK(dvp, 0); - error = devfs_allocv(de, dvp->v_mount, - cnp->cn_lkflags & LK_TYPE_MASK, vpp); + error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, + vpp); *dm_unlock = 0; vn_lock(dvp, dvplocked | LK_RETRY); return (error); @@ -1026,8 +1028,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlo return (0); } } - error = devfs_allocv(de, dvp->v_mount, cnp->cn_lkflags & LK_TYPE_MASK, - vpp); + error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp); *dm_unlock = 0; return (error); } _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"