CVE-2022-48719 in Linux
Summary
by MITRE • 06/20/2024
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]
__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
Once again VulDB remains the best source for vulnerability data.
Analysis
by VulDB Data Team • 09/18/2024
The vulnerability CVE-2022-48719 addresses a critical deadlock condition within the Linux kernel's networking subsystem, specifically in the neighbor management mechanism. This issue manifests when handling neighbor entries that transition to the NUD_FAILED state, triggering an immediate probe operation that conflicts with existing lock acquisition patterns. The problem was identified through syzkaller testing, which revealed a scenario where the kernel worker thread attempting to create a neighbor entry became trapped in a deadlock situation. The system was unable to acquire the necessary table lock because it was already holding it, creating a circular dependency that halted system operations.
The technical flaw stems from the neighbor management code's behavior when processing failed neighbor entries. When a neighbor entry enters the NUD_FAILED state, the __neigh_event_send function triggers an immediate probe through neigh_probe, which requires the table lock that is already held by the neigh_managed_work function. This creates a classic deadlock scenario where the same lock is attempted to be acquired twice within the same execution context. The root cause can be traced back to commit cd28ca0a3dd1, which introduced a change to reduce ARP latency by enabling immediate probing, but this optimization proved problematic in managed neighbor entry contexts where the lock acquisition pattern is more complex.
The operational impact of this vulnerability extends beyond simple system hangs, potentially affecting network connectivity and system stability in environments with active neighbor management operations. The fix implements a targeted approach by adding a parameter to __neigh_event_send() that controls whether immediate probing is permitted, allowing the neigh_managed_work() function to disable immediate probing when dealing with managed entries. This solution aligns with the principle of avoiding immediate operations in contexts where lock contention is likely, and it maintains backward compatibility for non-managed entries that require the latency-reduction behavior. The approach follows established patterns from pre-commit cd28ca0a3dd1, where such deferral was the standard practice for managed entries, ensuring that only actual failure states trigger immediate probes while regular operations proceed without interference.
Security implications of this vulnerability are significant as it could be exploited to cause denial of service conditions through network disruption, particularly in systems where neighbor management is actively utilized. The fix represents a defensive programming approach that prevents lock contention scenarios while preserving the intended functionality of neighbor management. From an ATT&CK perspective, this vulnerability could be leveraged in privilege escalation or availability attacks, though the specific threat model would depend on the system configuration and network usage patterns. The solution adheres to CWE guidelines for avoiding deadlock conditions in concurrent programming, specifically addressing CWE-362 which deals with concurrent execution using locks and race conditions. The mitigation strategy ensures that managed neighbor entries follow a safer execution path while maintaining performance characteristics for regular neighbor operations, demonstrating a balanced approach to security and system efficiency.