提交 9aa422ad 编写于 作者: J Jon Maloy 提交者: Linus Torvalds

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: NSamuel Page <samuel.page@appgate.com>
Reported-by: NEric Dumazet <edumazet@google.com>
Fixes: 35c55c98 ("tipc: add neighbor monitoring framework")
Signed-off-by: NJon Maloy <jmaloy@redhat.com>
Reviewed-by: NXin Long <lucien.xin@gmail.com>
Reviewed-by: NSamuel Page <samuel.page@appgate.com>
Reviewed-by: NEric Dumazet <edumazet@google.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 f4bc5bbb
...@@ -2200,7 +2200,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -2200,7 +2200,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
struct tipc_msg *hdr = buf_msg(skb); struct tipc_msg *hdr = buf_msg(skb);
struct tipc_gap_ack_blks *ga = NULL; struct tipc_gap_ack_blks *ga = NULL;
bool reply = msg_probe(hdr), retransmitted = false; 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_snd_nxt = msg_next_sent(hdr);
u16 peers_tol = msg_link_tolerance(hdr); u16 peers_tol = msg_link_tolerance(hdr);
u16 peers_prio = msg_linkprio(hdr); u16 peers_prio = msg_linkprio(hdr);
...@@ -2214,6 +2214,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -2214,6 +2214,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
void *data; void *data;
trace_tipc_proto_rcv(skb, false, l->name); trace_tipc_proto_rcv(skb, false, l->name);
if (dlen > U16_MAX)
goto exit;
if (tipc_link_is_blocked(l) || !xmitq) if (tipc_link_is_blocked(l) || !xmitq)
goto exit; goto exit;
...@@ -2309,7 +2313,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, ...@@ -2309,7 +2313,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
/* Receive Gap ACK blocks from peer if any */ /* Receive Gap ACK blocks from peer if any */
glen = tipc_get_gap_ack_blks(&ga, l, hdr, true); 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, tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr,
&l->mon_state, l->bearer_id); &l->mon_state, l->bearer_id);
......
...@@ -496,6 +496,8 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, ...@@ -496,6 +496,8 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr,
state->probing = false; state->probing = false;
/* Sanity check received domain record */ /* Sanity check received domain record */
if (new_member_cnt > MAX_MON_DOMAIN)
return;
if (dlen < dom_rec_len(arrv_dom, 0)) if (dlen < dom_rec_len(arrv_dom, 0))
return; return;
if (dlen != dom_rec_len(arrv_dom, new_member_cnt)) if (dlen != dom_rec_len(arrv_dom, new_member_cnt))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册