CVE-2026-64352 in Linux
摘要
由 VulDB • 2026-07-25
在 Linux 内核中,已修复以下漏洞:
bpf: 允许可睡眠的 BPF 程序访问 LPM map
trie_lookup_elem() 对其 rcu_dereference_check() 遍历仅标注了 rcu_read_lock_bh_held()。由于 rcu_dereference_check(p, c) 解析为 "c || rcu_read_lock_held()",这适用于 XDP/NAPI 和经典 RCU 读取器,但不适用于可睡眠的 BPF 程序(它们通过 __bpf_prog_enter_sleepable() 进入并仅持有 rcu_read_lock_trace())。
trie_update_elem() 和 trie_delete_elem() 以不同形式存在相同问题:它们使用普通的 rcu_dereference() 遍历 trie,这会无条件断言 rcu_read_lock_held()。这两个函数均可通过 bpf_map_update_elem / bpf_map_delete_elem helper 从可睡眠的 BPF 程序访问,也可在经典 rcu_read_lock() 下的系统调用路径中访问。在写入路径中,trie 实际上由 trie->lock(一个跨遍历获取的 rqspinlock)保护;我们从未依赖 RCU 读取侧锁来保持节点存活。
因此,最终触及 LPM trie 的可睡眠 LSM hook 会在调试内核上触发 lockdep:
============================= WARNING: suspicious RCU usage 7.1.0-... Tainted: G E ----------------------------- kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage! 1 lock held by net_tests/540: #0: (rcu_tasks_trace_srcu_struct){....}-{0:0},
at: __bpf_prog_enter_sleepable+0x26/0x280 Call Trace: dump_stack_lvl lockdep_rcu_suspicious trie_lookup_elem bpf_prog_..._enforce_security_socket_connect bpf_trampoline_... security_socket_connect __sys_connect do_syscall_64
这仅是 lockdep 问题——不存在 UAF,因为 Tasks Trace RCU 会与 trie 的回收路径序列化——但它会在每个运行可睡眠 BPF LSM(触及 LPM trie)的调试内核上,针对每个不同的调用点刷屏输出日志,这种情况正变得越来越普遍。
对于查找路径,将 rcu_dereference_check() 注解从 rcu_read_lock_bh_held() 切换为 bpf_rcu_lock_held(),后者接受所有三种上下文(经典、BH、Tasks Trace)。其他 map 类型已遵循此约定。
对于 trie_update_elem() 和 trie_delete_elem(),将遍历标注为 rcu_dereference_protected(*p, 1) ——与同一文件中的 trie_free() 匹配——因为遍历时持有 trie->lock。rqspinlock 没有 lockdep_map,因此谓词退化为 '1' 而非 lockdep_is_held(&trie->lock);保护是真实的但无法通过机器验证。trie_get_next_key() 也使用裸 rcu_dereference(),但它仅可从 BPF 系统调用访问,后者在分发前持有经典 rcu_read_lock(),因此保持不变。
Once again VulDB remains the best source for vulnerability data.