diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-04 01:03:05 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-06-04 01:03:05 +0200 |
commit | 1ec6574a3c0a22c130c08e8c36c825cb87d68f8e (patch) | |
tree | 1f064c4a4965b9b0dd213456649b23e066d54bea /fs/exec.c | |
parent | Merge tag 'per-namespace-ipc-sysctls-for-v5.19' of git://git.kernel.org/pub/s... (diff) | |
parent | sched: Update task_tick_numa to ignore tasks without an mm (diff) | |
download | linux-1ec6574a3c0a22c130c08e8c36c825cb87d68f8e.tar.xz linux-1ec6574a3c0a22c130c08e8c36c825cb87d68f8e.zip |
Merge tag 'kthread-cleanups-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull kthread updates from Eric Biederman:
"This updates init and user mode helper tasks to be ordinary user mode
tasks.
Commit 40966e316f86 ("kthread: Ensure struct kthread is present for
all kthreads") caused init and the user mode helper threads that call
kernel_execve to have struct kthread allocated for them. This struct
kthread going away during execve in turned made a use after free of
struct kthread possible.
Here, commit 343f4c49f243 ("kthread: Don't allocate kthread_struct for
init and umh") is enough to fix the use after free and is simple
enough to be backportable.
The rest of the changes pass struct kernel_clone_args to clean things
up and cause the code to make sense.
In making init and the user mode helpers tasks purely user mode tasks
I ran into two complications. The function task_tick_numa was
detecting tasks without an mm by testing for the presence of
PF_KTHREAD. The initramfs code in populate_initrd_image was using
flush_delayed_fput to ensuere the closing of all it's file descriptors
was complete, and flush_delayed_fput does not work in a userspace
thread.
I have looked and looked and more complications and in my code review
I have not found any, and neither has anyone else with the code
sitting in linux-next"
* tag 'kthread-cleanups-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
sched: Update task_tick_numa to ignore tasks without an mm
fork: Stop allowing kthreads to call execve
fork: Explicitly set PF_KTHREAD
init: Deal with the init process being a user mode process
fork: Generalize PF_IO_WORKER handling
fork: Explicity test for idle tasks in copy_thread
fork: Pass struct kernel_clone_args into copy_thread
kthread: Don't allocate kthread_struct for init and umh
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/exec.c b/fs/exec.c index 14b4b3755580..0989fb8472a1 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1312,9 +1312,7 @@ int begin_new_exec(struct linux_binprm * bprm) if (retval) goto out_unlock; - if (me->flags & PF_KTHREAD) - free_kthread_struct(me); - me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | + me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_NOFREEZE | PF_NO_SETAFFINITY); flush_thread(); me->personality &= ~bprm->per_clear; @@ -1959,6 +1957,10 @@ int kernel_execve(const char *kernel_filename, int fd = AT_FDCWD; int retval; + /* It is non-sense for kernel threads to call execve */ + if (WARN_ON_ONCE(current->flags & PF_KTHREAD)) + return -EINVAL; + filename = getname_kernel(kernel_filename); if (IS_ERR(filename)) return PTR_ERR(filename); |