FAILED: patch "[PATCH] ovl: prevent private clone if bind mount is not allowed" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 427215d85e8d1476da1a86b8d67aceb485eb3631 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Mon, 9 Aug 2021 10:19:47 +0200
Subject: [PATCH] ovl: prevent private clone if bind mount is not allowed
Add the following checks from __do_loopback() to clone_private_mount() as well:
- verify that the mount is in the current namespace
- verify that there are no locked children
Reported-by Alois Wohlschlager <[email protected]>
Fixes c771d683a62e ("vfs: introduce clone_private_mount()")
Cc <[email protected]> # v3.18
Signed-off-by Miklos Szeredi <[email protected]>
fs/namespace.c +28 -14
@@ -1938,6 +1938,20 @@ void drop_collected_mounts(struct vfsmount *mnt)namespace_unlock (); } +static bool has_locked_children (struct mount *mnt,struct dentry *dentry) +{ +struct mount *child; + +list_for_each_entry (child, &mnt->mnt_mounts, mnt_child) { +if (!is_subdir (child->mnt_mountpoint, dentry)) +continue ; + +if (child->mnt.mnt_flags &MNT_LOCKED ) +return true; + } +return false; +} +/** * clone_private_mount - create a private clone of a path * @path: path to clone
@@ -1953,10 +1967,19 @@ struct vfsmount *clone_private_mount(const struct path *path)struct mount *old_mnt =real_mount (path->mnt);struct mount *new_mnt; +down_read (&namespace_sem);if (IS_MNT_UNBINDABLE (old_mnt)) -return ERR_PTR (-EINVAL ); + goto invalid; + +if (!check_mnt (old_mnt)) + goto invalid; + +if (has_locked_children (old_mnt, path->dentry)) + goto invalid; new_mnt =clone_mnt (old_mnt, path->dentry,CL_PRIVATE ); +up_read (&namespace_sem); +if (IS_ERR (new_mnt))return ERR_CAST (new_mnt);
@@ -1964,6 +1987,10 @@ struct vfsmount *clone_private_mount(const struct path *path) new_mnt->mnt_ns =MNT_NS_INTERNAL ;return &new_mnt->mnt; + +invalid: +up_read (&namespace_sem); +return ERR_PTR (-EINVAL ); }EXPORT_SYMBOL_GPL (clone_private_mount);
@@ -2315,19 +2342,6 @@ static int do_change_type(struct path *path, int ms_flags)return err; } -static bool has_locked_children (struct mount *mnt,struct dentry *dentry) -{ -struct mount *child; -list_for_each_entry (child, &mnt->mnt_mounts, mnt_child) { -if (!is_subdir (child->mnt_mountpoint, dentry)) -continue ; - -if (child->mnt.mnt_flags &MNT_LOCKED ) -return true; - } -return false; -} -static struct mount *__do_loopback (struct path *old_path,int recurse) {struct mount *mnt =ERR_PTR (-EINVAL ), *old =real_mount (old_path->mnt);