Look up another CVE · open CVE-2026-89746 in the interactive tracker
CVE-2026-89746
tracing: Fix use-after-free with same-name named triggers
Published 2026-09-11 (37 days ago) by the Linux kernel CNA. Subsystem kernel/trace. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2026-89746 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
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | fixedDLA-4841-1 · 2026-10-17 · text | 6.1.190-1 | Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts. |
| Debian 13trixie | fixedDSA-6528-1 · 2026-09-29 · text | 6.12.111-1 | Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian 12bookworm · linux-6.12 | fixedDLA-4817-1 · 2026-10-04 · text | 6.12.111-1~deb12u1 | Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
When two hist triggers on different events are registered with the same name=, the second one reuses the first as named_data. Both are added to tr->hist_vars by save_hist_vars() during event_hist_trigger_parse(), because save_hist_vars() is called before event_trigger_register() while the named reuse is only detected later, in hist_register_trigger(). In the named-data branch hist_register_trigger() then frees the second histogram's hist_data via destroy_hist_data(), but never removes its tr->hist_vars list entry, leaving a dangling pointer and leaking the trace_array reference it holds. A later hist trigger that references a variable makes find_var_file() walk tr->hist_vars and dereference the freed hist_data. The bug is reproducible from userspace by writing three hist triggers to tracefs: cd /sys/kernel/tracing echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_switch/trigger echo 'hist:keys=common_pid:x=common_pid:name=mh' > events/sched/sched_process_fork/trigger echo 'hist:keys=common_pid:vals=$x' > events/sched/sched_process_exit/trigger The third write panics the kernel: BUG: KASAN: slab-use-after-free in find_var_file.part.0+0x272/0x290 Read of size 8 at addr ffff888001f8a0e0 by task sh/1 CPU: 1 UID: 0 PID: 1 Comm: sh Tainted: G D N Call Trace: find_var_file.part.0 find_event_var parse_atom parse_expr __create_val_field event_hist_trigger_parse trigger_process_regex event_trigger_write vfs_write ksys_write do_syscall_64 entry_SYSCALL_64_after_hwframe Allocated by task 1: event_hist_trigger_parse Freed by task 1: hist_register_trigger+0x618/0xa30 event_hist_trigger_parse The buggy address belongs to freed 2048-byte region Oops: general protection fault ... RIP: find_var_file.part.0 Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b Fix by removing the hist_data from tr->hist_vars and releasing the trace_array reference in the named-data branch of hist_register_trigger() before freeing the hist_data.
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/trace/trace_events_hist.c
- What this is
- TRACINGMAINTAINERS section matched on kernel/trace/ · linux-kernel@vger.kernel.org · Maintained
Check it on the machine
grep -wE 'CONFIG_FUNCTION_TRACER|CONFIG_HIST_TRIGGERS|CONFIG_RETHOOK|CONFIG_RING_BUFFER|CONFIG_TRACEPOINTS|CONFIG_TRACE_CLOCK|CONFIG_TRACING' /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.
- bookwormYnot built on arm64/arm64, arm64/cloud-arm64, arm64/rt/arm64, armhf/armmp, armhf/armmp-lpae, armhf/rt/armmp, ppc64el/powerpc64le
- trixieYnot built on arm64/arm64, arm64/arm64-16k, arm64/cloud-arm64, arm64/rt/arm64, armel/rpi, armhf/armmp, armhf/armmp-lpae, armhf/rt/armmp, riscv64/riscv64
- forky, sidYnot built on arm64/arm64, arm64/arm64-16k, arm64/cloud-arm64, arm64/rt-arm64, armhf/armmp, armhf/armmp-lpae, loong64/loong64
- bookworm · linux-6.12Ynot built on arm64/arm64, arm64/arm64-16k, arm64/cloud-arm64, arm64/rt/arm64, armhf/armmp, armhf/armmp-lpae, armhf/rt/armmp
- Y
- built in where it is built at all; some flavours do not build it
- Build switches
- CONFIG_FUNCTION_TRACER, CONFIG_HIST_TRIGGERS, CONFIG_RETHOOK, CONFIG_RING_BUFFER, CONFIG_TRACEPOINTS, CONFIG_TRACE_CLOCK, CONFIG_TRACING
- 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-11 (37 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.16%, higher than 5.2% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- kernel/trace
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 6.1.130 | 6.1.188 | 441aa6742dff |
| 6.6.81 | 6.6.157 | 3a8534664426 |
| 6.12.18 | 6.12.109 | 477d762be4b0 |
| 6.14 | 6.18.50 | b1a49c22de01 |
| 6.14 | 7.2.4 | 83d1ae0406d8 |
| 6.14 | 7.3 | a7318172aa33 |
| 6.13.6 | 0 | 0 |
Debian advisories
| Advisory | Date | Shipped to | Debian |
|---|---|---|---|
| DLA-4841-1 | 2026-10-17 | bookworm 6.1.190-1 | tracker |
| DLA-4817-1 | 2026-10-04 | bookworm 6.12.111-1~deb12u1 | tracker |
| DSA-6528-1 | 2026-09-29 | trixie 6.12.111-1 | tracker |
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 by writing hist trigger commands to tracefs event trigger files via write(2) (event_trigger_write -> event_hist_trigger_parse). There is no network, adjacent-radio, or physical-device path into hist_register_trigger() or find_var_file().
- AC:LAttack complexity, low
- Triggering is fully deterministic: two sequential same-name named hist writes free hist_data while leaving it on tr->hist_vars, and a third vals=$x write walks that dangling pointer. No race or victim state is required, and CONFIG_HIST_TRIGGERS is standard in distro and Android kernels.
- PR:LPrivileges required, low
- The path has no capable() check; event_trigger_open() only enforces LOCKDOWN_TRACEFS and DAC (TRACE_MODE_WRITE 0640). Tracefs is routinely delegated to non-root tracing users (Android/Perfetto, ChromeOS debugd, gid= tracing mounts), matching prior named-hist UAF scores (CVE-2025-21899).
- UI:NUser interaction, none
- The attacker performs all three trigger writes themselves; no victim action, mount, or cooperating process is required.
- S:UScope, unchanged
- The slab use-after-free corrupts kernel heap objects in the tracing subsystem within the same OS security authority and does not cross a VM, IOMMU, or sandbox boundary.
- C:HConfidentiality impact, high
- find_var_file() and find_var_field() dereference the freed 2048-byte hist_trigger_data (event_file, fields[]). After reclaiming that slab, the attacker controls those pointers, and create_var_ref() persists var_field->hist_data for later tracing_map reads, yielding an arbitrary kernel read primitive.
- I:HIntegrity impact, high
- The dangling hist_vars entry plus a sprayed hist_trigger_data lets create_var_ref() store attacker-controlled hist_data/map pointers into the new trigger; event_hist_trigger()/resolve_var_refs() then write tracing_map state through those pointers, a heap write primitive suitable for control-flow hijack.
- A:HAvailability impact, high
- The commit reproduces a KASAN slab-use-after-free in find_var_file() that oopses or panics the kernel (including killing init). Any use-after-free of hist_data is a reliable whole-system crash even without successful exploitation.