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
6#include <linux/path.h>6#include <linux/path.h>
7#include <linux/spinlock.h>7#include <linux/spinlock.h>
8#include <linux/seqlock.h>8#include <linux/seqlock.h>
9#include <linux/vfsdebug.h>
9 10
10struct fs_struct {11struct fs_struct {
11 int users;12 int users;
@@ -16,6 +17,7 @@ struct fs_struct { · 4 unmodified lines
16} __randomize_layout;17} __randomize_layout;
17 18
18extern struct kmem_cache *fs_cachep;19extern struct kmem_cache *fs_cachep;
20extern struct fs_struct *userspace_init_fs;
19 21
20extern void exit_fs(struct task_struct *);22extern void exit_fs(struct task_struct *);
21extern void set_fs_root(struct fs_struct *, const struct path *);23extern 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
40 read_sequnlock_excl(&fs->seq);42 read_sequnlock_excl(&fs->seq);
41}43}
42 44
45struct fs_struct *switch_fs_struct(struct fs_struct *new_fs);
46
43extern bool current_chrooted(void);47extern bool current_chrooted(void);
44 48
45static inline int current_umask(void)49static inline int current_umask(void)
@@ -47,4 +51,34 @@ static inline int current_umask(void) · 1 unmodified line
47 return current->fs->umask;51 return current->fs->umask;
48}52}
49 53
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 */
59static 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
68static 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
74DEFINE_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
82void __init init_userspace_fs(void);
83
50#endif /* _LINUX_FS_STRUCT_H */84#endif /* _LINUX_FS_STRUCT_H */
include/linux/init_task.h+1−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
24 24
25extern struct files_struct init_files;25extern struct files_struct init_files;
26extern struct fs_struct init_fs;26extern struct fs_struct init_fs;
27extern struct fs_struct *userspace_init_fs;
27extern struct nsproxy init_nsproxy;28extern struct nsproxy init_nsproxy;
28 29
29#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE30#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
include/linux/sched.h+1−0
@@ -1191,6 +1191,7 @@ struct task_struct { · 1190 unmodified lines
1191 unsigned long last_switch_time;1191 unsigned long last_switch_time;
1192#endif1192#endif
1193 /* Filesystem information: */1193 /* Filesystem information: */
1194 struct fs_struct *real_fs;
1194 struct fs_struct *fs;1195 struct fs_struct *fs;
1195 1196
1196 /* Open file information: */1197 /* Open file information: */
include/linux/sched/task.h+1−0
@@ -31,6 +31,7 @@ struct kernel_clone_args { · 30 unmodified lines
31 u32 io_thread:1;31 u32 io_thread:1;
32 u32 user_worker:1;32 u32 user_worker:1;
33 u32 no_files:1;33 u32 no_files:1;
34 u32 umh:1;
34 unsigned long stack;35 unsigned long stack;
35 unsigned long stack_size;36 unsigned long stack_size;
36 unsigned long tls;37 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