CVE-2026-99234
NoneCVSS
—
EPSS
0.2%
Published
Nov 2, 2026
CISA due date
—
Cloudanix analysis
A bug in Linux's built-in tracing system can let a carefully written monitoring command leave behind a broken internal record that may crash the whole machine.
- Exploitation
- Local Privilege
- Attacker needs
- Local User
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- OS kernel
- Class
- Use After Free
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The flaw leaves a registered histogram trigger active after its tracking structure in field_var_hists[] is freed during error handling in event_hist_trigger_parse(), resulting in a use-after-free when the orphaned trigger is later accessed or destroyed.
Why it matters to the business
Systems relying on advanced Linux tracing may experience kernel instability or crashes; because the issue was published only one day ago with no known exploitation, immediate operational risk remains low but requires prompt tracking of kernel updates.
How an attack unfolds
An attacker with write access to tracing triggers issues a multi-part hist command that registers an auxiliary field-variable histogram on one event, then fails on a later synthetic-event reference; the error path frees the tracking entry without unregistering the trigger, leaving a dangling structure that can be dereferenced to trigger use-after-free.
How to fix it
Apply the upstream kernel patch that calls unregister_field_var_hists() from the out_free error path and records each field_var_hist immediately upon registration; rebuild and deploy the fixed kernel on all affected systems.
How to confirm the fix worked
Inspect the tracing/histogram source for the presence of unregister_field_var_hists() in the error-exit path and confirm that field_var_hists[] entries are recorded before any subsequent lookup that could fail.
Typical attack path
- echo a hist command registering ts0 into sched_waking/trigger
- create a synthetic event
- echo a failing hist command referencing a nonexistent field into sched_switch/trigger
- access or destroy the orphaned trigger to trigger the use-after-free
How to detect it
Review dmesg and kernel logs for warnings or oopses involving hist triggers or field_var_hists; examine /sys/kernel/debug/tracing/events/*/trigger contents for orphaned active histograms that lack corresponding tracking entries.
What your security team should do
- Track and schedule deployment of the next stable kernel release containing the fix
- Limit unprivileged write access to /sys/kernel/debug/tracing/events/*/trigger where feasible
- Monitor upstream stable and distribution kernel advisories for backported fixes
The record
In the Linux kernel, the following vulnerability has been resolved: tracing: Unregister field variable histograms when the command fails An action that names a field on another event needs that field as a variable, so create_field_var_hist() registers a second hist trigger on that event to provide it, and records it in target_hist_data->field_var_hists[]. If a later part of the same command fails, create_actions() returns an error and event_hist_trigger_parse() jumps to out_free. The write fails with -EINVAL and sched_switch gets no trigger, but: # echo 'hist:keys=pid:ts0=common_timestamp.usecs' >> \ events/sched/sched_waking/trigger # echo 'my_synth u64 lat; int a; int b' >> synthetic_events # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0:\ onmatch(sched.sched_waking).my_synth($wakeup_lat,prio,nosuchfld)'\ >> events/sched/sched_switch/trigger # cat events/sched/sched_waking/trigger hist:keys=pid:vals=hitcount:ts0=common_timestamp.usecs:sort=hitcount:size=2048:clock=global [active] hist:keys=pid:vals=hitcount:synthetic_prio=prio:sort=hitcount:size=2048 [active] The second histogram is the one created for 'prio'. It is still active and still counting. out_free reaches destroy_field_var_hists(), which frees the field_var_hists[] entries, but never unregister_field_var_hists(), which is what removes the triggers and runs only from event_hist_trigger_free(). The entry is freed and the trigger is left with nothing tracking it. Unregister the field variable histograms in out_free as well, and record each one as soon as its trigger is registered rather than after the lookup that follows it, so no exit can leave a registered trigger untracked. The entry then belongs to field_var_hists[] and is released by destroy_field_var_hists(), so freeing it on that exit would be a double free.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|