From 533d4093462b55607000213dbfdc23639acbc322 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Sat, 5 Feb 2022 14:11:18 -0500 Subject: [PATCH] tipc: improve size validations for received domain records ANBZ: #451 commit 9aa422ad326634b76309e8ff342c246800621216 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 [Backport Notes] Backport from upstream stable commit f1af11edd08dd8376f7a84487cbb0ea8203e3a1d Reported-by: Samuel Page Reported-by: Eric Dumazet Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") Signed-off-by: Jon Maloy Reviewed-by: Xin Long Reviewed-by: Samuel Page Reviewed-by: Eric Dumazet Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Signed-off-by: Dust Li Acked-by: Xuan Zhuo --- net/tipc/link.c | 5 ++++- net/tipc/monitor.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 0fbf8ea18ce04f..49dc99619938d2 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1561,13 +1561,16 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, u16 peers_tol = msg_link_tolerance(hdr); u16 peers_prio = msg_linkprio(hdr); u16 rcv_nxt = l->rcv_nxt; - u16 dlen = msg_data_sz(hdr); + u32 dlen = msg_data_sz(hdr); int mtyp = msg_type(hdr); bool reply = msg_probe(hdr); void *data; char *if_name; int rc = 0; + if (dlen > U16_MAX) + goto exit; + if (tipc_link_is_blocked(l) || !xmitq) goto exit; diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 67f69389ec179b..4294e5fd801a7c 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -457,6 +457,8 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, state->probing = false; /* Sanity check received domain record */ + if (new_member_cnt > MAX_MON_DOMAIN) + return; if (dlen < dom_rec_len(arrv_dom, 0)) return; if (dlen != dom_rec_len(arrv_dom, new_member_cnt))