• Eric W. Biederman's avatar
    kthread: Don't allocate kthread_struct for init and umh · 343f4c49
    Eric W. Biederman authored
    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 40966e31 ("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 40966e31
    ("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: 40966e31 ("kthread: Ensure struct kthread is present for all kthreads")
    Reported-by: default avatarМаксим Кутявин <maximkabox13@gmail.com>
    Link: https://lkml.kernel.org/r/20220506141512.516114-1-ebiederm@xmission.comSigned-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
    343f4c49
fork.c 79.3 KB