Skip to content

Commit 77b1a97

Browse files
committed
mnt: fs_fully_visible enforce noexec and nosuid if !SB_I_NOEXEC
The filesystems proc and sysfs do not have executable files do not have exectuable files today and portions of userspace break if we do enforce nosuid and noexec consistency of nosuid and noexec flags between previous mounts and new mounts of proc and sysfs. Add the code to enforce consistency of the nosuid and noexec flags, and use the presence of SB_I_NOEXEC to signal that there is no need to bother. This results in a completely userspace invisible change that makes it clear fs_fully_visible can only skip the enforcement of noexec and nosuid because it is known the filesystems in question do not support executables. Signed-off-by: "Eric W. Biederman" <[email protected]>
1 parent 90f8572 commit 77b1a97

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

fs/namespace.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,8 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
31943194
down_read(&namespace_sem);
31953195
list_for_each_entry(mnt, &ns->list, mnt_list) {
31963196
struct mount *child;
3197+
int mnt_flags;
3198+
31973199
if (mnt->mnt.mnt_sb->s_type != type)
31983200
continue;
31993201

@@ -3203,17 +3205,30 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
32033205
if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
32043206
continue;
32053207

3208+
/* Read the mount flags and filter out flags that
3209+
* may safely be ignored.
3210+
*/
3211+
mnt_flags = mnt->mnt.mnt_flags;
3212+
if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC)
3213+
mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC);
3214+
32063215
/* Verify the mount flags are equal to or more permissive
32073216
* than the proposed new mount.
32083217
*/
3209-
if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
3218+
if ((mnt_flags & MNT_LOCK_READONLY) &&
32103219
!(new_flags & MNT_READONLY))
32113220
continue;
3212-
if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
3221+
if ((mnt_flags & MNT_LOCK_NODEV) &&
32133222
!(new_flags & MNT_NODEV))
32143223
continue;
3215-
if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
3216-
((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
3224+
if ((mnt_flags & MNT_LOCK_NOSUID) &&
3225+
!(new_flags & MNT_NOSUID))
3226+
continue;
3227+
if ((mnt_flags & MNT_LOCK_NOEXEC) &&
3228+
!(new_flags & MNT_NOEXEC))
3229+
continue;
3230+
if ((mnt_flags & MNT_LOCK_ATIME) &&
3231+
((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
32173232
continue;
32183233

32193234
/* This mount is not fully visible if there are any
@@ -3223,16 +3238,18 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
32233238
list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
32243239
struct inode *inode = child->mnt_mountpoint->d_inode;
32253240
/* Only worry about locked mounts */
3226-
if (!(mnt->mnt.mnt_flags & MNT_LOCKED))
3241+
if (!(mnt_flags & MNT_LOCKED))
32273242
continue;
32283243
/* Is the directory permanetly empty? */
32293244
if (!is_empty_dir_inode(inode))
32303245
goto next;
32313246
}
32323247
/* Preserve the locked attributes */
3233-
*new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
3234-
MNT_LOCK_NODEV | \
3235-
MNT_LOCK_ATIME);
3248+
*new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \
3249+
MNT_LOCK_NODEV | \
3250+
MNT_LOCK_NOSUID | \
3251+
MNT_LOCK_NOEXEC | \
3252+
MNT_LOCK_ATIME);
32363253
visible = true;
32373254
goto found;
32383255
next: ;

0 commit comments

Comments
 (0)