• David Howells's avatar
    rxrpc: Fix race between incoming ACK parser and retransmitter · 2ad6691d
    David Howells authored
    There's a race between the retransmission code and the received ACK parser.
    The problem is that the retransmission loop has to drop the lock under
    which it is iterating through the transmission buffer in order to transmit
    a packet, but whilst the lock is dropped, the ACK parser can crank the Tx
    window round and discard the packets from the buffer.
    
    The retransmission code then updated the annotations for the wrong packet
    and a later retransmission thought it had to retransmit a packet that
    wasn't there, leading to a NULL pointer dereference.
    
    Fix this by:
    
     (1) Moving the annotation change to before we drop the lock prior to
         transmission.  This means we can't vary the annotation depending on
         the outcome of the transmission, but that's fine - we'll retransmit
         again later if it failed now.
    
     (2) Skipping the packet if the skb pointer is NULL.
    
    The following oops was seen:
    
    	BUG: kernel NULL pointer dereference, address: 000000000000002d
    	Workqueue: krxrpcd rxrpc_process_call
    	RIP: 0010:rxrpc_get_skb+0x14/0x8a
    	...
    	Call Trace:
    	 rxrpc_resend+0x331/0x41e
    	 ? get_vtime_delta+0x13/0x20
    	 rxrpc_process_call+0x3c0/0x4ac
    	 process_one_work+0x18f/0x27f
    	 worker_thread+0x1a3/0x247
    	 ? create_worker+0x17d/0x17d
    	 kthread+0xe6/0xeb
    	 ? kthread_delayed_work_timer_fn+0x83/0x83
    	 ret_from_fork+0x1f/0x30
    
    Fixes: 248f219c ("rxrpc: Rewrite the data and ack handling code")
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    2ad6691d
call_event.c 12 KB