Commit 4241a702 authored by David Howells's avatar David Howells Committed by Paolo Abeni
Browse files

rxrpc: Fix the rxrpc_connection attend queue handling



The rxrpc_connection attend queue is never used because conn::attend_link
is never initialised and so is always NULL'd out and thus always appears to
be busy.  This requires the following fix:

 (1) Fix this the attend queue problem by initialising conn::attend_link.

And, consequently, two further fixes for things masked by the above bug:

 (2) Fix rxrpc_input_conn_event() to handle being invoked with a NULL
     sk_buff pointer - something that can now happen with the above change.

 (3) Fix the RXRPC_SKB_MARK_SERVICE_CONN_SECURED message to carry a pointer
     to the connection and a ref on it.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: netdev@vger.kernel.org
Fixes: f2cce89a ("rxrpc: Implement a mechanism to send an event notification to a connection")
Link: https://patch.msgid.link/20250203110307.7265-3-dhowells@redhat.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent d3ed6dee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@
	EM(rxrpc_conn_get_conn_input,		"GET inp-conn") \
	EM(rxrpc_conn_get_idle,			"GET idle    ") \
	EM(rxrpc_conn_get_poke_abort,		"GET pk-abort") \
	EM(rxrpc_conn_get_poke_secured,		"GET secured ") \
	EM(rxrpc_conn_get_poke_timer,		"GET poke    ") \
	EM(rxrpc_conn_get_service_conn,		"GET svc-conn") \
	EM(rxrpc_conn_new_client,		"NEW client  ") \
+10 −7
Original line number Diff line number Diff line
@@ -272,6 +272,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
			 * we've already received the packet, put it on the
			 * front of the queue.
			 */
			sp->conn = rxrpc_get_connection(conn, rxrpc_conn_get_poke_secured);
			skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED;
			rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured);
			skb_queue_head(&conn->local->rx_queue, skb);
@@ -437,6 +438,7 @@ void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb)
	if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events))
		rxrpc_abort_calls(conn);

	if (skb) {
		switch (skb->mark) {
		case RXRPC_SKB_MARK_SERVICE_CONN_SECURED:
			if (conn->state != RXRPC_CONN_SERVICE)
@@ -446,6 +448,7 @@ void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb)
				rxrpc_call_is_secure(conn->channels[loop].call);
			break;
		}
	}

	/* Process delayed ACKs whose time has come. */
	if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet,
		INIT_WORK(&conn->destructor, rxrpc_clean_up_connection);
		INIT_LIST_HEAD(&conn->proc_link);
		INIT_LIST_HEAD(&conn->link);
		INIT_LIST_HEAD(&conn->attend_link);
		mutex_init(&conn->security_lock);
		mutex_init(&conn->tx_data_alloc_lock);
		skb_queue_head_init(&conn->rx_queue);