History

Merge tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull kthread vfs updates from Christian Brauner: "This stops kernel threads from sharing filesystem state with userspace. This work is about 3 cycles old and has been in -next for about that time. When the kernel boots init_task creates PID 1 and then kthreadd. From that point every kthread and PID 1 share the same fs_struct. That is why pivot_root() has to rewrite the fs_struct of all kthreads. The rewriting exists so that kthreads can use init's filesystem state when they want to. It also means userspace can move the ground out from under the kernel. PID 1 now gets a completely separate fs_struct. All kthreads are anchored in a private SB_KERNMOUNT instance of nullfs that cannot be mounted on and cannot be used to follow other mounts. Userspace init can no longer affect kthread filesystem state and kthreads can no longer affect userspace fs state without explicit opting in to that. Path lookup from a kthread now fails by default. It makes it deliberately hard to offload security sensitive operations into init's filesystem state from a kthread. Places that legitimately need to look something up there opt in through the new scoped_with_init_fs() which temporarily overrides the caller's fs_struct with init's. usermodehelpers remain the only kernel tasks that genuinely share init's filesystem state, since they execute random binaries in the root filesystem (excellent...). The visible result is that /proc/2/root is a nullfs with an empty mountinfo while /proc/1/root is the real root" * tag 'vfs-7.3-rc1.kthread' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (26 commits) initramfs_test: use test init/exit hooks to override init fs fs: stop rewriting paths for PF_EXITING | PF_DUMPCORE fs: stop rewriting kthread fs structs fs: start all kthreads in nullfs nullfs: make nullfs multi-instance devtmpfs: create private mount namespace fs: add umh argument to struct kernel_clone_args fs: stop sharing fs_struct between init_task and pid 1 af_unix: use scoped_with_init_fs() for coredump socket lookup initramfs: use scoped_with_init_fs() for rootfs unpacking pnfs/blocklayout: use scoped_with_init_fs() for SCSI device lookup ksmbd: use scoped_with_init_fs() for VFS path operations ksmbd: use scoped_with_init_fs() for filesystem info path lookup ksmbd: use scoped_with_init_fs() for share path resolution fs: use scoped_with_init_fs() for kernel_read_file_from_path_initns() coredump: use scoped_with_init_fs() for coredump path resolution btrfs: use scoped_with_init_fs() for update_dev_time() scsi: target: use scoped_with_init_fs() for APTPL metadata scsi: target: use scoped_with_init_fs() for ALUA metadata crypto: ccp: use scoped_with_init_fs() for SEV file access ...

Linus Torvalds committed 2 months ago

Commit fff01502 parents de03b17 b4343ae31 files · +311 −116Browse files

Showing the changes to include (4 of 31 files). Show all

Unified · Split

4 files
  1. include/linux/fs_struct.h +34 −0
  2. include/linux/init_task.h +1 −0
  3. include/linux/sched.h +1 −0
  4. include/linux/sched/task.h +1 −0
include/linux/fs_struct.h+34−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/path.h>
77 #include <linux/spinlock.h>
88 #include <linux/seqlock.h>
9+#include <linux/vfsdebug.h>
910
1011 struct fs_struct {
1112 int users;
@@ -16,6 +17,7 @@ struct fs_struct { · 4 unmodified lines
1617 } __randomize_layout;
1718
1819 extern struct kmem_cache *fs_cachep;
20+extern struct fs_struct *userspace_init_fs;
1921
2022 extern void exit_fs(struct task_struct *);
2123 extern void set_fs_root(struct fs_struct *, const struct path *);
@@ -40,6 +42,8 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) · 18 unmodified lines
4042 read_sequnlock_excl(&fs->seq);
4143 }
4244
45+struct fs_struct *switch_fs_struct(struct fs_struct *new_fs);
46+
4347 extern bool current_chrooted(void);
4448
4549 static inline int current_umask(void)
@@ -47,4 +51,34 @@ static inline int current_umask(void) · 1 unmodified line
4751 return current->fs->umask;
4852 }
4953
54+/*
55+ * Temporarily use userspace_init_fs for path resolution in kthreads.
56+ * Callers should use scoped_with_init_fs() which automatically
57+ * restores the original fs_struct at scope exit.
58+ */
59+static inline struct fs_struct *__override_init_fs(void)
60+{
61+ struct fs_struct *old_fs;
62+
63+ old_fs = current->fs;
64+ WRITE_ONCE(current->fs, userspace_init_fs);
65+ return old_fs;
66+}
67+
68+static inline void __revert_init_fs(struct fs_struct *old_fs)
69+{
70+ VFS_WARN_ON_ONCE(current->fs != userspace_init_fs);
71+ WRITE_ONCE(current->fs, old_fs);
72+}
73+
74+DEFINE_CLASS(__override_init_fs,
75+ struct fs_struct *,
76+ __revert_init_fs(_T),
77+ __override_init_fs(), void)
78+
79+#define scoped_with_init_fs() \
80+ scoped_class(__override_init_fs, __UNIQUE_ID(label))
81+
82+void __init init_userspace_fs(void);
83+
5084 #endif /* _LINUX_FS_STRUCT_H */
include/linux/init_task.h+1−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424
2525 extern struct files_struct init_files;
2626 extern struct fs_struct init_fs;
27+extern struct fs_struct *userspace_init_fs;
2728 extern struct nsproxy init_nsproxy;
2829
2930 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
include/linux/sched.h+1−0
@@ -1191,6 +1191,7 @@ struct task_struct { · 1190 unmodified lines
11911191 unsigned long last_switch_time;
11921192 #endif
11931193 /* Filesystem information: */
1194+ struct fs_struct *real_fs;
11941195 struct fs_struct *fs;
11951196
11961197 /* Open file information: */
include/linux/sched/task.h+1−0
@@ -31,6 +31,7 @@ struct kernel_clone_args { · 30 unmodified lines
3131 u32 io_thread:1;
3232 u32 user_worker:1;
3333 u32 no_files:1;
34+ u32 umh:1;
3435 unsigned long stack;
3536 unsigned long stack_size;
3637 unsigned long tls;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t