4.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Eric W. Biederman" <ebied...@xmission.com>

commit 8c6cf9cc829fcd0b179b59f7fe288941d0e31108 upstream.

Ignore an existing mount if the locked readonly, nodev or atime
attributes are less permissive than the desired attributes
of the new mount.

On success ensure the new mount locks all of the same readonly, nodev and
atime attributes as the old mount.

The nosuid and noexec attributes are not checked here as this change
is destined for stable and enforcing those attributes causes a
regression in lxc and libvirt-lxc where those applications will not
start and there are no known executables on sysfs or proc and no known
way to create exectuables without code modifications

Fixes: e51db73532955 ("userns: Better restrictions on when proc and sysfs can 
be mounted")
Signed-off-by: "Eric W. Biederman" <ebied...@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 fs/namespace.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2334,7 +2334,7 @@ unlock:
        return err;
 }
 
-static bool fs_fully_visible(struct file_system_type *fs_type);
+static bool fs_fully_visible(struct file_system_type *fs_type, int 
*new_mnt_flags);
 
 /*
  * create a new mount for userspace and request it to be added into the
@@ -2368,7 +2368,7 @@ static int do_new_mount(struct path *pat
                        mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
                }
                if (type->fs_flags & FS_USERNS_VISIBLE) {
-                       if (!fs_fully_visible(type))
+                       if (!fs_fully_visible(type, &mnt_flags))
                                return -EPERM;
                }
        }
@@ -3172,9 +3172,10 @@ bool current_chrooted(void)
        return chrooted;
 }
 
-static bool fs_fully_visible(struct file_system_type *type)
+static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
 {
        struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+       int new_flags = *new_mnt_flags;
        struct mount *mnt;
        bool visible = false;
 
@@ -3193,6 +3194,19 @@ static bool fs_fully_visible(struct file
                if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
                        continue;
 
+               /* Verify the mount flags are equal to or more permissive
+                * than the proposed new mount.
+                */
+               if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
+                   !(new_flags & MNT_READONLY))
+                       continue;
+               if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
+                   !(new_flags & MNT_NODEV))
+                       continue;
+               if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
+                   ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & 
MNT_ATIME_MASK)))
+                       continue;
+
                /* This mount is not fully visible if there are any
                 * locked child mounts that cover anything except for
                 * empty directories.
@@ -3206,6 +3220,10 @@ static bool fs_fully_visible(struct file
                        if (!is_empty_dir_inode(inode))
                                goto next;
                }
+               /* Preserve the locked attributes */
+               *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
+                                                       MNT_LOCK_NODEV    | \
+                                                       MNT_LOCK_ATIME);
                visible = true;
                goto found;
        next:   ;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to