Skip to content

Commit 884af6a

Browse files
committed
Merge branch 'rxrpc-call-state-fixes'
David Howells says: ==================== rxrpc: Call state fixes Here some call state fixes for AF_RXRPC. (1) Fix the state of a call to not treat the challenge-response cycle as part of an incoming call's state set. The problem is that it makes handling received of the final packet in the receive phase difficult as that wants to change the call state - but security negotiations may not yet be complete. (2) Fix a race between the changing of the call state at the end of the request reception phase of a service call, recvmsg() collecting the last data and sendmsg() trying to send the reply before the I/O thread has advanced the call state. Link: https://lore.kernel.org/20250203110307.7265-2-dhowells@redhat.com ==================== Link: https://patch.msgid.link/20250204230558.712536-1-dhowells@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 811b8f5 + 2d7b30a commit 884af6a

File tree

5 files changed

+15
-11
lines changed

5 files changed

+15
-11
lines changed

net/rxrpc/ar-internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ enum rxrpc_call_flag {
582582
RXRPC_CALL_EXCLUSIVE, /* The call uses a once-only connection */
583583
RXRPC_CALL_RX_IS_IDLE, /* recvmsg() is idle - send an ACK */
584584
RXRPC_CALL_RECVMSG_READ_ALL, /* recvmsg() read all of the received data */
585+
RXRPC_CALL_CONN_CHALLENGING, /* The connection is being challenged */
585586
};
586587

587588
/*
@@ -602,7 +603,6 @@ enum rxrpc_call_state {
602603
RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */
603604
RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */
604605
RXRPC_CALL_SERVER_PREALLOC, /* - service preallocation */
605-
RXRPC_CALL_SERVER_SECURING, /* - server securing request connection */
606606
RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */
607607
RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */
608608
RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */

net/rxrpc/call_object.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
2222
[RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
2323
[RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
2424
[RXRPC_CALL_SERVER_PREALLOC] = "SvPrealc",
25-
[RXRPC_CALL_SERVER_SECURING] = "SvSecure",
2625
[RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq",
2726
[RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq",
2827
[RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl",
@@ -453,17 +452,16 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
453452
call->cong_tstamp = skb->tstamp;
454453

455454
__set_bit(RXRPC_CALL_EXPOSED, &call->flags);
456-
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
455+
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
457456

458457
spin_lock(&conn->state_lock);
459458

460459
switch (conn->state) {
461460
case RXRPC_CONN_SERVICE_UNSECURED:
462461
case RXRPC_CONN_SERVICE_CHALLENGING:
463-
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
462+
__set_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags);
464463
break;
465464
case RXRPC_CONN_SERVICE:
466-
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
467465
break;
468466

469467
case RXRPC_CONN_ABORTED:

net/rxrpc/conn_event.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,8 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn)
228228
*/
229229
static void rxrpc_call_is_secure(struct rxrpc_call *call)
230230
{
231-
if (call && __rxrpc_call_state(call) == RXRPC_CALL_SERVER_SECURING) {
232-
rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
231+
if (call && __test_and_clear_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags))
233232
rxrpc_notify_socket(call);
234-
}
235233
}
236234

237235
/*

net/rxrpc/input.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,19 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
448448
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
449449
bool last = sp->hdr.flags & RXRPC_LAST_PACKET;
450450

451-
skb_queue_tail(&call->recvmsg_queue, skb);
451+
spin_lock_irq(&call->recvmsg_queue.lock);
452+
453+
__skb_queue_tail(&call->recvmsg_queue, skb);
452454
rxrpc_input_update_ack_window(call, window, wtop);
453455
trace_rxrpc_receive(call, last ? why + 1 : why, sp->hdr.serial, sp->hdr.seq);
454456
if (last)
457+
/* Change the state inside the lock so that recvmsg syncs
458+
* correctly with it and using sendmsg() to send a reply
459+
* doesn't race.
460+
*/
455461
rxrpc_end_rx_phase(call, sp->hdr.serial);
462+
463+
spin_unlock_irq(&call->recvmsg_queue.lock);
456464
}
457465

458466
/*
@@ -657,7 +665,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
657665
rxrpc_propose_delay_ACK(call, sp->hdr.serial,
658666
rxrpc_propose_ack_input_data);
659667
}
660-
if (notify) {
668+
if (notify && !test_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) {
661669
trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
662670
rxrpc_notify_socket(call);
663671
}

net/rxrpc/sendmsg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
707707
} else {
708708
switch (rxrpc_call_state(call)) {
709709
case RXRPC_CALL_CLIENT_AWAIT_CONN:
710-
case RXRPC_CALL_SERVER_SECURING:
710+
case RXRPC_CALL_SERVER_RECV_REQUEST:
711711
if (p.command == RXRPC_CMD_SEND_ABORT)
712712
break;
713713
fallthrough;

0 commit comments

Comments
 (0)