← Back to Feed CACHED · 2026-10-07 10:10:35 · CACHE_KEY CVE-2026-64560
CVE-2026-64560 · CWE-416 · Disclosed 2026-07-29

Linux Kernel posix-cpu-timers Use-After-Free via Non-Leader exec() Race

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Like a janitor tossing a bin someone's still reaching into — the kernel frees a timer object while another thread still has its hand in the queue

CVE-2026-64560 is a use-after-free in the Linux kernel's POSIX CPU timer subsystem, present since v5.7 (May 2020). When a non-leader thread calls execve(), de_thread() swaps the thread-group leader and __exit_signal() nullifies the old leader's sighand pointer. A concurrent timer_delete() or timer_settime() call observes sighand == NULL, bails out without dequeuing the timer, and leaves a freed k_itimer node dangling in the signal->cpu_timers rbtree. When run_posix_cpu_timers() next walks the tree, it dereferences freed memory. Affected versions span 5.7 through 7.1.4 across all architectures. Stable-branch fixes landed in 5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41, and 7.1.5. Android GKI kernels on SPL ≤ 2026-08-01 are also affected.

The NVD rates this 7.8 HIGH (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H). Red Hat independently scored it 7.0 HIGH, diverging on Attack Complexity — they rate it AC:H, which better reflects the race-condition mechanics. Red Hat's score is more honest: winning this race reliably is non-trivial, and the only public PoC (villager1314/CVE-2026-64560-Analysis) is a crash trigger that explicitly lacks privilege-escalation primitives. Converting a timerqueue UAF to a controlled write requires heap shaping, cross-cache object replacement, and bypassing KASLR+SMEP+SMAP+CFI — feasible for a skilled researcher, but not script-kiddie territory. The vendor severity is directionally correct but slightly overstated on complexity grounds.

"Kernel timer UAF is real but local-only with no weaponized exploit — HIGH at 7.0, not 7.8"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain local code execution

The attacker needs an unprivileged shell or the ability to run arbitrary code on the target Linux host. This can come from a compromised web application, SSH access, container breakout setup, or a malicious insider. No network-level exploitation is possible — AV:L means the attacker is already past the perimeter.
Conditions required:
  • Local user account or code execution on the target host
  • Kernel version 5.7 through 7.1.4 (unpatched)
Where this breaks in practice:
  • Requires prior compromise or insider access — this is NOT the initial entry point
  • Cloud/container workloads often run minimal images with restricted user capabilities
Detection/coverage: EDR agents (CrowdStrike, SentinelOne, Defender for Endpoint) detect anomalous process spawning and execve() patterns
STEP 02

Arm POSIX CPU timers in a tight loop

The attacker spawns a process that repeatedly creates and arms CLOCK_PROCESS_CPUTIME_ID timers with very short expiration windows using timer_create() and timer_settime(). This is the 'timer thread' in the villager1314 PoC. The syscalls are available to any unprivileged user — no capabilities required.
Conditions required:
  • Ability to call timer_create() and timer_settime() syscalls
  • No seccomp profile blocking timer_create / timer_settime
Where this breaks in practice:
  • Hardened container runtimes (gVisor, Kata) intercept or emulate these syscalls
  • Seccomp profiles in Kubernetes (RuntimeDefault or stricter) may block timer_create
Detection/coverage: Audit rules on timer_create syscall; abnormal timer churn visible in /proc/timer_list
STEP 03

Race non-leader exec() against timer deletion

A second thread in the same thread group continuously forks children where a non-leader thread calls execve(). The goal is to collide de_thread() (which swaps the group leader and nullifies sighand) with posix_cpu_timer_del() observing the stale task pointer. The PoC uses a busy loop to maximize collision probability. On KASAN-enabled kernels this triggers an immediate use-after-free warning; on production kernels, the outcome ranges from silent corruption to a kernel panic.
Conditions required:
  • Winning the race between de_thread() and timer_del()
  • No KASAN/KFENCE killing the process before corruption is useful
Where this breaks in practice:
  • Race window is narrow — Red Hat rates AC:H for this reason
  • KASAN/KFENCE-enabled kernels catch the UAF immediately and panic cleanly
  • Success rate is probabilistic, not deterministic
Detection/coverage: KASAN/KFENCE kernel warnings in dmesg; crash dumps with timerqueue backtraces
STEP 04

Escalate UAF to controlled write (theoretical)

