Blob Blame History Raw
From 8db2609e76912d088d19ba0938e80c5628e58e9e Mon Sep 17 00:00:00 2001
From: Joe Lawrence <joe.lawrence@redhat.com>
Date: Thu, 3 Mar 2022 11:44:42 -0500
Subject: [KPATCH CVE-2022-0435] tipc: kpatch fixes for CVE-2022-0435

Kernels:
4.18.0-348.el8
4.18.0-348.2.1.el8_5
4.18.0-348.7.1.el8_5
4.18.0-348.12.2.el8_5

Changes since last build:
[x86_64]:
link.o: changed function: tipc_link_rcv
monitor.o: changed function: tipc_mon_rcv

[ppc64le]:
link.o: changed function: tipc_link_proto_rcv
monitor.o: changed function: tipc_mon_rcv

---------------------------

Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/36
Approved-by: Yannick Cote (@ycote1)
Kernels:
4.18.0-348.el8
4.18.0-348.2.1.el8_5
4.18.0-348.7.1.el8_5
4.18.0-348.12.2.el8_5

Modifications: none

commit 8b2b73e6cb7bd6d9d5af8d21f15d002a373d0a2e
Author: Xin Long <lxin@redhat.com>
Date:   Thu Feb 10 21:43:20 2022 -0500

    tipc: improve size validations for received domain records

    Bugzilla: https://bugzilla.redhat.com/2048970
    CVE: CVE-2022-0435
    Y-Commit: 0e080c279fd19325b263617515835d6ce45e88f4

    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2048971
    O-CVE: CVE-2022-0435
    Tested: compile only

    commit 9aa422ad326634b76309e8ff342c246800621216
    Author: Jon Maloy <jmaloy@redhat.com>
    Date:   Sat Feb 5 14:11:18 2022 -0500

        tipc: improve size validations for received domain records

        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: 35c55c9877f8 ("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: Xin Long <lxin@redhat.com>
    Signed-off-by: Bruno Meneguele <bmeneg@redhat.com>

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
---
 net/tipc/link.c    | 9 +++++++--
 net/tipc/monitor.c | 2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index b5ed87dded2c..062ec1989c41 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2165,7 +2165,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
 	struct tipc_msg *hdr = buf_msg(skb);
 	struct tipc_gap_ack_blks *ga = NULL;
 	bool reply = msg_probe(hdr), retransmitted = false;
-	u16 dlen = msg_data_sz(hdr), glen = 0;
+	u32 dlen = msg_data_sz(hdr), glen = 0;
 	u16 peers_snd_nxt =  msg_next_sent(hdr);
 	u16 peers_tol = msg_link_tolerance(hdr);
 	u16 peers_prio = msg_linkprio(hdr);
@@ -2179,6 +2179,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
 	void *data;
 
 	trace_tipc_proto_rcv(skb, false, l->name);
+
+	if (dlen > U16_MAX)
+		goto exit;
+
 	if (tipc_link_is_blocked(l) || !xmitq)
 		goto exit;
 
@@ -2275,7 +2279,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
 
 		/* Receive Gap ACK blocks from peer if any */
 		glen = tipc_get_gap_ack_blks(&ga, l, hdr, true);
-
+		if(glen > dlen)
+			break;
 		tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr,
 			     &l->mon_state, l->bearer_id);
 
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index 6dce2abf436e..a37190da5a50 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -465,6 +465,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.34.1