linux/init
Eric W. Biederman 343f4c49f2 kthread: Don't allocate kthread_struct for init and umh
If kthread_is_per_cpu runs concurrently with free_kthread_struct the
kthread_struct that was just freed may be read from.

This bug was introduced by commit 40966e316f ("kthread: Ensure
struct kthread is present for all kthreads").  When kthread_struct
started to be allocated for all tasks that have PF_KTHREAD set.  This
in turn required the kthread_struct to be freed in kernel_execve and
violated the assumption that kthread_struct will have the same
lifetime as the task.

Looking a bit deeper this only applies to callers of kernel_execve
which is just the init process and the user mode helper processes.
These processes really don't want to be kernel threads but are for
historical reasons.  Mostly that copy_thread does not know how to take
a kernel mode function to the process with for processes without
PF_KTHREAD or PF_IO_WORKER set.

Solve this by not allocating kthread_struct for the init process and
the user mode helper processes.

This is done by adding a kthread member to struct kernel_clone_args.
Setting kthread in fork_idle and kernel_thread.  Adding
user_mode_thread that works like kernel_thread except it does not set
kthread.  In fork only allocating the kthread_struct if .kthread is set.

I have looked at kernel/kthread.c and since commit 40966e316f
("kthread: Ensure struct kthread is present for all kthreads") there
have been no assumptions added that to_kthread or __to_kthread will
not return NULL.

There are a few callers of to_kthread or __to_kthread that assume a
non-NULL struct kthread pointer will be returned.  These functions are
kthread_data(), kthread_parmme(), kthread_exit(), kthread(),
kthread_park(), kthread_unpark(), kthread_stop().  All of those functions
can reasonably expected to be called when it is know that a task is a
kthread so that assumption seems reasonable.

Cc: stable@vger.kernel.org
Fixes: 40966e316f ("kthread: Ensure struct kthread is present for all kthreads")
Reported-by: Максим Кутявин <maximkabox13@gmail.com>
Link: https://lkml.kernel.org/r/20220506141512.516114-1-ebiederm@xmission.com
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
2022-05-06 14:49:44 -05:00
..
calibrate.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
do_mounts.c block: remove genhd.h 2022-02-02 07:49:59 -07:00
do_mounts.h init: add an init_mknod helper 2020-07-31 08:17:54 +02:00
do_mounts_initrd.c Merge branch 'hch.init_path' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2020-08-07 09:40:34 -07:00
do_mounts_rd.c init: add an init_unlink helper 2020-07-31 08:17:52 +02:00
init_task.c kcsan: Remove redundant zero-initialization of globals 2021-12-09 16:42:26 -08:00
initramfs.c memblock: use memblock_free for freeing virtual pointers 2021-11-06 13:30:41 -07:00
Kconfig Kbuild updates for v5.18 2022-03-31 11:59:03 -07:00
main.c kthread: Don't allocate kthread_struct for init and umh 2022-05-06 14:49:44 -05:00
Makefile sched/preempt: Tell about PREEMPT_DYNAMIC on kernel headers 2022-03-11 15:36:35 +01:00
noinitramfs.c init: move usermodehelper_enable() to populate_rootfs() 2021-09-08 11:50:27 -07:00
version.c kbuild: add an elfnote for whether vmlinux is built with lto 2021-04-25 05:25:42 +09:00