rxrpc: Fix oob challenge leak in cleanup after notification failure

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: 5800b1cf3f ("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>
This commit is contained in:
David Howells 2026-06-24 17:38:14 +01:00 committed by Jakub Kicinski
parent a58e33405a
commit 092275882a
3 changed files with 14 additions and 6 deletions

View 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);

View 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);

View 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;
}
/*