diff options
| author | Christian Brauner <brauner@kernel.org> | 2026-06-01 15:56:38 +0200 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2026-06-29 10:44:05 +0200 |
| commit | 9a8e296958884b807a02759975170b6559901242 (patch) | |
| tree | 3d0cc58cb5d53228e98694865f1a7909dd0c442e /include/linux/fs_struct.h | |
| parent | 1d4ee94a51bdb98610bf7283e6297b133f8c1025 (diff) | |
| download | linux-next-9a8e296958884b807a02759975170b6559901242.tar.gz linux-next-9a8e296958884b807a02759975170b6559901242.zip | |
fs: make userspace_init_fs a dynamically-initialized pointer
Change userspace_init_fs from a declared-but-unused extern struct to
a dynamically initialized pointer. Add init_userspace_fs() which is
called early in kernel_init() (PID 1) to record PID 1's fs_struct
as the canonical userspace filesystem state.
Wire up __override_init_fs() and __revert_init_fs() to actually swap
current->fs to/from userspace_init_fs. Previously these were no-ops
that stored current->fs back to itself.
Fix nullfs_userspace_init() to compare against userspace_init_fs
instead of &init_fs. When PID 1 unshares its filesystem state, revert
userspace_init_fs to init_fs's root (nullfs) so that stale filesystem
state is not silently inherited by kworkers and usermodehelpers.
At this stage PID 1's fs still points to rootfs (set by
init_mount_tree), so userspace_init_fs points to rootfs and
scoped_with_init_fs() is functionally equivalent to its previous no-op
behavior.
Link: https://patch.msgid.link/20260601-work-kthread-nullfs-v4-5-77ee053060e0@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'include/linux/fs_struct.h')
| -rw-r--r-- | include/linux/fs_struct.h | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index e11d0e57168f..97eef8d3863d 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -17,6 +17,7 @@ struct fs_struct { } __randomize_layout; extern struct kmem_cache *fs_cachep; +extern struct fs_struct *userspace_init_fs; extern void exit_fs(struct task_struct *); extern void set_fs_root(struct fs_struct *, const struct path *); @@ -57,17 +58,17 @@ static inline int current_umask(void) */ static inline struct fs_struct *__override_init_fs(void) { - struct fs_struct *fs; + struct fs_struct *old_fs; - fs = current->fs; - WRITE_ONCE(current->fs, fs); - return fs; + old_fs = current->fs; + WRITE_ONCE(current->fs, userspace_init_fs); + return old_fs; } -static inline void __revert_init_fs(struct fs_struct *revert_fs) +static inline void __revert_init_fs(struct fs_struct *old_fs) { - VFS_WARN_ON_ONCE(current->fs != revert_fs); - WRITE_ONCE(current->fs, revert_fs); + VFS_WARN_ON_ONCE(current->fs != userspace_init_fs); + WRITE_ONCE(current->fs, old_fs); } DEFINE_CLASS(__override_init_fs, |
