data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2026-90210 in the interactive tracker

CVE-2026-90210

bpf: Fix UAF in bpf_trampoline_multi_attach_free on update failure

7.8 EPSS 0.2% AV:L

Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem kernel/bpf. Debian urgency: unimportant.

What to do, per Debian release

Debian's own status for CVE-2026-90210 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormnot affected6.1.190-1Nothing to do. bookworm never shipped the vulnerable code.
Debian 13trixienot affected6.12.113-1Nothing to do. trixie never shipped the vulnerable code.
Debian 14forkynot affected7.2.11-1Nothing to do. forky never shipped the vulnerable code.
Debian unstablesidnot affected7.2.11-1Nothing to do. sid never shipped the vulnerable code.

The vulnerability

What the bug is

When bpf_trampoline_update() fails before modify_fentry_multi()/ unregister_fentry_multi() is called, cur_image is unchanged (cur_image == old_image) and ftrace still calls into it. Freeing old_image in that case causes a UAF. Only free old_image when it differs from cur_image.

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

kernel/bpf/trampoline.c

What this is
BPF [CORE]MAINTAINERS section matched on kernel/bpf/trampoline.c · bpf@vger.kernel.org · Maintained

Check it on the machine

grep -wE 'CONFIG_BPF|CONFIG_BPF_JIT' /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

Show whether Debian builds this, per release

Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.

  • bookwormy
  • trixie, forky, sidYnot built on s390x/s390x
y
built into the kernel image on every flavour - only a patch removes it
Y
built in where it is built at all; some flavours do not build it
Build switches
CONFIG_BPF, CONFIG_BPF_JIT
Reads as
all on means the file is compiled; any one off means it is not.

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2026-09-17 (31 days ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.17%, higher than 5.4% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
unimportantsource
Subsystem
kernel/bpf

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
7.27.2.665c3939656fd
7.27.30253073fb7d7

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
The UAF is reached only via the local bpf() syscall: BPF_PROG_LOAD of BPF_PROG_TYPE_TRACING with BPF_TRACE_FENTRY_MULTI/FEXIT_MULTI/FSESSION_MULTI, BPF_LINK_CREATE into bpf_tracing_multi_attach(), then close() of that link fd which runs bpf_tracing_multi_link_release() -> bpf_trampoline_multi_detach() -> bpf_trampoline_multi_attach_free().
AC:LAttack complexity, low
The attacker attaches a second fentry program on the same ftrace-managed function so detach rebuilds the trampoline, then closes the multi-link fd. bpf_trampoline_multi_detach() WARN_ON_ONCE-ignores bpf_trampoline_update() failure before modify_fentry_multi() and still calls bpf_trampoline_multi_attach_free(); ENOMEM from bpf_tramp_image_alloc() or arch_prepare_bpf_trampoline() is inducible by exhausting bpf_prog_pack from that process.
PR:LPrivileges required, low
bpf_prog_load() requires bpf_token_capable(CAP_BPF) and bpf_token_capable(CAP_PERFMON) for BPF_PROG_TYPE_TRACING. bpf_token_capable() calls ns_capable() on a delegated BPF token's user namespace, so a container user with a token (or a non-root tracing daemon holding only those two caps) can load and attach fentry.multi without host root.
UI:NUser interaction, none
The attacker loads the tracing programs, creates the tracing-multi link with BPF_LINK_CREATE, and closes their own link fd to hit bpf_trampoline_multi_attach_free(); no other user must mount, open a file, or otherwise act.
S:UScope, unchanged
The UAF of bpf_tramp_image and its JIT text, and any resulting kernel control-flow hijack, remain inside the host kernel; this is a standard kernel privilege-escalation defect, not a VM escape or IOMMU/guest boundary crossing.
C:HConfidentiality impact, high
On the failing detach path bpf_trampoline_multi_attach_free() calls bpf_tramp_image_put() while ftrace still direct-calls that image (old_image == cur_image). After the RCU tasks-trace GP, bpf_prog_pack_free() returns those pages; reclaiming them exposes kernel/JIT contents and yields an arbitrary-read primitive.
I:HIntegrity impact, high
ftrace keeps a direct call into the trampoline that bpf_tramp_image_put() is freeing. Reclaiming the bpf_prog_pack pages with attacker-controlled BPF JIT text makes the next call of the traced function jump to chosen kernel instructions, i.e. control-flow hijack and arbitrary write.
A:HAvailability impact, high
After bpf_tramp_image_put() of a trampoline that ftrace still invokes, the next entry to the attached kernel function jumps into freed executable memory and oopses/panics. Closing the multi-link fd retriggers this at will.