| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2022-48719: net, neigh: Do not trigger immediate probes on NUD_FAILED from neigh_managed_work |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| net, neigh: Do not trigger immediate probes on NUD_FAILED from neigh_managed_work |
| |
| syzkaller was able to trigger a deadlock for NTF_MANAGED entries [0]: |
| |
| kworker/0:16/14617 is trying to acquire lock: |
| ffffffff8d4dd370 (&tbl->lock){++-.}-{2:2}, at: ___neigh_create+0x9e1/0x2990 net/core/neighbour.c:652 |
| [...] |
| but task is already holding lock: |
| ffffffff8d4dd370 (&tbl->lock){++-.}-{2:2}, at: neigh_managed_work+0x35/0x250 net/core/neighbour.c:1572 |
| |
| The neighbor entry turned to NUD_FAILED state, where __neigh_event_send() |
| triggered an immediate probe as per commit cd28ca0a3dd1 ("neigh: reduce |
| arp latency") via neigh_probe() given table lock was held. |
| |
| One option to fix this situation is to defer the neigh_probe() back to |
| the neigh_timer_handler() similarly as pre cd28ca0a3dd1. For the case |
| of NTF_MANAGED, this deferral is acceptable given this only happens on |
| actual failure state and regular / expected state is NUD_VALID with the |
| entry already present. |
| |
| The fix adds a parameter to __neigh_event_send() in order to communicate |
| whether immediate probe is allowed or disallowed. Existing call-sites |
| of neigh_event_send() default as-is to immediate probe. However, the |
| neigh_managed_work() disables it via use of neigh_event_send_probe(). |
| |
| [0] <TASK> |
| __dump_stack lib/dump_stack.c:88 [inline] |
| dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 |
| print_deadlock_bug kernel/locking/lockdep.c:2956 [inline] |
| check_deadlock kernel/locking/lockdep.c:2999 [inline] |
| validate_chain kernel/locking/lockdep.c:3788 [inline] |
| __lock_acquire.cold+0x149/0x3ab kernel/locking/lockdep.c:5027 |
| lock_acquire kernel/locking/lockdep.c:5639 [inline] |
| lock_acquire+0x1ab/0x510 kernel/locking/lockdep.c:5604 |
| __raw_write_lock_bh include/linux/rwlock_api_smp.h:202 [inline] |
| _raw_write_lock_bh+0x2f/0x40 kernel/locking/spinlock.c:334 |
| ___neigh_create+0x9e1/0x2990 net/core/neighbour.c:652 |
| ip6_finish_output2+0x1070/0x14f0 net/ipv6/ip6_output.c:123 |
| __ip6_finish_output net/ipv6/ip6_output.c:191 [inline] |
| __ip6_finish_output+0x61e/0xe90 net/ipv6/ip6_output.c:170 |
| ip6_finish_output+0x32/0x200 net/ipv6/ip6_output.c:201 |
| NF_HOOK_COND include/linux/netfilter.h:296 [inline] |
| ip6_output+0x1e4/0x530 net/ipv6/ip6_output.c:224 |
| dst_output include/net/dst.h:451 [inline] |
| NF_HOOK include/linux/netfilter.h:307 [inline] |
| ndisc_send_skb+0xa99/0x17f0 net/ipv6/ndisc.c:508 |
| ndisc_send_ns+0x3a9/0x840 net/ipv6/ndisc.c:650 |
| ndisc_solicit+0x2cd/0x4f0 net/ipv6/ndisc.c:742 |
| neigh_probe+0xc2/0x110 net/core/neighbour.c:1040 |
| __neigh_event_send+0x37d/0x1570 net/core/neighbour.c:1201 |
| neigh_event_send include/net/neighbour.h:470 [inline] |
| neigh_managed_work+0x162/0x250 net/core/neighbour.c:1574 |
| process_one_work+0x9ac/0x1650 kernel/workqueue.c:2307 |
| worker_thread+0x657/0x1110 kernel/workqueue.c:2454 |
| kthread+0x2e9/0x3a0 kernel/kthread.c:377 |
| ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 |
| </TASK> |
| |
| The Linux kernel CVE team has assigned CVE-2022-48719 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 5.16 with commit 7482e3841d520a368426ac196720601687e2dc47 and fixed in 5.16.8 with commit 203a35ebb49cdce377416b0690215d3ce090d364 |
| Issue introduced in 5.16 with commit 7482e3841d520a368426ac196720601687e2dc47 and fixed in 5.17 with commit 4a81f6da9cb2d1ef911131a6fd8bd15cb61fc772 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2022-48719 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| include/net/neighbour.h |
| net/core/neighbour.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/203a35ebb49cdce377416b0690215d3ce090d364 |
| https://git.kernel.org/stable/c/4a81f6da9cb2d1ef911131a6fd8bd15cb61fc772 |