Commit a1935c17 authored by Eric W. Biederman's avatar Eric W. Biederman

mnt: Simplify mount_too_revealing

Verify all filesystems that we check in mount_too_revealing set
SB_I_NOEXEC and SB_I_NODEV in sb->s_iflags.  That is true for today
and it should remain true in the future.

Remove the now unnecessary checks from mnt_already_visibile that
ensure MNT_LOCK_NOSUID, MNT_LOCK_NOEXEC, and MNT_LOCK_NODEV are
preserved.  Making the code shorter and easier to read.

Relying on SB_I_NOEXEC and SB_I_NODEV instead of the user visible
MNT_NOSUID, MNT_NOEXEC, and MNT_NODEV ensures the many current
systems where proc and sysfs are mounted with "nosuid, nodev, noexec"
and several slightly buggy container applications don't bother to
set those flags continue to work.
Acked-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent a2982cc9
...@@ -3232,12 +3232,8 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new, ...@@ -3232,12 +3232,8 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
continue; continue;
/* Read the mount flags and filter out flags that /* A local view of the mount flags */
* may safely be ignored.
*/
mnt_flags = mnt->mnt.mnt_flags; mnt_flags = mnt->mnt.mnt_flags;
if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC)
mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC);
/* Don't miss readonly hidden in the superblock flags */ /* Don't miss readonly hidden in the superblock flags */
if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY) if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY)
...@@ -3249,15 +3245,6 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new, ...@@ -3249,15 +3245,6 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
if ((mnt_flags & MNT_LOCK_READONLY) && if ((mnt_flags & MNT_LOCK_READONLY) &&
!(new_flags & MNT_READONLY)) !(new_flags & MNT_READONLY))
continue; continue;
if ((mnt_flags & MNT_LOCK_NODEV) &&
!(new_flags & MNT_NODEV))
continue;
if ((mnt_flags & MNT_LOCK_NOSUID) &&
!(new_flags & MNT_NOSUID))
continue;
if ((mnt_flags & MNT_LOCK_NOEXEC) &&
!(new_flags & MNT_NOEXEC))
continue;
if ((mnt_flags & MNT_LOCK_ATIME) && if ((mnt_flags & MNT_LOCK_ATIME) &&
((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK))) ((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
continue; continue;
...@@ -3277,9 +3264,6 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new, ...@@ -3277,9 +3264,6 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
} }
/* Preserve the locked attributes */ /* Preserve the locked attributes */
*new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \ *new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \
MNT_LOCK_NODEV | \
MNT_LOCK_NOSUID | \
MNT_LOCK_NOEXEC | \
MNT_LOCK_ATIME); MNT_LOCK_ATIME);
visible = true; visible = true;
goto found; goto found;
...@@ -3292,6 +3276,7 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new, ...@@ -3292,6 +3276,7 @@ static bool mnt_already_visible(struct mnt_namespace *ns, struct vfsmount *new,
static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags) static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags)
{ {
const unsigned long required_iflags = SB_I_NOEXEC | SB_I_NODEV;
struct mnt_namespace *ns = current->nsproxy->mnt_ns; struct mnt_namespace *ns = current->nsproxy->mnt_ns;
unsigned long s_iflags; unsigned long s_iflags;
...@@ -3303,6 +3288,12 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags) ...@@ -3303,6 +3288,12 @@ static bool mount_too_revealing(struct vfsmount *mnt, int *new_mnt_flags)
if (!(s_iflags & SB_I_USERNS_VISIBLE)) if (!(s_iflags & SB_I_USERNS_VISIBLE))
return false; return false;
if ((s_iflags & required_iflags) != required_iflags) {
WARN_ONCE(1, "Expected s_iflags to contain 0x%lx\n",
required_iflags);
return true;
}
return !mnt_already_visible(ns, mnt, new_mnt_flags); return !mnt_already_visible(ns, mnt, new_mnt_flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment