]> git.baikalelectronics.ru Git - kernel.git/commit
rxrpc: Fix race between incoming ACK parser and retransmitter
authorDavid Howells <dhowells@redhat.com>
Thu, 11 Jun 2020 20:57:00 +0000 (21:57 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 12 Jun 2020 01:18:22 +0000 (18:18 -0700)
commite80fe3262e5dafd856c9a0465cdb17144a04a9a5
tree70af0d718096dff609e04878213d985284b3adbf
parent4b0a457989e10e2bccbbc7c7015dbd5a454e065e
rxrpc: Fix race between incoming ACK parser and retransmitter

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: a42fc64729e7 ("rxrpc: Rewrite the data and ack handling code")
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rxrpc/call_event.c