• David Howells's avatar
    rxrpc: Fix net namespace cleanup · ccb784fd
    David Howells authored
    [ Upstream commit b13023421b5179413421333f602850914f6a7ad8 ]
    
    In rxrpc_destroy_all_calls(), there are two phases: (1) make sure the
    ->calls list is empty, emitting error messages if not, and (2) wait for the
    RCU cleanup to happen on outstanding calls (ie. ->nr_calls becomes 0).
    
    To avoid taking the call_lock, the function prechecks ->calls and if empty,
    it returns to avoid taking the lock - this is wrong, however: it still
    needs to go and do the second phase and wait for ->nr_calls to become 0.
    
    Without this, the rxrpc_net struct may get deallocated before we get to the
    RCU cleanup for the last calls.  This can lead to:
    
      Slab corruption (Not tainted): kmalloc-16k start=ffff88802b178000, len=16384
      050: 6b 6b 6b 6b 6b 6b 6b 6b 61 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkakkkkkkk
    
    Note the "61" at offset 0x58.  This corresponds to the ->nr_calls member of
    struct rxrpc_net (which is >9k in size, and thus allocated out of the 16k
    slab).
    
    Fix this by flipping the condition on the if-statement, putting the locked
    section inside the if-body and dropping the return from there.  The
    function will then always go on to wait for the RCU cleanup on outstanding
    calls.
    
    Fixes: 2baec2c3 ("rxrpc: Support network namespacing")
    Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
    Signed-off-by: 's avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    ccb784fd
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
af_rxrpc.c Loading commit data...
ar-internal.h Loading commit data...
call_accept.c Loading commit data...
call_event.c Loading commit data...
call_object.c Loading commit data...
conn_client.c Loading commit data...
conn_event.c Loading commit data...
conn_object.c Loading commit data...
conn_service.c Loading commit data...
input.c Loading commit data...
insecure.c Loading commit data...
key.c Loading commit data...
local_event.c Loading commit data...
local_object.c Loading commit data...
misc.c Loading commit data...
net_ns.c Loading commit data...
output.c Loading commit data...
peer_event.c Loading commit data...
peer_object.c Loading commit data...
proc.c Loading commit data...
protocol.h Loading commit data...
recvmsg.c Loading commit data...
rxkad.c Loading commit data...
security.c Loading commit data...
sendmsg.c Loading commit data...
skbuff.c Loading commit data...
sysctl.c Loading commit data...
utils.c Loading commit data...