Thread (7 messages) 7 messages, 2 authors, 2026-06-03

RE: [PATCH net 3/4] tipc: prevent snt_unacked underflow on CONN_ACK

From: Tung Quang Nguyen <hidden>
Date: 2026-06-03 03:55:43
Also in: lkml

quoted hunk ↗ jump to hunk
Subject: [PATCH net 3/4] tipc: prevent snt_unacked underflow on CONN_ACK

tipc_sk_conn_proto_rcv() subtracts the peer-supplied connection ack count
from the unsigned 16-bit send counter snt_unacked without checking that it
does not exceed the number of messages actually
outstanding:

tsk->snt_unacked -= msg_conn_ack(hdr);

msg_conn_ack() is read straight from a received CONN_MANAGER/CONN_ACK
message. If the ack count is larger than snt_unacked the subtraction wraps to a
near-maximum value, leaving tsk_conn_cong() permanently true and starving
the connection of further transmits.

Cap the ack to the outstanding count before subtracting. A peer (or, for a local
connection, the connected peer socket) can otherwise wedge a TIPC
connection's send side by sending an oversized connection ack.

Fixes: 10724cc7bb78 ("tipc: redesign connection-level flow control")
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Michael Bommarito <redacted>
---
net/tipc/socket.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index
9329919fb07f0..9c739a3cea126 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1362,9 +1362,16 @@ static void tipc_sk_conn_proto_rcv(struct tipc_sock
*tsk, struct sk_buff *skb,
			__skb_queue_tail(xmitq, skb);
		return;
	} else if (mtyp == CONN_ACK) {
+		u16 conn_ack = msg_conn_ack(hdr);
+
		was_cong = tsk_conn_cong(tsk);
		tipc_sk_push_backlog(tsk, msg_nagle_ack(hdr));
-		tsk->snt_unacked -= msg_conn_ack(hdr);
+		/* Cap a peer-supplied ack so a forged value cannot underflow
+		 * the unsigned counter and wedge connection flow control.
+		 */
+		if (conn_ack > tsk->snt_unacked)
This handling of an invalid field in the message header is not correct.
Please validate this field at the beginning of the body block and drop the message if it is invalid.
 
+			conn_ack = tsk->snt_unacked;
+		tsk->snt_unacked -= conn_ack;
		if (tsk->peer_caps & TIPC_BLOCK_FLOWCTL)
			tsk->snd_win = msg_adv_win(hdr);
		if (was_cong && !tsk_conn_cong(tsk))
--
2.53.0
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help