Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessLocal unprivileged shell access
-
DeliveryArm per-thread CPU timer then execve
-
ExploitRace SIGKILL during failing exec step
-
ExecutionTrigger use-after-free on freed timer node
-
PersistCorrupt kernel rbtree
-
ImpactEscalate privileges or crash kernel
Vulnerability Assessment
| Exploitation Conditions | Requires local code execution as an unprivileged user able to use timer_create(CLOCK_THREAD_CPUTIME_ID)/timer_settime() and execve(). The bug only manifests when a non-leader thread exec()s AND one of the post-point_of_no_return steps (unshare_files, set_mm_exe_file, exec_mmap, or exec_task_namespaces) fails, AND the task is forced into do_exit() (e.g., via a SIGKILL landing in that window) before begin_new_exec() reaches posix_cpu_timers_exit(). Limiting factors: it is not remotely reachable (AV:L), needs a valid local account (PR:L), and depends on winning a narrow timing race around a failing exec path, so it is not exploitable against default idle systems without attacker-driven conditions. Unaffected are kernels already at the fixed stable releases (e.g., 6.6.158, 6.12.112, 6.18.54, 7.2.8) or where de_thread timing cannot be influenced. |
| Impact | This is a local, memory-corruption (use-after-free) flaw in the Linux kernel's exec()/POSIX CPU-timer cleanup path, not a remotely reachable issue. The provided CVSS 3.1 vector (AV:L/AC:L/PR:L/UI:N, C:H/I:H/A:H, score 7.8) correctly scopes it as local and requiring an authenticated low-privileged user, with high impact consistent with a kernel UAF that can corrupt an rbtree and lead to privilege escalation or denial of service. However, the exploitation-probability signals all point to low real-world priority: EPSS is only 0.18% (6th percentile), the CVE is NOT on the CISA KEV list, and no public exploit code is referenced. Importantly, the CVSS AC:L rating understates reality - the description describes a genuine race condition that requires one of several exec() sub-steps (unshare_files/set_mm_exe_file/exec_mmap/exec_task_namespaces) to fail AND a SIGKILL to land in a narrow window after de_thread() but before do_exit(), which in practice raises attack complexity. No SSVC decision data was provided. Net assessment: a legitimate high-severity kernel bug worth patching in normal cadence, but given low EPSS, no KEV, no POC, and the race-condition timing requirement, it is not an emergency-priority, mass-exploited issue. |
| Exploit ScenarioDerived | A local unprivileged user creates a non-leader thread that arms a per-thread CPU timer (CLOCK_THREAD_CPUTIME_ID), then calls execve() while arranging for a later exec step to fail and for the thread to receive SIGKILL in the race window after de_thread(). The k_itimer is freed while its node is still queued, so when the task is reaped the kernel manipulates a freed rbtree node, yielding a use-after-free that can be leveraged for privilege escalation or a kernel crash. No public proof-of-concept is identified at time of analysis, and the required timing race makes reliable exploitation non-trivial. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 07, 2026
Use-after-free in the Linux kernel's POSIX CPU-timer cleanup path during exec() can corrupt kernel memory and, under the assessed vector (CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H), potentially lead to local privilege escalation or arbitrary code execution in kernel context. The flaw exists in kernels from Linux 5.7 onward and is triggered when a non-leader thread that has armed a CLOCK_THREAD_CPUTIME_ID timer calls execve(), the exec later fails after bprm->point_of_no_return, and the task is forced into do_exit() before begin_new_exec() reaches posix_cpu_timers_exit(), freeing a k_itimer whose node is still queued in an rbtree. Exploitation requires local code execution as an unprivileged user and winning a narrow timing race around a failing exec path, so it is not remotely reachable; EPSS is low (0.18%, 6th percentile) and no public exploit has been identified at time of analysis, while vendor-released patches exist in 6.6.158, 6.12.112, 6.18.54 and 7.2.8.
RemediationAI
Vendor-released patch: upgrade to Linux 6.6.158, 6.12.112, 6.18.54 or 7.2.8 (or 7.3-rc4 or later) - the fix moves the POSIX CPU-timer cleanup to immediately after de_thread(), and the individual stable commits are 75aa08b93c65766040f9ca99f41ac85ad22596b6, 6f1977cea3e85cd8ab55fb337d3e1725fe61d1ce, d602877baf36c43c788a5f472c977e0be414029f, acb03d3881818581052924a9bbbe92b8741ed448 and d9ae467e617ca29b825493a362bf0d75ad5f4ac3, available at https://git.kernel.org/stable/c/75aa08b93c65766040f9ca99f41ac85ad22596b6 and the mirror URLs in the references (see also https://nvd.nist.gov/vuln/detail/CVE-2026-98260). Because the trigger requires a non-leader thread to arm a CLOCK_THREAD_CPUTIME_ID timer and then hit a failing exec() window, the practical compensating controls are to restrict untrusted local execution on unpatched hosts: apply a seccomp profile that denies timer_create()/timer_settime() (or specifically CLOCK_THREAD_CPUTIME_ID) to sandboxed or multi-tenant workloads - the trade-off is that applications relying on per-thread CPU-time accounting, profilers and some runtimes will break or misbehave; alternatively, confine potentially hostile local users to containers/VMs that do not share the host kernel, or defer unprivileged local code execution entirely. Note that forcing or observing the failing-exec plus SIGKILL race is not reliably blocked by generic hardening such as ASLR or KASLR, and no configuration knob disables the vulnerable code path, so patching remains the only complete fix; monitor the listed stable commit URLs for the branch that matches your kernel and validate vendor/distribution advisories, since kernel packages backport patches independently of upstream version strings.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The bug lives in the interaction between Linux's exec() path and the per-thread POSIX CPU-timer machinery. An armed per-thread CPU timer (CLOCK_THREAD_CPUTIME_ID) stores a reference to the PID of the thread it is attached to in timer->it.cpu.pid and keeps its node queued in that task's posix_cputimers timerqueue; the owning task is resolved with pid_task(timer->it.cpu.pid, PIDTYPE_PID). When a non-leader thread calls execve(), de_thread() calls exchange_tids() to transfer the PID to the exec'ing thread, then release_task() on the old leader runs __exit_signal()/posix_cpu_timers_exit(), which cleans the leader's queue but not the exec'ing thread's leftover node, and __unhash_process() removes the task from that PID. From that point pid_task() returns NULL, and timer_lock_sighand() interprets a failed lookup as 'node already dequeued', so posix_cpu_timer_del() performs no removal. Normally begin_new_exec() calls posix_cpu_timers_exit(me) immediately after exec_task_namespaces() and drains the stale node, keeping the state invisible, but bprm->point_of_no_return is set before de_thread(), so a failure in unshare_files(), set_mm_exe_file(), exec_mmap() (e.g., mmap_read_lock_killable() returning -EINTR after SIGKILL) or exec_task_namespaces() sends the task into do_exit(); exit_itimers() → posix_timer_delete() → posix_timer_unhash_and_free() then frees the k_itimer while its node is still linked, and the parent's later wait4() → release_task() → posix_cpu_timers_exit() → cleanup_timerqueue() → timerqueue_del() unlinks the freed node from the rbtree - a classic use-after-free (CWE-416-class memory corruption) in kernel timer/rbtree code. The affected component is the upstream Linux kernel itself (CPE cpe:2.3:a:linux:linux:*:*:*:*:*:*:*:*); the vulnerable code was introduced by commit 55e8c8eb2c7b6bf30e99423ccfe7ca032f498f59 and the fix moves the timer cleanup to immediately after de_thread().
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Local-only kernel bug reachable by an unprivileged user (AV:L/PR:L); the de_thread/SIGKILL timing race makes it AC:H, and the UAF yields full kernel compromise (C/I/A:H).
Primary rating from Vendor (Linux).
CVSS VectorVendor: Linux
Lifecycle Timeline
4DescriptionCVE.org
In the Linux kernel, the following vulnerability has been resolved:
exec: Cleanup POSIX timers right after de_thread()
A per-thread CPU timer holds a reference to the PID of the thread it is attached to and, while it is armed, its node is queued in that thread's posix_cputimers. The task is looked up by that PID.
When a non-leader thread exec()s, de_thread() changes which task owns that PID. pid_task(timer->it.cpu.pid, PIDTYPE_PID) then returns NULL, but the node is still queued on tsk, which is alive. timer_lock_sighand() takes a failed lookup to mean that the node is already dequeued, so it has nothing to undo.
begin_new_exec() calls posix_cpu_timers_exit(me) right after exec_task_namespaces() and that removes the leftover node, so the state normally stays invisible. But bprm->point_of_no_return is set before de_thread(), so if unshare_files(), set_mm_exe_file(), exec_mmap() or exec_task_namespaces() fails, the task dies before it gets there. exit_itimers() then frees the k_itimer while its node is still queued, and reaping tsk later erases that freed node from the rbtree.
In short:
the non-leader thread B the parent
timer_create(CLOCK_THREAD_CPUTIME_ID) timer_settime() arm_timer() // the node is queued on B execve() de_thread(B) exchange_tids(B, leader) // B's PID now belongs to the leader release_task(leader) __exit_signal(leader) posix_cpu_timers_exit(leader) // cleans leader's queue, not B's __unhash_process(leader) // that PID has no task anymore exec_mmap() mmap_read_lock_killable(old_mm) kill(B, SIGKILL) // -EINTR get_signal() do_exit() exit_itimers() posix_timer_delete() posix_cpu_timer_del() posix_timer_unhash_and_free() // freed while still queued wait4() release_task(B) posix_cpu_timers_exit(B) cleanup_timerqueue() timerqueue_del() // use-after-free
Move the POSIX timer cleanup right after de_thread() before any of the later failure conditions brings the task into do_exit().
[ tglx: Move the cleanup right after de_thread() ]
Executive ViewAI
The Linux kernel from version 5.7 onward contains a use-after-free flaw in POSIX CPU-timer cleanup during exec() that can enable a local unprivileged user to escalate to kernel-level privileges or execute arbitrary code in kernel context. This affects Linux servers, cloud instances, containers, and endpoints, where a successful exploit could compromise the host and the data or services it runs. Leadership should prioritize remediation because kernel-level compromise bypasses most application-layer defenses, even though exploitation requires local access, a difficult timing race, and no public exploit identified at time of analysis.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
EUVD-2026-93188
GHSA-pr95-77xq-3v99
NVD
CVE.org
EPSS
Exploit-DB