• David Howells's avatar
    rxrpc: Make service call handling more robust · 0099dc58
    David Howells authored
    Make the following changes to improve the robustness of the code that sets
    up a new service call:
    
     (1) Cache the rxrpc_sock struct obtained in rxrpc_data_ready() to do a
         service ID check and pass that along to rxrpc_new_incoming_call().
         This means that I can remove the check from rxrpc_new_incoming_call()
         without the need to worry about the socket attached to the local
         endpoint getting replaced - which would invalidate the check.
    
     (2) Cache the rxrpc_peer struct, thereby allowing the peer search to be
         done once.  The peer is passed to rxrpc_new_incoming_call(), thereby
         saving the need to repeat the search.
    
         This also reduces the possibility of rxrpc_publish_service_conn()
         BUG()'ing due to the detection of a duplicate connection, despite the
         initial search done by rxrpc_find_connection_rcu() having turned up
         nothing.
    
         This BUG() shouldn't ever get hit since rxrpc_data_ready() *should* be
         non-reentrant and the result of the initial search should still hold
         true, but it has proven possible to hit.
    
         I *think* this may be due to __rxrpc_lookup_peer_rcu() cutting short
         the iteration over the hash table if it finds a matching peer with a
         zero usage count, but I don't know for sure since it's only ever been
         hit once that I know of.
    
         Another possibility is that a bug in rxrpc_data_ready() that checked
         the wrong byte in the header for the RXRPC_CLIENT_INITIATED flag
         might've let through a packet that caused a spurious and invalid call
         to be set up.  That is addressed in another patch.
    
     (3) Fix __rxrpc_lookup_peer_rcu() to skip peer records that have a zero
         usage count rather than stopping and returning not found, just in case
         there's another peer record behind it in the bucket.
    
     (4) Don't search the peer records in rxrpc_alloc_incoming_call(), but
         rather either use the peer cached in (2) or, if one wasn't found,
         preemptively install a new one.
    
    Fixes: 8496af50 ("rxrpc: Use RCU to access a peer's service connection tree")
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    0099dc58
peer_object.c 12 KB