]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
rxrpc: Fix oob challenge leak in cleanup after notification failure
authorDavid Howells <dhowells@redhat.com>
Wed, 24 Jun 2026 16:38:14 +0000 (17:38 +0100)
committerJakub Kicinski <kuba@kernel.org>
Thu, 25 Jun 2026 17:07:18 +0000 (10:07 -0700)
Fix rxrpc_notify_socket_oob() to return an indication of failure in the
event that it failed to queue a packet and fix rxrpc_post_challenge() to
clean up the connection ref in such an event.

Fixes: 5800b1cf3fd8 ("rxrpc: Allow CHALLENGEs to the passed to the app for a RESPONSE")
Link: https://sashiko.dev/#/patchset/20260616155749.2125907-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jeffrey Altman <jaltman@auristor.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: stable@kernel.org
Link: https://patch.msgid.link/20260624163819.3017002-8-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/rxrpc/ar-internal.h
net/rxrpc/conn_event.c
net/rxrpc/oob.c

index 2a105113cd778619d5136d1b518b1ba13705a67f..ce946b0a03e2b3bbb2ea69d15a8cf700d4dddf1b 100644 (file)
@@ -1376,9 +1376,9 @@ static inline struct rxrpc_net *rxrpc_net(struct net *net)
 }
 
 /*
- * out_of_band.c
+ * oob.c
  */
-void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb);
+bool rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb);
 void rxrpc_add_pending_oob(struct rxrpc_sock *rx, struct sk_buff *skb);
 int rxrpc_sendmsg_oob(struct rxrpc_sock *rx, struct msghdr *msg, size_t len);
 
index c96ca615b787c6bca6dfc51cd944065e1f5505a4..611c790bc6d0ce8aabfd79dbf3015fe15f2a3e0d 100644 (file)
@@ -436,7 +436,7 @@ static bool rxrpc_post_challenge(struct rxrpc_connection *conn,
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_call *call = NULL;
        struct rxrpc_sock *rx;
-       bool respond = false;
+       bool respond = false, queued = false;
 
        sp->chall.conn =
                rxrpc_get_connection(conn, rxrpc_conn_get_challenge_input);
@@ -472,8 +472,13 @@ static bool rxrpc_post_challenge(struct rxrpc_connection *conn,
        }
 
        if (call)
-               rxrpc_notify_socket_oob(call, skb);
+               queued = rxrpc_notify_socket_oob(call, skb);
        rcu_read_unlock();
+       if (call && !queued) {
+               rxrpc_put_connection(conn, rxrpc_conn_put_challenge_input);
+               sp->chall.conn = NULL;
+               return false;
+       }
 
        if (!call)
                rxrpc_post_packet_to_conn(conn, skb);
index 3318c8bd82ad55cf4bb9fd247990644f03e38113..c80ee2487d09410fe67957ed0097031b09e21990 100644 (file)
@@ -32,11 +32,12 @@ struct rxrpc_oob_params {
  * Post an out-of-band message for attention by the socket or kernel service
  * associated with a reference call.
  */
-void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb)
+bool rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct rxrpc_sock *rx;
        struct sock *sk;
+       bool queued = false;
 
        rcu_read_lock();
 
@@ -49,6 +50,7 @@ void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb)
                        skb->skb_mstamp_ns = rx->oob_id_counter++;
                        rxrpc_get_skb(skb, rxrpc_skb_get_post_oob);
                        skb_queue_tail(&rx->recvmsg_oobq, skb);
+                       queued = true;
 
                        trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
                        if (rx->app_ops)
@@ -56,11 +58,12 @@ void rxrpc_notify_socket_oob(struct rxrpc_call *call, struct sk_buff *skb)
                }
 
                spin_unlock_irq(&rx->recvmsg_lock);
-               if (!rx->app_ops && !sock_flag(sk, SOCK_DEAD))
+               if (queued && !rx->app_ops && !sock_flag(sk, SOCK_DEAD))
                        sk->sk_data_ready(sk);
        }
 
        rcu_read_unlock();
+       return queued;
 }
 
 /*