• David Howells's avatar
    rxrpc: Fix I/O thread startup getting skipped · 8fbcc833
    David Howells authored
    When starting a kthread, the __kthread_create_on_node() function, as called
    from kthread_run(), waits for a completion to indicate that the task_struct
    (or failure state) of the new kernel thread is available before continuing.
    
    This does not wait, however, for the thread function to be invoked and,
    indeed, will skip it if kthread_stop() gets called before it gets there.
    
    If this happens, though, kthread_run() will have returned successfully,
    indicating that the thread was started and returning the task_struct
    pointer.  The actual error indication is returned by kthread_stop().
    
    Note that this is ambiguous, as the caller cannot tell whether the -EINTR
    error code came from kthread() or from the thread function.
    
    This was encountered in the new rxrpc I/O thread, where if the system is
    being pounded hard by, say, syzbot, the check of KTHREAD_SHOULD_STOP can be
    delayed long enough for kthread_stop() to get called when rxrpc releases a
    socket - and this causes an oops because the I/O thread function doesn't
    get started and thus doesn't remove the rxrpc_local struct from the
    local_endpoints list.
    
    Fix this by using a completion to wait for the thread to actually enter
    rxrpc_io_thread().  This makes sure the thread can't be prematurely
    stopped and makes sure the relied-upon cleanup is done.
    
    Fixes: a275da62 ("rxrpc: Create a per-local endpoint receive queue and I/O thread")
    Reported-by: syzbot+3538a6a72efa8b059c38@syzkaller.appspotmail.com
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: Marc Dionne <marc.dionne@auristor.com>
    cc: Hillf Danton <hdanton@sina.com>
    Link: https://lore.kernel.org/r/000000000000229f1505ef2b6159@google.com/Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    8fbcc833
local_object.c 11 KB