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 2a7ee696f7b0"(tipc: add reference counter to bearer") 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);