[SRU Bionic 1/1] tipc: improve size validations for received domain records

Thadeu Lima de Souza Cascardo cascardo at canonical.com
Mon Feb 14 14:25:14 UTC 2022


From: Jon Maloy <jmaloy at redhat.com>

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

Reported-by: Samuel Page <samuel.page at appgate.com>
Reported-by: Eric Dumazet <edumazet at google.com>
Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework")
Signed-off-by: Jon Maloy <jmaloy at redhat.com>
Reviewed-by: Xin Long <lucien.xin at gmail.com>
Reviewed-by: Samuel Page <samuel.page at appgate.com>
Reviewed-by: Eric Dumazet <edumazet at google.com>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
(cherry picked from commit fde4ddeadd099bf9fbb9ccbee8e1b5c20d530a2d linux-4.14.y)
CVE-2022-0435
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
---
 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 a711caf8d6a9..5b9b9d3054d5 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1469,13 +1469,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 5453e564da82..057965d97426 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))
-- 
2.32.0




More information about the kernel-team mailing list