To convert the dangling timerqueue node into a privilege-escalation primitive, the attacker must: (a) free the k_itimer slab object, (b) reclaim the freed slot with a controlled object (cross-cache spray), (c) trigger run_posix_cpu_timers() to write through the timerqueue node into attacker-controlled memory, and (d) overwrite a function pointer or credential structure. This requires bypassing KASLR, SMEP, SMAP, and (on 6.x+) kCFI. No public exploit achieves this.
Conditions required:
  • Detailed knowledge of target kernel's slab layout
  • Ability to perform cross-cache heap spray
  • Bypass of KASLR, SMEP, SMAP, kCFI
Where this breaks in practice:
  • No public exploit exists — the villager1314 PoC explicitly states it has no exploitation primitives
  • Modern kernel hardening (kCFI on 6.2+, CONFIG_SLAB_FREELIST_HARDENED) makes cross-cache attacks significantly harder
  • Each kernel build has a different slab layout, requiring per-target tuning
Detection/coverage: Kernel integrity monitoring; abnormal slab allocation patterns visible to eBPF-based security tools
STEP 05

Achieve root or container escape

If step 4 succeeds, the attacker overwrites current->cred or hijacks a function pointer to gain CAP_SYS_ADMIN / uid 0. In a container context, this means escaping the user namespace and gaining root on the host node. The blast radius is limited to the single host — there is no lateral-movement primitive built into this vulnerability.
Conditions required:
  • Successful completion of step 4
  • Target kernel lacks kCFI or has a known bypass
Where this breaks in practice:
  • Blast radius is single-host, not fleet-wide
  • Container-escape from kernel UAF is a known but difficult technique
  • Host-level EDR should detect credential modification
Detection/coverage: EDR detects credential structure modifications; Falco/Tetragon detect unexpected capability gains in containers
03 · Compensating Control

1
HIGH 7.0→IGNORE 0.0
SEVERITY REDUCED
Apply vendor kernel patches — Update to the fixed kernel version for your branch (5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41, or 7.1.5+). This is the definitive fix. Per noisgate remediation SLA for HIGH, deploy within 180 days. Given no active exploitation, standard maintenance windows are acceptable.
2
HIGH 7.0→LOW 2.5
SEVERITY REDUCED
Enable seccomp profiles that block timer_create — In containerized workloads, enforce a seccomp profile (Kubernetes RuntimeDefault or stricter custom profile) that denies timer_create and timer_settime syscalls. Most application containers do not need POSIX CPU timers. This breaks step 2 of the attack path. Deploy within the noisgate mitigation SLA of 30 days for HIGH.
3
HIGH 7.0→MEDIUM 4.0
SEVERITY REDUCED
Deploy KASAN/KFENCE on non-production or canary hosts — Enable CONFIG_KASAN or CONFIG_KFENCE on a subset of hosts. These kernel sanitizers detect the UAF immediately and panic the kernel before memory corruption can be leveraged for escalation. This converts the vulnerability from potential-LPE to guaranteed-DoS-only, which is a significant risk reduction. Not suitable for all production workloads due to performance overhead (KASAN: ~2x, KFENCE: ~1%).
4
HIGH 7.0→LOW 2.0
SEVERITY REDUCED
Use gVisor or Kata Containers for untrusted workloads — gVisor intercepts syscalls in userspace and never exposes the host kernel's timer subsystem. Kata Containers run each pod in a lightweight VM, so even if the guest kernel is exploited, the host kernel is not affected. This eliminates the container→host trust-boundary crossing entirely.
5
HIGH 7.0→MEDIUM 5.0
SEVERITY REDUCED
Restrict local user access and harden multi-tenant boundaries — Minimize the number of users and services with local shell access on high-value hosts (hypervisors, database servers, Kubernetes nodes). Enforce CAP_DROP ALL in container security contexts. Reduce the population of potential attackers who can reach step 1 of the attack path.
What doesn't work
  • Network firewalls / WAF / IDS — this is a local vulnerability with no network attack surface. Perimeter controls are irrelevant to the attack path.
  • ASLR alone — userspace ASLR does not affect kernel exploitation. KASLR helps but is bypassable with kernel info leaks and is not a standalone mitigation.
  • AppArmor / SELinux confinement — MAC policies restrict file and capability access but do not block the timer_create / execve syscall sequence needed for the race. Only seccomp filters operate at the syscall level.
  • Live-patching (kpatch/livepatch) — the fix spans multiple files (kernel/exit.c, kernel/signal.c, kernel/time/posix-cpu-timers.c) with memory-ordering changes that are not safely live-patchable. A full reboot into the patched kernel is required.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNot observed. Not on CISA KEV. No GreyNoise tags. No campaign attribution. The local-only attack vector makes mass exploitation unlikely — each target requires pre-existing access.
