diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-04-27 10:26:03 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-05-11 23:13:01 +0200 |
| commit | dc4edae7f41dceb236553b61cda0383895293c90 (patch) | |
| tree | da4b78ba0fe6a7f9dc10728eb35656c1226a8930 /fs | |
| parent | 672697c37c9dfe05aabfd44ccb51c2877deb524e (diff) | |
fs: move SB_I_USERNS_VISIBLE to FS_USERNS_MOUNT_RESTRICTED
Whether a filesystem's mounts need to undergo a visibility check in user
namespaces is a static property of the filesystem type, not a runtime
property of each superblock instance. Both proc and sysfs always set
SB_I_USERNS_VISIBLE on their superblocks unconditionally (sysfs does so
on first creation, and subsequent mounts reuse the same superblock).
Move this flag from sb->s_iflags (SB_I_USERNS_VISIBLE) to
file_system_type->fs_flags (FS_USERNS_MOUNT_RESTRICTED) so the intent
is expressed at the filesystem type level where it belongs.
All check sites are updated to test sb->s_type->fs_flags instead of
sb->s_iflags. The SB_I_NOEXEC and SB_I_NODEV flags remain on the
superblock as they are runtime properties set during fill_super.
Link: https://patch.msgid.link/72887c5b6204dc3adf5a53104f0be6bd8bc4f6cd.1777278334.git.legion@kernel.org
Reviewed-by: Aleksa Sarai <aleksa@amutable.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/namespace.c | 6 | ||||
| -rw-r--r-- | fs/proc/root.c | 4 | ||||
| -rw-r--r-- | fs/sysfs/mount.c | 4 |
3 files changed, 6 insertions, 8 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 047efa737ef9..e6e58117c778 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1099,7 +1099,7 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt) rb_link_node(&mnt->mnt_node, parent, link); rb_insert_color(&mnt->mnt_node, &ns->mounts); - if ((mnt->mnt.mnt_sb->s_iflags & SB_I_USERNS_VISIBLE) && + if ((mnt->mnt.mnt_sb->s_type->fs_flags & FS_USERNS_MOUNT_RESTRICTED) && mnt->mnt.mnt_root == mnt->mnt.mnt_sb->s_root) hlist_add_head(&mnt->mnt_ns_visible, &ns->mnt_visible_mounts); @@ -6408,10 +6408,10 @@ static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags return false; /* Can this filesystem be too revealing? */ - s_iflags = sb->s_iflags; - if (!(s_iflags & SB_I_USERNS_VISIBLE)) + if (!(sb->s_type->fs_flags & FS_USERNS_MOUNT_RESTRICTED)) return false; + s_iflags = sb->s_iflags; if ((s_iflags & required_iflags) != required_iflags) { WARN_ONCE(1, "Expected s_iflags to contain 0x%lx\n", required_iflags); diff --git a/fs/proc/root.c b/fs/proc/root.c index 0f9100559471..b65053f9f046 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -257,7 +257,7 @@ static int proc_fill_super(struct super_block *s, struct fs_context *fc) proc_apply_options(fs_info, fc, current_user_ns()); /* User space would break if executables or devices appear on proc */ - s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC | SB_I_NODEV; + s->s_iflags |= SB_I_NOEXEC | SB_I_NODEV; s->s_flags |= SB_NODIRATIME | SB_NOSUID | SB_NOEXEC; s->s_blocksize = 1024; s->s_blocksize_bits = 10; @@ -359,7 +359,7 @@ static struct file_system_type proc_fs_type = { .init_fs_context = proc_init_fs_context, .parameters = proc_fs_parameters, .kill_sb = proc_kill_sb, - .fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM, + .fs_flags = FS_USERNS_MOUNT | FS_USERNS_MOUNT_RESTRICTED | FS_DISALLOW_NOTIFY_PERM, }; void __init proc_root_init(void) diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index b199e8ff79b1..b45ea5d511e7 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -32,8 +32,6 @@ static int sysfs_get_tree(struct fs_context *fc) if (ret) return ret; - if (kfc->new_sb_created) - fc->root->d_sb->s_iflags |= SB_I_USERNS_VISIBLE; return 0; } @@ -93,7 +91,7 @@ static struct file_system_type sysfs_fs_type = { .name = "sysfs", .init_fs_context = sysfs_init_fs_context, .kill_sb = sysfs_kill_sb, - .fs_flags = FS_USERNS_MOUNT, + .fs_flags = FS_USERNS_MOUNT | FS_USERNS_MOUNT_RESTRICTED, }; int __init sysfs_init(void) |
