diff options
| author | David Howells <dhowells@redhat.com> | 2023-01-06 16:03:18 +0300 | 
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2023-01-07 12:30:26 +0300 | 
| commit | 42f229c350f57a8e825f7591e17cbc5c87e50235 (patch) | |
| tree | d23e4db2c49fee5670e336e3c25624ee6a5509a9 /tools/lib/api/fs/tracing_path.c | |
| parent | 9d35d880e0e4a3ab32d8c12f9e4d76198aadd42d (diff) | |
| download | linux-42f229c350f57a8e825f7591e17cbc5c87e50235.tar.xz | |
rxrpc: Fix incoming call setup race
An incoming call can race with rxrpc socket destruction, leading to a
leaked call.  This may result in an oops when the call timer eventually
expires:
   BUG: kernel NULL pointer dereference, address: 0000000000000874
   RIP: 0010:_raw_spin_lock_irqsave+0x2a/0x50
   Call Trace:
    <IRQ>
    try_to_wake_up+0x59/0x550
    ? __local_bh_enable_ip+0x37/0x80
    ? rxrpc_poke_call+0x52/0x110 [rxrpc]
    ? rxrpc_poke_call+0x110/0x110 [rxrpc]
    ? rxrpc_poke_call+0x110/0x110 [rxrpc]
    call_timer_fn+0x24/0x120
with a warning in the kernel log looking something like:
   rxrpc: Call 00000000ba5e571a still in use (1,SvAwtACK,1061d,0)!
incurred during rmmod of rxrpc.  The 1061d is the call flags:
   RECVMSG_READ_ALL, RX_HEARD, BEGAN_RX_TIMER, RX_LAST, EXPOSED,
   IS_SERVICE, RELEASED
but no DISCONNECTED flag (0x800), so it's an incoming (service) call and
it's still connected.
The race appears to be that:
 (1) rxrpc_new_incoming_call() consults the service struct, checks sk_state
     and allocates a call - then pauses, possibly for an interrupt.
 (2) rxrpc_release_sock() sets RXRPC_CLOSE, nulls the service pointer,
     discards the prealloc and releases all calls attached to the socket.
 (3) rxrpc_new_incoming_call() resumes, launching the new call, including
     its timer and attaching it to the socket.
Fix this by read-locking local->services_lock to access the AF_RXRPC socket
providing the service rather than RCU in rxrpc_new_incoming_call().
There's no real need to use RCU here as local->services_lock is only
write-locked by the socket side in two places: when binding and when
shutting down.
Fixes: 5e6ef4f1017c ("rxrpc: Make the I/O thread take over the call and local processor work")
Reported-by: Marc Dionne <marc.dionne@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: linux-afs@lists.infradead.org
Diffstat (limited to 'tools/lib/api/fs/tracing_path.c')
0 files changed, 0 insertions, 0 deletions
