mount: Check for !VDIR mount points before handling -o emptydir

To implement -o emptydir, vfs_emptydir() checks that the passed
directory is empty.  This should be done after checking whether the
vnode is of type VDIR, though, or vfs_emptydir() may end up calling
VOP_READDIR on a non-directory.

Reported by:	syzbot+4006732c69fb0f792b2c@syzkaller.appspotmail.com
Reviewed by:	kib, imp
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D32475
This commit is contained in:
Mark Johnston 2021-10-12 20:11:02 -04:00
parent d0f0e0bd74
commit 03d5820f73
2 changed files with 3 additions and 8 deletions

View File

@ -1095,14 +1095,6 @@ vfs_domount_first(
ASSERT_VOP_ELOCKED(vp, __func__);
KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here"));
if ((fsflags & MNT_EMPTYDIR) != 0) {
error = vfs_emptydir(vp);
if (error != 0) {
vput(vp);
return (error);
}
}
/*
* If the jail of the calling thread lacks permission for this type of
* file system, or is trying to cover its own root, deny immediately.
@ -1124,6 +1116,8 @@ vfs_domount_first(
error = vinvalbuf(vp, V_SAVE, 0, 0);
if (error == 0 && vp->v_type != VDIR)
error = ENOTDIR;
if (error == 0 && (fsflags & MNT_EMPTYDIR) != 0)
error = vfs_emptydir(vp);
if (error == 0) {
VI_LOCK(vp);
if ((vp->v_iflag & VI_MOUNT) == 0 && vp->v_mountedhere == NULL)

View File

@ -6300,6 +6300,7 @@ vfs_emptydir(struct vnode *vp)
eof = 0;
ASSERT_VOP_LOCKED(vp, "vfs_emptydir");
VNASSERT(vp->v_type == VDIR, vp, ("vp is not a directory"));
dirent = malloc(sizeof(struct dirent), M_TEMP, M_WAITOK);
iov.iov_base = dirent;