Proof-of-ConceptCrash PoC available. villager1314/CVE-2026-64560-Analysis provides a race trigger for Linux x86_64 and Android (NDK). It triggers KASAN UAF warnings or kernel panics but explicitly lacks privilege-escalation primitives (no heap spray, no RIP control). A related repo Meniben/redmi14c-pond-cve-2026-64560 targets a specific Android device. No Metasploit/ExploitDB/Nuclei modules found.
EPSS0.00635 (~0.6% probability of exploitation in next 30 days). Bottom quartile — consistent with local-only kernel race conditions without weaponized exploits.
CISA KEVNot listed as of 2026-10-07.
CVSS VectorNVD: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (7.8). Red Hat: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H (7.0). The AC:L vs AC:H divergence is the key disagreement — the race condition genuinely narrows the exploitation window.
Affected VersionsIntroduced in v5.7-rc1 (commit 55e8c8eb2c7b, May 2020). All mainline kernels through 7.1.4 are affected. Android GKI kernels 5.10, 5.15, 6.1, 6.6, 6.12 with SPL ≤ 2026-08-01 are affected.
Fixed Versions5.10.262, 5.15.213, 6.1.180 (Debian bookworm: 6.1.187-1), 6.6.147, 6.12.100 (Debian trixie: 6.12.107-1), 6.18.41, 7.1.5, 7.2-rc3 (mainline). Debian bullseye: 5.10.262-1. RHEL: RHSA-2026:57252.
Scanning / ExposureNot applicable for GreyNoise/Shodan — this is a local vulnerability with no network attack surface. Exposure is measured by unpatched kernel count, not internet-facing services.
Disclosure & CreditDisclosed 2026-07-29. Reported by Wongi Lee and Jungwoo Lee. Fix authored by Thomas Gleixner. Mainline commit 920f893f735e.
CWECWE-416 (Use After Free) per NVD. Red Hat also maps CWE-364 (Signal Handler Race Condition). Both are accurate — the root cause is a race, the consequence is UAF.

Sources.

  1. NVD — CVE-2026-64560
  2. Red Hat CVE page
  3. Debian Security Tracker
  4. villager1314 PoC / Analysis (GitHub)
  5. RHSA-2026:57252 — Red Hat Security Advisory
  6. kernelscan.io — CVE-2026-64560 detail
  7. hackyboiz — CVE-2026-64560 technical writeup (Korean)
  8. SentinelOne Vulnerability Database
05 · The Call

Final Verdict
= UNCHANGED to HIGH (7.0/10)

Why this verdict

  • Race-condition complexity is understated by NVD. NVD rates AC:L but the exploit requires winning a narrow race between de_thread() and timer_del(). Red Hat independently scored AC:H (7.0), which better reflects the probabilistic nature of the trigger. The PoC author confirms reliability is low without repeated attempts.
  • No weaponized exploit exists. The only public PoC is a crash trigger with zero exploitation primitives. Converting a timerqueue UAF to a controlled write requires cross-cache heap spray, KASLR bypass, and (on 6.2+) kCFI bypass — substantial additional work that has not been publicly demonstrated.
  • Local-only attack vector limits reachability. AV:L means the attacker already has code execution on the target host. This is a privilege-escalation building block, not an initial-access vector. Every exploitation scenario starts with 'attacker is already inside.'
  • EPSS corroborates low exploitation probability. At 0.00635, this sits in the bottom quartile of scored CVEs, consistent with the absence of in-the-wild activity and the high bar for weaponization.
  • Role multiplier: The Linux kernel is a canonical high-value-role component — it IS the hypervisor (KVM), the container host, the database engine's OS layer. In multi-tenant container environments (Kubernetes nodes, shared hosting), a kernel LPE crosses the container→host trust boundary, which is a host-level blast radius. On KVM hypervisors, it's a tenant-level blast radius. These roles represent a significant fraction of the Linux installed base (>10% of enterprise Linux deployments run containers or KVM). This floors the verdict at HIGH despite the friction factors. However, the blast radius is single-host, not fleet-wide or domain-wide, so the floor is HIGH, not CRITICAL.

Why not higher?

