From: Chen Zhongjin <chenzhong...@huawei.com>

When IPv6 module gets initialized but hits an error in the middle,
kenel panic with:

KASAN: null-ptr-deref in range [0x0000000000000598-0x000000000000059f]
CPU: 1 PID: 361 Comm: insmod
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
RIP: 0010:__neigh_ifdown.isra.0+0x24b/0x370
RSP: 0018:ffff888012677908 EFLAGS: 00000202
...
Call Trace:
 <TASK>
 neigh_table_clear+0x94/0x2d0
 ndisc_cleanup+0x27/0x40 [ipv6]
 inet6_init+0x21c/0x2cb [ipv6]
 do_one_initcall+0xd3/0x4d0
 do_init_module+0x1ae/0x670
...
Kernel panic - not syncing: Fatal exception

When ipv6 initialization fails, it will try to cleanup and calls:

neigh_table_clear()
  neigh_ifdown(tbl, NULL)
    pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev == NULL))
    # dev_net(NULL) triggers null-ptr-deref.

Fix it by passing NULL to pneigh_queue_purge() in neigh_ifdown() if dev
is NULL, to make kernel not panic immediately.

Fixes: 66ba215cb513 ("neigh: fix possible DoS due to net iface start/stop loop")
Signed-off-by: Chen Zhongjin <chenzhong...@huawei.com>
Reviewed-by: Eric Dumazet <eduma...@google.com>
Reviewed-by: Denis V. Lunev <d...@openvz.org>
Link: https://lore.kernel.org/r/20221101121552.21890-1-chenzhong...@huawei.com
Signed-off-by: Jakub Kicinski <k...@kernel.org>
(cherry picked from commit f8017317cb0b279b8ab98b0f3901a2e0ac880dad)
https://virtuozzo.atlassian.net/browse/PSBM-153018
https://bugs.openvz.org/browse/OVZ-7410
Signed-off-by: Alexander Atanasov <alexander.atana...@virtuozzo.com>
---
 net/core/neighbour.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


v1->v2: fixed wrong merge
v2->v3: backported one more patch - which is not in the vz7 tree but is in 
mainstream,
so it looked like two patches are made into one. Both touch the same code to 
increase
the confusion.


diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d5b28c158144..ae6490f8d3ae 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -321,7 +321,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device 
*dev)
        neigh_flush_dev(tbl, dev);
        pneigh_ifdown(tbl, dev);
        write_unlock_bh(&tbl->lock);
-       pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev));
+       pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
        if (skb_queue_empty(&tbl->proxy_queue))
                del_timer_sync(&tbl->proxy_timer);
        return 0;
-- 
2.39.3

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to