We want to mount beneath the given location. For that operation to make sense, location must be the root of some mount that has something under it. Currently we let it proceed if those requirements are not met, with rather meaningless results, and have that bogosity caught further down the road; let's fail early instead - do_lock_mount() doesn't make sense unless those conditions hold, and checking them there makes things simpler. Reviewed-by: Christian Brauner <brauner@xxxxxxxxxx> Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> --- fs/namespace.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 74c67ea1b5a8..86c6dd432b13 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2768,12 +2768,19 @@ static int do_lock_mount(struct path *path, struct pinned_mountpoint *pinned, bo struct path under = {}; int err = -ENOENT; + if (unlikely(beneath) && !path_mounted(path)) + return -EINVAL; + for (;;) { struct mount *m = real_mount(mnt); if (beneath) { path_put(&under); read_seqlock_excl(&mount_lock); + if (unlikely(!mnt_has_parent(m))) { + read_sequnlock_excl(&mount_lock); + return -EINVAL; + } under.mnt = mntget(&m->mnt_parent->mnt); under.dentry = dget(m->mnt_mountpoint); read_sequnlock_excl(&mount_lock); @@ -3437,8 +3444,6 @@ static bool mount_is_ancestor(const struct mount *p1, const struct mount *p2) * @to: mount under which to mount * @mp: mountpoint of @to * - * - Make sure that @to->dentry is actually the root of a mount under - * which we can mount another mount. * - Make sure that nothing can be mounted beneath the caller's current * root or the rootfs of the namespace. * - Make sure that the caller can unmount the topmost mount ensuring @@ -3459,12 +3464,6 @@ static int can_move_mount_beneath(struct mount *mnt_from, struct mount *mnt_to = real_mount(to->mnt), *parent_mnt_to = mnt_to->mnt_parent; - if (!mnt_has_parent(mnt_to)) - return -EINVAL; - - if (!path_mounted(to)) - return -EINVAL; - if (IS_MNT_LOCKED(mnt_to)) return -EINVAL; -- 2.47.2