Skip to content

Commit 3c7e594

Browse files
lmcjomagregkh
authored andcommitted
tipc: improve size validations for received domain records
commit 9aa422a upstream. The function tipc_mon_rcv() allows a node to receive and process domain_record structs from peer nodes to track their views of the network topology. This patch verifies that the number of members in a received domain record does not exceed the limit defined by MAX_MON_DOMAIN, something that may otherwise lead to a stack overflow. tipc_mon_rcv() is called from the function tipc_link_proto_rcv(), where we are reading a 32 bit message data length field into a uint16. To avert any risk of bit overflow, we add an extra sanity check for this in that function. We cannot see that happen with the current code, but future designers being unaware of this risk, may introduce it by allowing delivery of very large (> 64k) sk buffers from the bearer layer. This potential problem was identified by Eric Dumazet. This fixes CVE-2022-0435 Reported-by: Samuel Page <samuel.page@appgate.com> Reported-by: Eric Dumazet <edumazet@google.com> Fixes: 35c55c9 ("tipc: add neighbor monitoring framework") Signed-off-by: Jon Maloy <jmaloy@redhat.com> Reviewed-by: Xin Long <lucien.xin@gmail.com> Reviewed-by: Samuel Page <samuel.page@appgate.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 2951d21 commit 3c7e594

2 files changed

Lines changed: 9 additions & 2 deletions

File tree

net/tipc/link.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,7 +2159,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
21592159
struct tipc_msg *hdr = buf_msg(skb);
21602160
struct tipc_gap_ack_blks *ga = NULL;
21612161
bool reply = msg_probe(hdr), retransmitted = false;
2162-
u16 dlen = msg_data_sz(hdr), glen = 0;
2162+
u32 dlen = msg_data_sz(hdr), glen = 0;
21632163
u16 peers_snd_nxt = msg_next_sent(hdr);
21642164
u16 peers_tol = msg_link_tolerance(hdr);
21652165
u16 peers_prio = msg_linkprio(hdr);
@@ -2173,6 +2173,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
21732173
void *data;
21742174

21752175
trace_tipc_proto_rcv(skb, false, l->name);
2176+
2177+
if (dlen > U16_MAX)
2178+
goto exit;
2179+
21762180
if (tipc_link_is_blocked(l) || !xmitq)
21772181
goto exit;
21782182

@@ -2268,7 +2272,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
22682272

22692273
/* Receive Gap ACK blocks from peer if any */
22702274
glen = tipc_get_gap_ack_blks(&ga, l, hdr, true);
2271-
2275+
if(glen > dlen)
2276+
break;
22722277
tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr,
22732278
&l->mon_state, l->bearer_id);
22742279

net/tipc/monitor.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr,
465465
state->probing = false;
466466

467467
/* Sanity check received domain record */
468+
if (new_member_cnt > MAX_MON_DOMAIN)
469+
return;
468470
if (dlen < dom_rec_len(arrv_dom, 0))
469471
return;
470472
if (dlen != dom_rec_len(arrv_dom, new_member_cnt))

0 commit comments

Comments
 (0)