Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rxrpc: Fix ability to add more data to a call once MSG_MORE deasserted

When userspace is adding data to an RPC call for transmission, it must pass
MSG_MORE to sendmsg() if it intends to add more data in future calls to
sendmsg(). Calling sendmsg() without MSG_MORE being asserted closes the
transmission phase of the call (assuming sendmsg() adds all the data
presented) and further attempts to add more data should be rejected.

However, this is no longer the case. The change of call state that was
previously the guard got bumped over to the I/O thread, which leaves a
window for a repeat sendmsg() to insert more data. This previously went
unnoticed, but the more recent patch that changed the structures behind the
Tx queue added a warning:

WARNING: CPU: 3 PID: 6639 at net/rxrpc/sendmsg.c:296 rxrpc_send_data+0x3f2/0x860

and rejected the additional data, returning error EPROTO.

Fix this by adding a guard flag to the call, setting the flag when we queue
the final packet and then rejecting further attempts to add data with
EPROTO.

Fixes: 2d689424b618 ("rxrpc: Move call state changes from sendmsg to I/O thread")
Reported-by: syzbot+ff11be94dfcd7a5af8da@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/6757fb68.050a0220.2477f.005f.GAE@google.com/
Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: syzbot+ff11be94dfcd7a5af8da@syzkaller.appspotmail.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/2870480.1734037462@warthog.procyon.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

David Howells and committed by
Jakub Kicinski
ae4f8998 d920270a

+9
+1
net/rxrpc/ar-internal.h
··· 571 571 RXRPC_CALL_RX_LAST, /* Received the last packet (at rxtx_top) */ 572 572 RXRPC_CALL_TX_LAST, /* Last packet in Tx buffer (at rxtx_top) */ 573 573 RXRPC_CALL_TX_ALL_ACKED, /* Last packet has been hard-acked */ 574 + RXRPC_CALL_TX_NO_MORE, /* No more data to transmit (MSG_MORE deasserted) */ 574 575 RXRPC_CALL_SEND_PING, /* A ping will need to be sent */ 575 576 RXRPC_CALL_RETRANS_TIMEOUT, /* Retransmission due to timeout occurred */ 576 577 RXRPC_CALL_BEGAN_RX_TIMER, /* We began the expect_rx_by timer */
+8
net/rxrpc/sendmsg.c
··· 266 266 /* Order send_top after the queue->next pointer and txb content. */ 267 267 smp_store_release(&call->send_top, seq); 268 268 if (last) { 269 + set_bit(RXRPC_CALL_TX_NO_MORE, &call->flags); 269 270 rxrpc_notify_end_tx(rx, call, notify_end_tx); 270 271 call->send_queue = NULL; 271 272 } ··· 329 328 long timeo; 330 329 bool more = msg->msg_flags & MSG_MORE; 331 330 int ret, copied = 0; 331 + 332 + if (test_bit(RXRPC_CALL_TX_NO_MORE, &call->flags)) { 333 + trace_rxrpc_abort(call->debug_id, rxrpc_sendmsg_late_send, 334 + call->cid, call->call_id, call->rx_consumed, 335 + 0, -EPROTO); 336 + return -EPROTO; 337 + } 332 338 333 339 timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); 334 340