Thread (3 messages) flat view 3 messages, 2 authors, 6d ago
COOLING6d

[PATCH] tipc: validate data size before reading Gap ACK block header

From: Aamir Ahmed <hidden>
Date: 2026-09-06 23:38:26
Also in: lkml, stable
Subsystem: networking [general], the rest, tipc network layer · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Jon Maloy, Tung Quang Nguyen

tipc_get_gap_ack_blks() reads the Gap ACK block header fields (len,
ugack_cnt, bgack_cnt) from msg_data(hdr) without first checking that the
message data area is large enough to hold the header struct.  A peer
that has negotiated TIPC_GAP_ACK_BLOCK capability can send a STATE_MSG
or broadcast PROTOCOL message with a data area shorter than
sizeof(struct tipc_gap_ack_blks), causing an out-of-bounds read of up
to 4 bytes past the valid skb data.

In the backward-compatible code path, a 1-byte out-of-bounds write also
occurs through "p->bgack_cnt = 0".

Both callers (tipc_link_proto_rcv and tipc_bcast_sync_rcv) validate the
returned size against msg_data_sz() after the function returns, so the
invalid data is never used further.  However, the OOB accesses inside
the function itself are undefined behavior and are detectable by KASAN.

Add a check at the start of the function that msg_data_sz(hdr) is at
least sizeof(*p) before reading any fields, jumping to the p = NULL path
when the data area is too small.

Fixes: d7626b5acff9 ("tipc: introduce Gap ACK blocks for broadcast link")
Cc: stable@vger.kernel.org
---
 net/tipc/link.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 6427c69f8929..0be86cbdc913 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1419,6 +1419,8 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l,
 
 	/* Does peer support the Gap ACK blocks feature? */
 	if (l->peer_caps & TIPC_GAP_ACK_BLOCK) {
+		if (msg_data_sz(hdr) < sizeof(*p))
+			goto out;
 		p = (struct tipc_gap_ack_blks *)msg_data(hdr);
 		sz = ntohs(p->len);
 		/* Sanity check */
@@ -1435,6 +1437,7 @@ u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l,
 		}
 	}
 	/* Other cases: ignore! */
+out:
 	p = NULL;
 
 ok:
-- 
2.43.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