HIGH Introduced in 2.6.19
reboot CadPid UAF
CVE-2026-97938
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H
01Description
In the Linux kernel, the following vulnerability has been resolved: reboot: fix cad_pid use-after-free race cad_pid is a single kernel-wide struct pid pointer. proc_do_cad_pid() reads it and passes it to pid_vnr() without protecting the lifetime of the referenced struct pid. A concurrent writer can replace cad_pid and drop the final reference to the old struct pid after the reader has loaded the pointer but before pid_vnr() has finished dereferencing it, causing a use-after-free. kill_cad_pid() has the same lifetime race when it passes cad_pid to kill_pid(). At the time this issue was reported, an unprivileged user could reach the sysctl through user and PID namespaces because cad_pid was registered in pid_table[]. Moving cad_pid back to the global reboot sysctl table corrected that namespace and permission mismatch, but did not fix the underlying lifetime race. Fix this by treating cad_pid as an RCU-protected pointer at both read sites and by waiting for a grace period before dropping the old reference on the write side. call_rcu(&old_pid->rcu, ...) cannot be used here because free_pid() also queues pid->rcu; queueing the same rcu_head twice can corrupt the RCU callback list. Original KASAN crash stack: kernel/pid.c:545 pid_nr_ns() # reads freed pid->level kernel/pid.c:556 pid_vnr() # calls pid_nr_ns() kernel/pid.c:775 proc_do_cad_pid() # calls pid_vnr(cad_pid)
02KernelScan AI Analysis
Risk summary
An unprivileged local user can trigger a race condition on the kernel's Ctrl+Alt+Del process ID pointer, causing a use-after-free. The race occurs when a sysctl read happens concurrently with an update to the same global setting. Systems that allow unprivileged local access or host untrusted workloads are at risk. Successful exploitation of the memory corruption could lead to arbitrary kernel read/write and potential container escape.
Vulnerability analysis
The kernel stores the target process for the Ctrl+Alt+Del sequence as a global pointer that can be read and written concurrently without safeguarding the lifetime of the pointed-to object. When one thread updates this setting through a sysctl, it can free the old process ID object while another thread is still reading it, resulting in a use-after-free. The fix protects the pointer so that readers always access a valid object and writers delay freeing the old object until all concurrent readers have finished. At the time the issue was originally reported, an unprivileged local user could reach the sysctl through user and PID namespaces; the sysctl has since been moved back to the global table, correcting that exposure, but the underlying race remained.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 6.12 | 2.6.19 | 6.12.112 | ae3e53fe3c12 |
| 6.18 | 2.6.19 | 6.18.53 | ad72e2566643 |
| 7.2 | 2.6.19 | 7.2.7 | 9a17b0e05319 |
| mainline | 2.6.19 | 7.3-rc3 | 5a88f78df753 |