]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
rxrpc: Fix call state set to not include the SERVER_SECURING state
authorDavid Howells <dhowells@redhat.com>
Tue, 4 Feb 2025 23:05:53 +0000 (23:05 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Feb 2025 02:47:46 +0000 (18:47 -0800)
The RXRPC_CALL_SERVER_SECURING state doesn't really belong with the other
states in the call's state set as the other states govern the call's Rx/Tx
phase transition and govern when packets can and can't be received or
transmitted.  The "Securing" state doesn't actually govern the reception of
packets and would need to be split depending on whether or not we've
received the last packet yet (to mirror RECV_REQUEST/ACK_REQUEST).

The "Securing" state is more about whether or not we can start forwarding
packets to the application as recvmsg will need to decode them and the
decoding can't take place until the challenge/response exchange has
completed.

Fix this by removing the RXRPC_CALL_SERVER_SECURING state from the state
set and, instead, using a flag, RXRPC_CALL_CONN_CHALLENGING, to track
whether or not we can queue the call for reception by recvmsg() or notify
the kernel app that data is ready.  In the event that we've already
received all the packets, the connection event handler will poke the app
layer in the appropriate manner.

Also there's a race whereby the app layer sees the last packet before rxrpc
has managed to end the rx phase and change the state to one amenable to
allowing a reply.  Fix this by queuing the packet after calling
rxrpc_end_rx_phase().

Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
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-2-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/rxrpc/ar-internal.h
net/rxrpc/call_object.c
net/rxrpc/conn_event.c
net/rxrpc/input.c
net/rxrpc/sendmsg.c

index 718193df9d2e21373e4977246c0c13eb64874758..f251845fe532cccc7761acde51c25e507d0c975e 100644 (file)
@@ -582,6 +582,7 @@ enum rxrpc_call_flag {
        RXRPC_CALL_EXCLUSIVE,           /* The call uses a once-only connection */
        RXRPC_CALL_RX_IS_IDLE,          /* recvmsg() is idle - send an ACK */
        RXRPC_CALL_RECVMSG_READ_ALL,    /* recvmsg() read all of the received data */
+       RXRPC_CALL_CONN_CHALLENGING,    /* The connection is being challenged */
 };
 
 /*
@@ -602,7 +603,6 @@ enum rxrpc_call_state {
        RXRPC_CALL_CLIENT_AWAIT_REPLY,  /* - client awaiting reply */
        RXRPC_CALL_CLIENT_RECV_REPLY,   /* - client receiving reply phase */
        RXRPC_CALL_SERVER_PREALLOC,     /* - service preallocation */
-       RXRPC_CALL_SERVER_SECURING,     /* - server securing request connection */
        RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */
        RXRPC_CALL_SERVER_ACK_REQUEST,  /* - server pending ACK of request */
        RXRPC_CALL_SERVER_SEND_REPLY,   /* - server sending reply */
index 5a543c3f6fb0856c745e9136b1476a0b872990bc..c4c8b46a68c67744192b03f7826db45dc5b6b13e 100644 (file)
@@ -22,7 +22,6 @@ const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
        [RXRPC_CALL_CLIENT_AWAIT_REPLY]         = "ClAwtRpl",
        [RXRPC_CALL_CLIENT_RECV_REPLY]          = "ClRcvRpl",
        [RXRPC_CALL_SERVER_PREALLOC]            = "SvPrealc",
-       [RXRPC_CALL_SERVER_SECURING]            = "SvSecure",
        [RXRPC_CALL_SERVER_RECV_REQUEST]        = "SvRcvReq",
        [RXRPC_CALL_SERVER_ACK_REQUEST]         = "SvAckReq",
        [RXRPC_CALL_SERVER_SEND_REPLY]          = "SvSndRpl",
@@ -453,17 +452,16 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
        call->cong_tstamp       = skb->tstamp;
 
        __set_bit(RXRPC_CALL_EXPOSED, &call->flags);
-       rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
+       rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
 
        spin_lock(&conn->state_lock);
 
        switch (conn->state) {
        case RXRPC_CONN_SERVICE_UNSECURED:
        case RXRPC_CONN_SERVICE_CHALLENGING:
-               rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SECURING);
+               __set_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags);
                break;
        case RXRPC_CONN_SERVICE:
-               rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
                break;
 
        case RXRPC_CONN_ABORTED:
index 74bb49b936cd49947dc3f35e02d587b9bfc734fb..4d9c5e21ba785df026493732be9fe877187be3ec 100644 (file)
@@ -228,10 +228,8 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn)
  */
 static void rxrpc_call_is_secure(struct rxrpc_call *call)
 {
-       if (call && __rxrpc_call_state(call) == RXRPC_CALL_SERVER_SECURING) {
-               rxrpc_set_call_state(call, RXRPC_CALL_SERVER_RECV_REQUEST);
+       if (call && __test_and_clear_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags))
                rxrpc_notify_socket(call);
-       }
 }
 
 /*
index 4974b5accafa3372238127b5fccfff05bc8215cf..4a152f3c831fd5d9d1ee2a1d8408d393654223ca 100644 (file)
@@ -657,7 +657,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
                rxrpc_propose_delay_ACK(call, sp->hdr.serial,
                                        rxrpc_propose_ack_input_data);
        }
-       if (notify) {
+       if (notify && !test_bit(RXRPC_CALL_CONN_CHALLENGING, &call->flags)) {
                trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
                rxrpc_notify_socket(call);
        }
index 0e8da909d4f2f43afb46b7f516ab3fb3030aaad5..584397aba4a07bdd09c5c76db26f130bbc87aa51 100644 (file)
@@ -707,7 +707,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
        } else {
                switch (rxrpc_call_state(call)) {
                case RXRPC_CALL_CLIENT_AWAIT_CONN:
-               case RXRPC_CALL_SERVER_SECURING:
+               case RXRPC_CALL_SERVER_RECV_REQUEST:
                        if (p.command == RXRPC_CMD_SEND_ABORT)
                                break;
                        fallthrough;