linux-kernelorg-stable/net/rxrpc
David Howells 2d7b30aef3 rxrpc: Fix race in call state changing vs recvmsg()
There's a race in between the rxrpc I/O thread recording the end of the
receive phase of a call and recvmsg() examining the state of the call to
determine whether it has completed.

The problem is that call->_state records the I/O thread's view of the call,
not the application's view (which may lag), so that alone is not
sufficient.  To this end, the application also checks whether there is
anything left in call->recvmsg_queue for it to pick up.  The call must be
in state RXRPC_CALL_COMPLETE and the recvmsg_queue empty for the call to be
considered fully complete.

In rxrpc_input_queue_data(), the latest skbuff is added to the queue and
then, if it was marked as LAST_PACKET, the state is advanced...  But this
is two separate operations with no locking around them.

As a consequence, the lack of locking means that sendmsg() can jump into
the gap on a service call and attempt to send the reply - but then get
rejected because the I/O thread hasn't advanced the state yet.

Simply flipping the order in which things are done isn't an option as that
impacts the client side, causing the checks in rxrpc_kernel_check_life() as
to whether the call is still alive to race instead.

Fix this by moving the update of call->_state inside the skb queue
spinlocked section where the packet is queued on the I/O thread side.

rxrpc's recvmsg() will then automatically sync against this because it has
to take the call->recvmsg_queue spinlock in order to dequeue the last
packet.

rxrpc's sendmsg() doesn't need amending as the app shouldn't be calling it
to send a reply until recvmsg() indicates it has returned all of the
request.

Fixes: 93368b6bd5 ("rxrpc: Move call state changes from recvmsg to I/O thread")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20250204230558.712536-3-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-02-05 18:47:46 -08:00
..
Kconfig
Makefile rxrpc: Implement RACK/TLP to deal with transmission stalls [RFC8985] 2024-12-09 13:48:33 -08:00
af_rxrpc.c rxrpc: Use irq-disabling spinlocks between app and I/O thread 2024-12-09 13:48:31 -08:00
ar-internal.h rxrpc: Fix call state set to not include the SERVER_SECURING state 2025-02-05 18:47:46 -08:00
call_accept.c rxrpc: Use irq-disabling spinlocks between app and I/O thread 2024-12-09 13:48:31 -08:00
call_event.c rxrpc: Implement RACK/TLP to deal with transmission stalls [RFC8985] 2024-12-09 13:48:33 -08:00
call_object.c rxrpc: Fix call state set to not include the SERVER_SECURING state 2025-02-05 18:47:46 -08:00
call_state.c
conn_client.c rxrpc: Use irq-disabling spinlocks between app and I/O thread 2024-12-09 13:48:31 -08:00
conn_event.c rxrpc: Fix call state set to not include the SERVER_SECURING state 2025-02-05 18:47:46 -08:00
conn_object.c rxrpc: Fix the rxrpc_connection attend queue handling 2025-02-04 15:30:28 +01:00
conn_service.c rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() 2023-12-24 15:22:49 +00:00
input.c rxrpc: Fix race in call state changing vs recvmsg() 2025-02-05 18:47:46 -08:00
input_rack.c rxrpc: Implement RACK/TLP to deal with transmission stalls [RFC8985] 2024-12-09 13:48:33 -08:00
insecure.c rxrpc: Prepare to be able to send jumbo DATA packets 2024-12-09 13:48:26 -08:00
io_thread.c rxrpc: Disable IRQ, not BH, to take the lock for ->attend_link 2024-12-16 18:06:23 -08:00
key.c rxrpc: Fix error when reading rxrpc tokens 2023-04-23 13:38:28 +01:00
local_event.c rxrpc: Truncate UTS_RELEASE for rxrpc version 2023-05-30 10:01:06 +02:00
local_object.c rxrpc: Don't use received skbuff timestamps 2024-12-09 13:48:29 -08:00
misc.c rxrpc: Implement path-MTU probing using padded PING ACKs (RFC8899) 2024-12-09 13:48:25 -08:00
net_ns.c rxrpc: Create a procfile to display outstanding client conn bundles 2023-12-24 15:22:56 +00:00
output.c rxrpc: Implement RACK/TLP to deal with transmission stalls [RFC8985] 2024-12-09 13:48:33 -08:00
peer_event.c rxrpc, afs: Fix peer hash locking vs RCU callback 2025-01-27 14:46:18 -08:00
peer_object.c rxrpc, afs: Fix peer hash locking vs RCU callback 2025-01-27 14:46:18 -08:00
proc.c rxrpc: Manage RTT per-call rather than per-peer 2024-12-09 13:48:32 -08:00
protocol.h rxrpc: Implement path-MTU probing using padded PING ACKs (RFC8899) 2024-12-09 13:48:25 -08:00
recvmsg.c rxrpc: Use irq-disabling spinlocks between app and I/O thread 2024-12-09 13:48:31 -08:00
rtt.c rxrpc: Manage RTT per-call rather than per-peer 2024-12-09 13:48:32 -08:00
rxkad.c rxrpc: Prepare to be able to send jumbo DATA packets 2024-12-09 13:48:26 -08:00
rxperf.c rxrpc: Use umin() and umax() rather than min_t()/max_t() where possible 2024-12-09 13:48:23 -08:00
security.c rxrpc: Use irq-disabling spinlocks between app and I/O thread 2024-12-09 13:48:31 -08:00
sendmsg.c rxrpc: Fix call state set to not include the SERVER_SECURING state 2025-02-05 18:47:46 -08:00
server_key.c
skbuff.c
sysctl.c rxrpc: Implement path-MTU probing using padded PING ACKs (RFC8899) 2024-12-09 13:48:25 -08:00
txbuf.c rxrpc: Don't allocate a txbuf for an ACK transmission 2024-12-09 13:48:31 -08:00
utils.c