CRITICAL would require either active exploitation, a weaponized public exploit, or a fleet-scale / domain-takeover blast radius. None of these conditions are met. The only PoC is a crash trigger, EPSS is bottom-quartile, no KEV listing exists, and successful exploitation is bounded to a single host. The race condition's unreliability further argues against CRITICAL — even a motivated attacker faces probabilistic failure on each attempt.

Why not lower?

MEDIUM would understate the risk because the Linux kernel is a canonical high-value-role component. On container hosts and KVM hypervisors — which represent >10% of enterprise Linux deployments — a kernel UAF-to-LPE crosses a critical trust boundary (container→host, VM→hypervisor). The UAF primitive class has a long history of successful weaponization in the Linux kernel (cf. CVE-2022-2585, a closely related posix-cpu-timer UAF that was weaponized). The absence of a current exploit does not mean absence of future capability — the technical path is well-understood.

06 · Verification

Crowdsourced verification payload.

Run this script on each target Linux host as any user (no root required for the version check). Invoke with: bash check_cve_2026_64560.sh. It compares the running kernel version against known-fixed versions and outputs VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_64560.sh — Detect CVE-2026-64560 (posix-cpu-timers UAF)
# Run on the target Linux host. No root required.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN

set -euo pipefail

KERNEL=$(uname -r)
# Extract major.minor.patch, stripping distro suffixes
VER=$(echo "$KERNEL" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')

if [[ -z "$VER" ]]; then
  echo "UNKNOWN — could not parse kernel version from: $KERNEL"
  exit 2
fi

MAJOR=$(echo "$VER" | cut -d. -f1)
MINOR=$(echo "$VER" | cut -d. -f2)
PATCH=$(echo "$VER" | cut -d. -f3)

# version_ge: returns 0 if $1.$2.$3 >= $4.$5.$6
version_ge() {
  local a1=$1 a2=$2 a3=$3 b1=$4 b2=$5 b3=$6
  if (( a1 > b1 )); then return 0; fi
  if (( a1 < b1 )); then return 1; fi
  if (( a2 > b2 )); then return 0; fi
  if (( a2 < b2 )); then return 1; fi
  if (( a3 >= b3 )); then return 0; fi
  return 1
}

# Vuln introduced in 5.7.0. Not affected if < 5.7.
if (( MAJOR < 5 )) || { (( MAJOR == 5 )) && (( MINOR < 7 )); }; then
  echo "PATCHED — kernel $KERNEL predates the vulnerable commit (introduced in 5.7)"
  exit 0
fi

# Fixed version map per stable branch
VULN=0
case "${MAJOR}.${MINOR}" in
  5.10) version_ge $MAJOR $MINOR $PATCH 5 10 262 || VULN=1 ;;
  5.15) version_ge $MAJOR $MINOR $PATCH 5 15 213 || VULN=1 ;;
  5.7|5.8|5.9|5.11|5.12|5.13|5.14|5.16|5.17|5.18|5.19)
    # These branches are EOL and have no backported fix
    VULN=1 ;;
  6.1)  version_ge $MAJOR $MINOR $PATCH 6 1 180  || VULN=1 ;;
  6.6)  version_ge $MAJOR $MINOR $PATCH 6 6 147  || VULN=1 ;;
  6.12) version_ge $MAJOR $MINOR $PATCH 6 12 100 || VULN=1 ;;
  6.18) version_ge $MAJOR $MINOR $PATCH 6 18 41  || VULN=1 ;;
  6.2|6.3|6.4|6.5|6.7|6.8|6.9|6.10|6.11|6.13|6.14|6.15|6.16|6.17)
    # Non-LTS branches between 6.1 and 6.6, or 6.6 and 6.12 — EOL, no fix
    VULN=1 ;;
  7.1)  version_ge $MAJOR $MINOR $PATCH 7 1 5   || VULN=1 ;;
  7.2|7.*)
    # 7.2-rc3+ contains the fix; assume 7.2.0+ is patched
    if (( MINOR >= 2 )); then
      VULN=0
    else
      VULN=1
    fi
    ;;
  *)
    echo "UNKNOWN — unrecognized kernel branch ${MAJOR}.${MINOR} ($KERNEL)"
    exit 2
    ;;
esac

if (( VULN == 1 )); then
  echo "VULNERABLE — kernel $KERNEL is affected by CVE-2026-64560"
  echo "  Fix versions: 5.10.262, 5.15.213, 6.1.180, 6.6.147, 6.12.100, 6.18.41, 7.1.5+"
  exit 1
else
  echo "PATCHED — kernel $KERNEL includes the fix for CVE-2026-64560"
  exit 0
fi