Skip to content
  • David Howells's avatar
    rxrpc: Fix call RCU cleanup using non-bh-safe locks · 963485d4
    David Howells authored
    rxrpc_rcu_destroy_call(), which is called as an RCU callback to clean up a
    put call, calls rxrpc_put_connection() which, deep in its bowels, takes a
    number of spinlocks in a non-BH-safe way, including rxrpc_conn_id_lock and
    local->client_conns_lock.  RCU callbacks, however, are normally called from
    softirq context, which can cause lockdep to notice the locking
    inconsistency.
    
    To get lockdep to detect this, it's necessary to have the connection
    cleaned up on the put at the end of the last of its calls, though normally
    the clean up is deferred.  This can be induced, however, by starting a call
    on an AF_RXRPC socket and then closing the socket without reading the
    reply.
    
    Fix this by having rxrpc_rcu_destroy_call() punt the destruction to a
    workqueue if in softirq-mode and defer the destruction to process context.
    
    Note that another way to fix this could be to add a bunch of bh-disable
    annotations to the spinlocks concerned - and there might be more than just
    those two - but that means spending more time with BHs disabled.
    
    Note also that some of these places were covered by bh-disable spinlocks
    belonging to the rxrpc_transport object, but these got removed without the
    _bh annotation being retained on the next lock in.
    
    Fixes: 999b69f8
    
     ("rxrpc: Kill the client connection bundle concept")
    Reported-by: default avatar <syzbot+d82f3ac8d87e7ccbb2c9@syzkaller.appspotmail.com>
    Reported-by: default avatar <syzbot+3f1fd6b8cbf8702d134e@syzkaller.appspotmail.com>
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    cc: Hillf Danton <hdanton@sina.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    963485d4