svn commit: r326851 - head/sys/fs/devfs
Konstantin Belousov
kib at FreeBSD.org
Thu Dec 14 13:41:13 UTC 2017
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);
}
More information about the svn-src-all
mailing list