---
id: CVE-2026-64352
title: 'bpf: Allow LPM map access from sleepable BPF programs'
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  bpf: Allow LPM map access from sleepable BPF programs

  trie_lookup_elem() annotates its rcu_dereference_check() walks with
  only rcu_read_lock_bh_held().  Because rcu_de…
severity: none
vendor: Linux
product: Linux
affected:
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    f0967d4f1ba4323a3cb7dc8fdba74dd3a8caaf04
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    304ca50582f0c047370f85e13caec456f78c9fcc
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    ec662a8b2cde01e76b37ccd4b992d0342299e69c
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    9bfdf4b81b0e56d47bc6c46c34a46638be716695
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    57454944737f3ad9a8703aecbbb79713b513a94b
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    bd6ad9a6b30498d845413e863fb95c6fab3babe3
  - >-
    Linux >= 694cea395fded425008e93cd90cfdf7a451674af <
    2f884d371fafea137afea504d49ee4a7c8d7985b
  - Linux 5.14
ssvc:
  exploitation: none
  automatable: 'no'
  technicalImpact: partial
  timestamp: '2026-11-06T16:36:44.456089Z'
published: '2026-07-25'
updated: '2026-11-06'
sourceUpdated: '2026-11-06T16:44:48.606Z'
source: CVEORG
sourceUrl: 'https://www.cve.org/CVERecord?id=CVE-2026-64352'
references:
  - url: 'https://git.kernel.org/stable/c/f0967d4f1ba4323a3cb7dc8fdba74dd3a8caaf04'
  - url: 'https://git.kernel.org/stable/c/304ca50582f0c047370f85e13caec456f78c9fcc'
  - url: 'https://git.kernel.org/stable/c/ec662a8b2cde01e76b37ccd4b992d0342299e69c'
  - url: 'https://git.kernel.org/stable/c/9bfdf4b81b0e56d47bc6c46c34a46638be716695'
  - url: 'https://git.kernel.org/stable/c/57454944737f3ad9a8703aecbbb79713b513a94b'
  - url: 'https://git.kernel.org/stable/c/bd6ad9a6b30498d845413e863fb95c6fab3babe3'
  - url: 'https://git.kernel.org/stable/c/2f884d371fafea137afea504d49ee4a7c8d7985b'
tags:
  - cve.org
epss: 0.00129
epssPercentile: 0.02574
ingestedAt: '2026-11-06T16:57:43.191Z'
---

## Overview

In the Linux kernel, the following vulnerability has been resolved:

bpf: Allow LPM map access from sleepable BPF programs

trie_lookup_elem() annotates its rcu_dereference_check() walks with
only rcu_read_lock_bh_held().  Because rcu_dereference_check(p, c)
resolves to "c || rcu_read_lock_held()", this passes for XDP/NAPI and
classic RCU readers but fails for sleepable BPF programs, which enter
via __bpf_prog_enter_sleepable() and hold only rcu_read_lock_trace().

trie_update_elem() and trie_delete_elem() have the same problem in a
different form: they walk the trie with plain rcu_dereference(), which
asserts rcu_read_lock_held() unconditionally.  Both are reachable from
sleepable BPF programs via the bpf_map_update_elem / bpf_map_delete_elem
helpers, and from the syscall path under classic rcu_read_lock().  In
the writer paths the trie is actually protected by trie->lock (an
rqspinlock taken across the walk); we never relied on the RCU read-side
lock to keep nodes alive there.

A sleepable LSM hook that ends up touching an LPM trie therefore
triggers lockdep on debug kernels:

  =============================
  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

This is lockdep-only -- no UAF, since Tasks Trace RCU does serialize
against the trie's reclaim path -- but it spams the console once per
distinct callsite on every debug kernel running a sleepable BPF LSM
that touches an LPM trie, which is increasingly common.

For the lookup path, switch the rcu_dereference_check() annotation
from rcu_read_lock_bh_held() to bpf_rcu_lock_held(), which accepts all
three contexts (classic, BH, Tasks Trace).  Other map types already
follow this convention.

For trie_update_elem() and trie_delete_elem(), annotate the walks as
rcu_dereference_protected(*p, 1) -- matching trie_free() in the same
file -- since trie->lock is held across the walk.  rqspinlock has no
lockdep_map, so the predicate degenerates to '1' rather than
lockdep_is_held(&trie->lock); the protection is real but not
machine-verifiable.  trie_get_next_key() also uses bare
rcu_dereference() but is reachable only from the BPF syscall, which
holds classic rcu_read_lock() before dispatching, so it is left
untouched.

## Affected

- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < f0967d4f1ba4323a3cb7dc8fdba74dd3a8caaf04`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < 304ca50582f0c047370f85e13caec456f78c9fcc`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < ec662a8b2cde01e76b37ccd4b992d0342299e69c`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < 9bfdf4b81b0e56d47bc6c46c34a46638be716695`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < 57454944737f3ad9a8703aecbbb79713b513a94b`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < bd6ad9a6b30498d845413e863fb95c6fab3babe3`
- `Linux >= 694cea395fded425008e93cd90cfdf7a451674af < 2f884d371fafea137afea504d49ee4a7c8d7985b`
- `Linux 5.14`

## Remediation

Refer to the linked advisories for vendor-supplied fixes and affected version ranges.
