Fix CVE-2022-48865.
Tung Nguyen (1): tipc: fix kernel panic when enabling bearer
Tuong Lien (1): tipc: fix NULL pointer dereference in tipc_disc_rcv()
net/tipc/bearer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
From: Tuong Lien tuong.t.lien@dektech.com.au
mainline inclusion from mainline-v5.8-rc1 commit 9798278260e8f61d04415342544a8f701bc5ace7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IADGRO CVE: CVE-2022-48865
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
When a bearer is enabled, we create a 'tipc_discoverer' object to store the bearer related data along with a timer and a preformatted discovery message buffer for later probing... However, this is only carried after the bearer was set 'up', that left a race condition resulting in kernel panic.
It occurs when a discovery message from a peer node is received and processed in bottom half (since the bearer is 'up' already) just before the discoverer object is created but is now accessed in order to update the preformatted buffer (with a new trial address, ...) so leads to the NULL pointer dereference.
We solve the problem by simply moving the bearer 'up' setting to later, so make sure everything is ready prior to any message receiving.
Acked-by: Jon Maloy jmaloy@redhat.com Signed-off-by: Tuong Lien tuong.t.lien@dektech.com.au Signed-off-by: David S. Miller davem@davemloft.net
Conflicts: net/tipc/bearer.c [The conflict occurs because the commit is not merged] Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- net/tipc/bearer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 6f808402bb21..aabb8084a19c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -312,7 +312,6 @@ static int tipc_enable_bearer(struct net *net, const char *name, b->domain = disc_domain; b->net_plane = bearer_id + 'A'; b->priority = prio; - test_and_set_bit_lock(0, &b->up);
res = tipc_disc_create(net, b, &b->bcast_addr, &skb); if (res) { @@ -321,6 +320,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, goto rejected; }
+ test_and_set_bit_lock(0, &b->up); rcu_assign_pointer(tn->bearer_list[bearer_id], b); if (skb) tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr);
From: Tung Nguyen tung.q.nguyen@dektech.com.au
mainline inclusion from mainline-v5.17-rc8 commit be4977b847f5d5cedb64d50eaaf2218c3a55a3a3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IADGRO CVE: CVE-2022-48865
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
When enabling a bearer on a node, a kernel panic is observed:
[ 4.498085] RIP: 0010:tipc_mon_prep+0x4e/0x130 [tipc] ... [ 4.520030] Call Trace: [ 4.520689] <IRQ> [ 4.521236] tipc_link_build_proto_msg+0x375/0x750 [tipc] [ 4.522654] tipc_link_build_state_msg+0x48/0xc0 [tipc] [ 4.524034] __tipc_node_link_up+0xd7/0x290 [tipc] [ 4.525292] tipc_rcv+0x5da/0x730 [tipc] [ 4.526346] ? __netif_receive_skb_core+0xb7/0xfc0 [ 4.527601] tipc_l2_rcv_msg+0x5e/0x90 [tipc] [ 4.528737] __netif_receive_skb_list_core+0x20b/0x260 [ 4.530068] netif_receive_skb_list_internal+0x1bf/0x2e0 [ 4.531450] ? dev_gro_receive+0x4c2/0x680 [ 4.532512] napi_complete_done+0x6f/0x180 [ 4.533570] virtnet_poll+0x29c/0x42e [virtio_net] ...
The node in question is receiving activate messages in another thread after changing bearer status to allow message sending/ receiving in current thread:
thread 1 | thread 2 -------- | -------- | tipc_enable_bearer() | test_and_set_bit_lock() | tipc_bearer_xmit_skb() | | tipc_l2_rcv_msg() | tipc_rcv() | __tipc_node_link_up() | tipc_link_build_state_msg() | tipc_link_build_proto_msg() | tipc_mon_prep() | { | ... | // null-pointer dereference | u16 gen = mon->dom_gen; | ... | } // Not being executed yet | tipc_mon_create() | { | ... | // allocate | mon = kzalloc(); | ... | } |
Monitoring pointer in thread 2 is dereferenced before monitoring data is allocated in thread 1. This causes kernel panic.
This commit fixes it by allocating the monitoring data before enabling the bearer to receive messages.
Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") Reported-by: Shuang Li shuali@redhat.com Acked-by: Jon Maloy jmaloy@redhat.com Signed-off-by: Tung Nguyen tung.q.nguyen@dektech.com.au Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- net/tipc/bearer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index aabb8084a19c..8879f7923ef5 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -320,16 +320,18 @@ static int tipc_enable_bearer(struct net *net, const char *name, goto rejected; }
- test_and_set_bit_lock(0, &b->up); - rcu_assign_pointer(tn->bearer_list[bearer_id], b); - if (skb) - tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); - + /* Create monitoring data before accepting activate messages */ if (tipc_mon_create(net, bearer_id)) { bearer_disable(net, b); + kfree_skb(skb); return -ENOMEM; }
+ test_and_set_bit_lock(0, &b->up); + rcu_assign_pointer(tn->bearer_list[bearer_id], b); + if (skb) + tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); + pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
return res;
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/10208 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/P...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/10208 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/P...