]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Merge tag 'kthread-cleanups-for-v5.19' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Jun 2022 23:03:05 +0000 (16:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Jun 2022 23:03:05 +0000 (16:03 -0700)
Pull kthread updates from Eric Biederman:
 "This updates init and user mode helper tasks to be ordinary user mode
  tasks.

  Commit aa52bf4ac30d ("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 ce0508581165 ("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

16 files changed:
1  2 
arch/arm64/kernel/process.c
arch/csky/kernel/process.c
arch/ia64/kernel/process.c
arch/m68k/kernel/process.c
arch/openrisc/kernel/process.c
arch/parisc/kernel/process.c
arch/powerpc/kernel/process.c
arch/riscv/kernel/process.c
arch/x86/kernel/fpu/core.c
arch/x86/kernel/process.c
arch/xtensa/kernel/process.c
fs/exec.c
init/initramfs.c
init/main.c
kernel/fork.c
kernel/sched/fair.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 58fb48d3004fe2ef766c61d4b8ee13a175823583,d20eaad52a859485685a4b00fb5b9854a030d8e4..9b2772b7e1f3990eee3760100880054cf7942a31
@@@ -193,10 -193,14 +195,10 @@@ int copy_thread(struct task_struct *p, 
        if (sp)
                childregs->sp = sp;
  
-       if (unlikely(p->flags & PF_IO_WORKER)) {
 -#ifdef CONFIG_X86_32
 -      task_user_gs(p) = get_user_gs(current_pt_regs());
 -#endif
 -
+       if (unlikely(args->fn)) {
                /*
-                * An IO thread is a user space thread, but it doesn't
-                * return to ret_after_fork().
+                * A user space thread, but it doesn't return to
+                * ret_after_fork().
                 *
                 * In order to indicate that to tools like gdb,
                 * we reset the stack and instruction pointers.
Simple merge
diff --cc fs/exec.c
Simple merge
index dc84cf756cea1a50e060e1663b50ec49fa49b6b9,41e7857d510d68d995433b1239acbebd0570249f..18229cfe8906b7632d7f3f94574c870145f565a6
  #include <linux/mm.h>
  #include <linux/namei.h>
  #include <linux/init_syscalls.h>
+ #include <linux/task_work.h>
  #include <linux/umh.h>
  
 -static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
 -              loff_t *pos)
 +static __initdata bool csum_present;
 +static __initdata u32 io_csum;
 +
 +static ssize_t __init xwrite(struct file *file, const unsigned char *p,
 +              size_t count, loff_t *pos)
  {
        ssize_t out = 0;
  
diff --cc init/main.c
Simple merge
diff --cc kernel/fork.c
Simple merge
Simple merge