• Vegard Nossum's avatar
    kthread: Fix use-after-free if kthread fork fails · 0f7ff02f
    Vegard Nossum authored
    commit 4d6501dc upstream.
    
    If a kthread forks (e.g. usermodehelper since commit 1da5c46f) but
    fails in copy_process() between calling dup_task_struct() and setting
    p->set_child_tid, then the value of p->set_child_tid will be inherited
    from the parent and get prematurely freed by free_kthread_struct().
    
        kthread()
         - worker_thread()
            - process_one_work()
            |  - call_usermodehelper_exec_work()
            |     - kernel_thread()
            |        - _do_fork()
            |           - copy_process()
            |              - dup_task_struct()
            |                 - arch_dup_task_struct()
            |                    - tsk->set_child_tid = current->set_child_tid // implied
            |              - ...
            |              - goto bad_fork_*
            |              - ...
            |              - free_task(tsk)
            |                 - free_kthread_struct(tsk)
            |                    - kfree(tsk->set_child_tid)
            - ...
            - schedule()
               - __schedule()
                  - wq_worker_sleeping()
                     - kthread_data(task)->flags // UAF
    
    The problem started showing up with commit 1da5c46f since it reused
    ->set_child_tid for the kthread worker data.
    
    A better long-term solution might be to get rid of the ->set_child_tid
    abuse. The comment in set_kthread_struct() also looks slightly wrong.
    Debugged-by: default avatarJamie Iles <jamie.iles@oracle.com>
    Fixes: 1da5c46f ("kthread: Make struct kthread kmalloc'ed")
    Signed-off-by: default avatarVegard Nossum <vegard.nossum@oracle.com>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Frederic Weisbecker <fweisbec@gmail.com>
    Cc: Jamie Iles <jamie.iles@oracle.com>
    Link: http://lkml.kernel.org/r/20170509073959.17858-1-vegard.nossum@oracle.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    0f7ff02f
fork.c 58.1 KB