rxrpc: Extract the code from a received ABORT packet much earlier
authorDavid Howells <dhowells@redhat.com>
Mon, 14 Nov 2022 12:21:32 +0000 (12:21 +0000)
committerDavid Howells <dhowells@redhat.com>
Thu, 1 Dec 2022 13:36:38 +0000 (13:36 +0000)
Extract the code from a received rx ABORT packet much earlier and in a
single place and harmonise the responses to malformed ABORT packets.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org

net/rxrpc/conn_event.c
net/rxrpc/input.c

index 71ed6b9..f890a30 100644 (file)
@@ -282,8 +282,6 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
                               u32 *_abort_code)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
-       __be32 wtmp;
-       u32 abort_code;
        int loop, ret;
 
        if (conn->state >= RXRPC_CONN_REMOTELY_ABORTED) {
@@ -305,16 +303,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
                return 0;
 
        case RXRPC_PACKET_TYPE_ABORT:
-               if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
-                                 &wtmp, sizeof(wtmp)) < 0) {
-                       trace_rxrpc_rx_eproto(NULL, sp->hdr.serial,
-                                             tracepoint_string("bad_abort"));
-                       return -EPROTO;
-               }
-               abort_code = ntohl(wtmp);
-
                conn->error = -ECONNABORTED;
-               conn->abort_code = abort_code;
+               conn->abort_code = skb->priority;
                conn->state = RXRPC_CONN_REMOTELY_ABORTED;
                set_bit(RXRPC_CONN_DONT_REUSE, &conn->flags);
                rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED, sp->hdr.serial);
index 44caf88..42c8257 100644 (file)
@@ -1019,20 +1019,11 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb)
 static void rxrpc_input_abort(struct rxrpc_call *call, struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
-       __be32 wtmp;
-       u32 abort_code = RX_CALL_DEAD;
-
-       _enter("");
-
-       if (skb->len >= 4 &&
-           skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
-                         &wtmp, sizeof(wtmp)) >= 0)
-               abort_code = ntohl(wtmp);
 
-       trace_rxrpc_rx_abort(call, sp->hdr.serial, abort_code);
+       trace_rxrpc_rx_abort(call, sp->hdr.serial, skb->priority);
 
        rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED,
-                                 abort_code, -ECONNABORTED);
+                                 skb->priority, -ECONNABORTED);
 }
 
 /*
@@ -1193,6 +1184,20 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
        return 0;
 }
 
+/*
+ * Extract the abort code from an ABORT packet and stash it in skb->priority.
+ */
+static bool rxrpc_extract_abort(struct sk_buff *skb)
+{
+       __be32 wtmp;
+
+       if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
+                         &wtmp, sizeof(wtmp)) < 0)
+               return false;
+       skb->priority = ntohl(wtmp);
+       return true;
+}
+
 /*
  * handle data received on the local endpoint
  * - may be called in interrupt context
@@ -1264,8 +1269,10 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
        case RXRPC_PACKET_TYPE_ACKALL:
                if (sp->hdr.callNumber == 0)
                        goto bad_message;
-               fallthrough;
+               break;
        case RXRPC_PACKET_TYPE_ABORT:
+               if (!rxrpc_extract_abort(skb))
+                       return true; /* Just discard if malformed */
                break;
 
        case RXRPC_PACKET_TYPE_DATA: