CVE-2025-22035 Overview
CVE-2025-22035 is a use-after-free vulnerability [CWE-416] in the Linux kernel's ftrace subsystem. The flaw resides in print_graph_function_flags() and is triggered when a user switches the active tracer while another process is concurrently reading the trace file. Switching from the function_graph tracer to another tracer such as timerlat frees iter->private via graph_trace_close() without setting the pointer to NULL. A subsequent call path through event->funcs->trace() then dereferences the stale pointer.
Critical Impact
A local user with access to the tracing interface can trigger memory corruption in kernel space, potentially leading to privilege escalation, kernel crash, or arbitrary code execution.
Affected Products
- Linux Kernel (multiple stable branches prior to the fix commits)
- Debian distributions referenced in DLA advisories msg00030 and msg00045
- Downstream distributions packaging vulnerable kernel versions
Discovery Timeline
- 2025-04-16 - CVE-2025-22035 published to NVD
- 2025-11-03 - Last updated in NVD database
Technical Details for CVE-2025-22035
Vulnerability Analysis
The vulnerability is a use-after-free condition in the kernel tracing subsystem. During each s_show() call, print_trace_line() invokes print_graph_function_flags() through two paths: directly via iter->trace->print_line() and indirectly via event->funcs->trace() inside print_trace_fmt(). When a user switches tracers mid-read, only the first path is updated to reflect the new tracer. The second path retains a reference to the previous tracer's print function.
When the previous tracer was function_graph, s_start() calls graph_trace_close() to release iter->private. The pointer itself is never cleared. Subsequent reads then pass the dangling pointer to event->funcs->trace(), producing the use-after-free.
Root Cause
The root cause is a missing pointer invalidation in graph_trace_close(). The function frees memory allocated to iter->private but does not assign NULL to the pointer after release. Combined with stale function pointers cached through the event subsystem during tracer switching, this leaves a window where freed memory is dereferenced by code path that was not synchronized with the tracer change.
Attack Vector
Exploitation requires local access and the ability to write to current_tracer and read from trace under tracefs or debugfs. These interfaces typically require CAP_SYS_ADMIN or root, but they may be exposed to lower-privileged contexts in misconfigured containers or systems with relaxed tracing permissions. The reporter reproduced the issue by enabling function_graph, beginning a cat trace read, then switching to timerlat during the read window. A local attacker who controls execution timing can convert the freed allocation into a controlled object and achieve kernel memory corruption.
No public proof-of-concept exploit has been released, and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog.
Detection Methods for CVE-2025-22035
Indicators of Compromise
- Unexpected kernel oops or panic messages referencing print_graph_function_flags, print_trace_line, or print_trace_fmt in dmesg or /var/log/kern.log
- KASAN reports flagging use-after-free in the ftrace code path when kernel address sanitizer is enabled
- Non-root or container processes writing to /sys/kernel/tracing/current_tracer or /sys/kernel/debug/tracing/current_tracer
Detection Strategies
- Audit access to tracefs and debugfs mount points and alert on unprivileged writes to current_tracer
- Enable kernel hardening features such as KASAN in test environments to surface the use-after-free during regression testing
- Correlate kernel crash dumps with concurrent reads of the trace file and tracer-switch events
Monitoring Recommendations
- Monitor process execution that touches /sys/kernel/tracing/ or /sys/kernel/debug/tracing/ paths and flag non-administrative users
- Track kernel version inventory across the fleet to confirm patched builds are deployed
- Forward kernel ring buffer events to a centralized logging platform for retroactive analysis of crash patterns
How to Mitigate CVE-2025-22035
Immediate Actions Required
- Apply the upstream kernel patches referenced in the stable tree commits, including 099ef33, 42561fe, 70be951, 7f81f27, 81a85b1, a2cce54, c85efe6, de7b309, and f14752d
- Update Debian systems using the fixed packages announced in Debian LTS msg00030 and Debian LTS msg00045
- Restrict access to tracefs and debugfs to trusted administrators only
Patch Information
The fix sets iter->private to NULL immediately after freeing it in graph_trace_close(), preventing other tracers from dereferencing the released allocation. The patch also removes redundant iter->private = NULL assignments from the wakeup and irqsoff tracers. Refer to the upstream commit 099ef33 and the additional backport commits in the Linux stable tree.
Workarounds
- Unmount or restrict tracefs and debugfs where kernel tracing is not required for production workloads
- Set restrictive permissions on /sys/kernel/tracing/current_tracer so that only privileged administrators can change the active tracer
- Disable container access to host tracing interfaces by removing CAP_SYS_ADMIN and masking /sys/kernel/debug in container runtimes
# Configuration example: restrict tracefs access to root only
mount -o remount,mode=0700 /sys/kernel/tracing
chmod 0600 /sys/kernel/tracing/current_tracer
chmod 0600 /sys/kernel/tracing/trace
# Verify the running kernel includes the fix
uname -r
dpkg -l | grep linux-image # Debian/Ubuntu
rpm -qa | grep kernel # RHEL/Fedora
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


