CVE-2026-64352
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
25/07/2026
Última modificación:
25/07/2026
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
bpf: Allow LPM map access from sleepable BPF programs<br />
<br />
trie_lookup_elem() annotates its rcu_dereference_check() walks with<br />
only rcu_read_lock_bh_held(). Because rcu_dereference_check(p, c)<br />
resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and<br />
classic RCU readers but fails for sleepable BPF programs, which enter<br />
via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace().<br />
<br />
trie_update_elem() and trie_delete_elem() have the same problem in a<br />
different form: they walk the trie with plain rcu_dereference(), which<br />
asserts rcu_read_lock_held() unconditionally. Both are reachable from<br />
sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem<br />
helpers, and from the syscall path under classic rcu_read_lock(). In<br />
the writer paths the trie is actually protected by trie->lock (an<br />
rqspinlock taken across the walk); we never relied on the RCU read-side<br />
lock to keep nodes alive there.<br />
<br />
A sleepable LSM hook that ends up touching an LPM trie therefore<br />
triggers lockdep on debug kernels:<br />
<br />
=============================<br />
WARNING: suspicious RCU usage<br />
7.1.0-... Tainted: G E<br />
-----------------------------<br />
kernel/bpf/lpm_trie.c:249 suspicious rcu_dereference_check() usage!<br />
1 lock held by net_tests/540:<br />
#0: (rcu_tasks_trace_srcu_struct){....}-{0:0},<br />
at: __bpf_prog_enter_sleepable+0x26/0x280<br />
Call Trace:<br />
dump_stack_lvl<br />
lockdep_rcu_suspicious<br />
trie_lookup_elem<br />
bpf_prog_..._enforce_security_socket_connect<br />
bpf_trampoline_...<br />
security_socket_connect<br />
__sys_connect<br />
do_syscall_64<br />
<br />
This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize<br />
against the trie&#39;s reclaim path -- but it spams the console once per<br />
distinct callsite on every debug kernel running a sleepable BPF LSM<br />
that touches an LPM trie, which is increasingly common.<br />
<br />
For the lookup path, switch the rcu_dereference_check() annotation<br />
from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all<br />
three contexts (classic, BH, Tasks Trace). Other map types already<br />
follow this convention.<br />
<br />
For trie_update_elem() and trie_delete_elem(), annotate the walks as<br />
rcu_dereference_protected(*p, 1) -- matching trie_free() in the same<br />
file -- since trie->lock is held across the walk. rqspinlock has no<br />
lockdep_map, so the predicate degenerates to &#39;1&#39; rather than<br />
lockdep_is_held(&trie->lock); the protection is real but not<br />
machine-verifiable. trie_get_next_key() also uses bare<br />
rcu_dereference() but is reachable only from the BPF syscall, which<br />
holds classic rcu_read_lock() before dispatching, so it is left<br />
untouched.
Impacto
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/2f884d371fafea137afea504d49ee4a7c8d7985b
- https://git.kernel.org/stable/c/304ca50582f0c047370f85e13caec456f78c9fcc
- https://git.kernel.org/stable/c/57454944737f3ad9a8703aecbbb79713b513a94b
- https://git.kernel.org/stable/c/9bfdf4b81b0e56d47bc6c46c34a46638be716695
- https://git.kernel.org/stable/c/bd6ad9a6b30498d845413e863fb95c6fab3babe3
- https://git.kernel.org/stable/c/ec662a8b2cde01e76b37ccd4b992d0342299e69c
- https://git.kernel.org/stable/c/f0967d4f1ba4323a3cb7dc8fdba74dd3a8caaf04



