A 16-year-old timing gap in the kernel's stopwatch lets any local user rewrite memory the kernel already freed
CVE-2026-64560 is a use-after-free in the Linux kernel's POSIX CPU timer subsystem, present since kernel 5.7 (and partially masked since ~2010). When a non-leader thread calls exec() while sys_timer_delete() is running concurrently, the old thread-group leader's task struct can be freed while sys_timer_delete() still holds a stale pointer. Subsequent run_posix_cpu_timers() or timerqueue add/delete operations then walk a dangling timerqueue_node, giving an attacker a kernel-heap UAF primitive — read, write, and control-flow hijack. The bug was independently discovered by Wongi Lee and Jungwoo Lee. Affected versions span 5.7 through mainline, and fixes landed in six LTS branches (5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41) plus 7.1.5 and 7.2-rc3.
The vendor score of 7.8 HIGH is fair and we leave it essentially unchanged. The AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H vector accurately captures the threat: any unprivileged local user on a multi-threaded system can trigger the race with CPU pinning, and the impact is full CIA compromise of the host kernel. There is no remote vector and no evidence of in-the-wild exploitation yet, which prevents an upgrade to CRITICAL — but the kernel is the ultimate high-value component on every Linux host, so friction alone cannot pull this below HIGH.
5 steps from start to impact.
Obtain local unprivileged shell
PR:L is sufficient.- Local access to target Linux host
- Kernel version 5.7+ and < fixed LTS release
- Requires prior foothold — this is a post-access primitive, not initial access
- Container runtimes with seccomp profiles may block
timer_create/timer_deletesyscalls
Create multi-threaded process with POSIX CPU timer
CLOCK_PROCESS_CPUTIME_ID POSIX timer via timer_create(). The timer is armed so that run_posix_cpu_timers() will traverse the timerqueue. This is entirely userspace-controlled and requires no elevated privileges.- Ability to call
timer_create()andclone()syscalls
- Seccomp profiles in hardened containers (e.g., Docker default) allow
timer_createbut custom profiles may not - gVisor/kata containers intercept these syscalls entirely
Trigger non-leader exec() racing with timer_delete()
execve() while the main thread simultaneously calls timer_delete(). The attacker uses CPU pinning (sched_setaffinity) to control scheduling and maximize the race window. When the race hits, de_thread() + switch_leader() frees the old leader's task struct while sys_timer_delete() still references it, leaving a dangling timerqueue_node.- Multi-CPU system (race is trivial to win with CPU pinning)
- Attacker controls timing of both threads
- Single-vCPU VMs make the race harder (but not impossible)
- KASAN-enabled debug kernels will detect and halt the corruption
CONFIG_KASAN=y) detects the UAF at trigger time; audit rules on timer_delete syscall can flag unusual volumeExploit UAF for kernel heap corruption
msgsnd, sendmsg, or add_key). When the kernel next walks the timerqueue via run_posix_cpu_timers(), it reads/writes attacker-controlled data, enabling arbitrary kernel read/write or RIP control.- Heap spray capability (standard for any local user)
- Knowledge of slab allocator layout for target kernel build
- SLAB_VIRTUAL /
CONFIG_SLAB_FREELIST_HARDENEDreduces spray reliability - KASLR adds ~9 bits of entropy the attacker must leak or brute-force
- CFI (
CONFIG_CFI_CLANG) blocks control-flow hijack via corrupted function pointers
dmesg/journalctl; EDR agents monitoring for privilege changes on Linux (e.g., Crowdstrike Falcon for Linux, SentinelOne) may catch the post-exploitation pivotAchieve local privilege escalation to root
cred structures or modprobe_path to escalate to UID 0. From root on a bare-metal host or VM, the attacker owns the entire machine. On a KVM hypervisor or Kubernetes node, this becomes a host-level compromise affecting all tenants/containers.- Successful heap corruption from step 4
- SELinux/AppArmor in enforcing mode constrains what root can do post-escalation
- Lockdown LSM (
integrityorconfidentialitymode) blocks many kernel-write-to-root techniques
setuid(0) from non-root parent; Falco rules for unexpected privilege escalation in containersThe supporting signals.
| In-the-Wild Exploitation | No confirmed in-the-wild exploitation as of 2026-08-07. Not listed on CISA KEV. |
|---|---|
| Proof of Concept | No public PoC specific to CVE-2026-64560. A related POSIX timer UAF PoC exists for CVE-2025-38352 (researcher *Faraz Sth*, targeting 32-bit Android), demonstrating the class is exploitable. The race mechanics are well-understood and reproducible. |
| EPSS Score | 0.0012 (~12th percentile) — very low predicted exploitation probability in the next 30 days |
| KEV Status | Not listed |
| CVSS Vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — local access, low complexity (attacker controls both race sides), low privilege, no user interaction, full CIA impact, scope unchanged |
| Affected Versions | Linux kernel 5.7 through all branches prior to fix commits. Essentially every supported LTS and mainline release shipped between ~2020 and July 2026. |
| Fixed Versions | 5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41, 7.1.5, 7.2-rc3. Distro backports: check RHEL, Ubuntu, SUSE, Debian errata for kernel updates released ≥2026-07-29. |
| Scanning/Exposure | Not remotely exploitable — no Shodan/GreyNoise/Censys exposure surface. Vulnerability assessment is version-check only (e.g., Qualys QID, Nessus plugin for kernel version). |
| Disclosure Date | 2026-07-29 (coordinated via linux-cve-announce, patches in stable trees same day) |
| Researchers | Wongi Lee and Jungwoo Lee (independent co-discovery). Fix authored by Thomas Gleixner (four-part patch series). |
noisgate verdict.
The vendor's HIGH/7.8 is directionally correct and we hold the severity bucket at HIGH with a minor score trim to 7.4. The single most decisive factor is the role multiplier: the Linux kernel is the affected component, and on hypervisors, container hosts, and database servers (≥10% of the installed base by definition), a local-to-root chain ends in fleet-scale or data-tier compromise — setting a hard floor at HIGH that friction cannot breach.
Why this verdict
- Local-only attack vector — requires a pre-existing foothold (SSH, container shell, compromised service). This is a post-access primitive, not an initial-access vector, which applies moderate downward pressure from the 7.8 baseline.
- Low complexity, low privilege — the attacker controls both sides of the race via CPU pinning and needs only an unprivileged account. No exotic conditions required. This resists further downgrade.
- Role multiplier: kernel = universal high-value target — the Linux kernel runs on every Linux host. On KVM hypervisors, Kubernetes worker nodes, and CI/CD runners (collectively ≥10% of Linux installs), local-to-root means host compromise → fleet-scale blast radius. The chain succeeds in these roles (no additional prerequisites beyond local shell), setting a hard floor at HIGH.
- No in-the-wild exploitation or KEV listing — EPSS at 0.0012 and no public weaponized PoC for this specific CVE prevent an upgrade to CRITICAL.
- Broad affected window — kernels from 5.7 (2020) through July 2026 are vulnerable, meaning most enterprise fleets have vulnerable hosts unless they track stable branches closely.
Why not higher?
No confirmed in-the-wild exploitation, no CISA KEV listing, and EPSS is at the 12th percentile. The attack is local-only with no remote vector, meaning it cannot serve as initial access. A related POSIX timer PoC exists but no weaponized exploit for this specific CVE has been published. Without active exploitation evidence or a remote chain, CRITICAL is not justified.
Why not lower?
The Linux kernel is the canonical high-value-role component — it IS the hypervisor (KVM), the container host, the database tier OS. Local-to-root on these systems is fleet-compromise-scale. The race is described as low-complexity with attacker-controlled timing, and the 6-year affected window means broad exposure across enterprise fleets. Friction (local access requirement) sets the score within HIGH but cannot breach the HIGH floor given the role multiplier.
What to do — in priority order.
- Apply kernel updates from your distro's security errata immediately — The upstream fix landed 2026-07-29 across all LTS branches. RHEL, Ubuntu, SUSE, and Debian have or will backport. This is the only complete remediation. Per noisgate HIGH remediation SLA, patch within 180 days; aim for 30 days given the breadth of the affected window.
- Restrict POSIX timer syscalls via seccomp on containerized workloads — Add
timer_create,timer_delete, andtimer_settimeto your seccomp deny-list for containers that don't need POSIX timers. This blocks the trigger entirely in container-escape scenarios. Deploy within 30 days per noisgate mitigation SLA. - Enable KASAN on staging/canary kernels —
CONFIG_KASAN=ydetects the UAF at trigger time and halts execution before exploitation completes. Not suitable for production performance workloads but useful for detecting exploitation attempts in pre-prod or canary rings. - Enforce SELinux/AppArmor in enforcing mode on high-value hosts — Even if the attacker achieves root via this UAF, mandatory access controls constrain lateral movement and data access. Ensure hypervisors, container hosts, and database servers run enforcing profiles. Deploy within 30 days.
- Audit and limit local shell access on tier-0 infrastructure — The attack requires a local unprivileged shell. Reduce the population of users with interactive access to hypervisors, Kubernetes nodes, and database hosts. Use jump boxes with MFA and session recording.
- Network firewalls/WAFs — this is a local-only kernel vulnerability with no network attack surface. Perimeter controls are irrelevant.
- KASLR alone — provides ~9 bits of entropy but is routinely bypassed via information leaks in local LPE chains. It slows but does not stop a motivated attacker.
- Container isolation (namespaces/cgroups) without seccomp — the vulnerable syscalls are allowed by default Docker/containerd seccomp profiles. Namespace isolation does not prevent kernel-level UAF exploitation.
Crowdsourced verification payload.
Run this script on each target Linux host as any user (no root required). It checks the running kernel version against known-fixed versions. Invoke with: bash check_cve_2026_64560.sh
#!/usr/bin/env bash
# check_cve_2026_64560.sh — Detect CVE-2026-64560 (POSIX CPU timer UAF)
# Run on target host, no privileges required.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
KERNEL=$(uname -r)
echo "[*] Running kernel: $KERNEL"
# Extract major.minor.patch
BASE=$(echo "$KERNEL" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')
MAJOR=$(echo "$BASE" | cut -d. -f1)
MINOR=$(echo "$BASE" | cut -d. -f2)
PATCH=$(echo "$BASE" | cut -d. -f3)
if [ -z "$MAJOR" ] || [ -z "$MINOR" ] || [ -z "$PATCH" ]; then
echo "UNKNOWN — could not parse kernel version"
exit 2
fi
# Fixed versions per branch:
# 5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41, 7.1.5, 7.2+
# Affected: 5.7 <= kernel < fixed
vulnerable() { echo "VULNERABLE — kernel $KERNEL is affected by CVE-2026-64560"; exit 1; }
patched() { echo "PATCHED — kernel $KERNEL includes the fix"; exit 0; }
# Kernels before 5.7 are not affected
if [ "$MAJOR" -lt 5 ]; then patched; fi
if [ "$MAJOR" -eq 5 ] && [ "$MINOR" -lt 7 ]; then patched; fi
# 7.2+ is patched (fix in 7.2-rc3)
if [ "$MAJOR" -gt 7 ]; then patched; fi
if [ "$MAJOR" -eq 7 ] && [ "$MINOR" -ge 2 ]; then patched; fi
# Branch checks
if [ "$MAJOR" -eq 5 ]; then
if [ "$MINOR" -ge 7 ] && [ "$MINOR" -lt 10 ]; then
# 5.7-5.9: no LTS fix backported to these EOL branches
vulnerable
elif [ "$MINOR" -eq 10 ]; then
[ "$PATCH" -ge 262 ] && patched || vulnerable
elif [ "$MINOR" -gt 10 ] && [ "$MINOR" -lt 15 ]; then
vulnerable
elif [ "$MINOR" -eq 15 ]; then
[ "$PATCH" -ge 213 ] && patched || vulnerable
else
vulnerable
fi
elif [ "$MAJOR" -eq 6 ]; then
if [ "$MINOR" -lt 1 ]; then
vulnerable
elif [ "$MINOR" -eq 1 ]; then
[ "$PATCH" -ge 180 ] && patched || vulnerable
elif [ "$MINOR" -gt 1 ] && [ "$MINOR" -lt 6 ]; then
vulnerable
elif [ "$MINOR" -eq 6 ]; then
[ "$PATCH" -ge 147 ] && patched || vulnerable
elif [ "$MINOR" -gt 6 ] && [ "$MINOR" -lt 12 ]; then
vulnerable
elif [ "$MINOR" -eq 12 ]; then
[ "$PATCH" -ge 100 ] && patched || vulnerable
elif [ "$MINOR" -gt 12 ] && [ "$MINOR" -lt 18 ]; then
vulnerable
elif [ "$MINOR" -eq 18 ]; then
[ "$PATCH" -ge 41 ] && patched || vulnerable
else
patched
fi
elif [ "$MAJOR" -eq 7 ]; then
if [ "$MINOR" -eq 0 ]; then
vulnerable
elif [ "$MINOR" -eq 1 ]; then
[ "$PATCH" -ge 5 ] && patched || vulnerable
fi
fi
echo "UNKNOWN — kernel version $KERNEL did not match any known branch"
exit 2If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.