Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-64560-Analysis — Linux kernel UAF analysis for CVE-2026-64560 with race-triggering PoC, patch review, affected LTS/Android version matrix, and self-check for patched devices. | Kitploit
Tools/GitHubGitHub/villager1314/cve-2026-64560-analysis
Android SecurityVulnerability AnalysisExploitationMobile SecurityLearning & EducationBinary Exploitation
GitHubvillager1314/cve-2026-64560-analysis

CVE-2026-64560-Analysis

Linux kernel UAF analysis for CVE-2026-64560 with race-triggering PoC, patch review, affected LTS/Android version matrix, and self-check for patched devices.

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
11451 month agoReviewed by Kitploit

CVE-2026-64560 — Linux Kernel posix-cpu-timers non-leader exec() race UAF

Reproducer / PoC (trigger verification) : Linux & Android (NDK) This repository is intended solely for verifying patch status and for research/learning on your own test devices. It does not contain any privilege escalation/exploitation primitive.

CVSS 3.1 CVSS 4.0 (SUSE) CWE-416 Fix


1. Vulnerability Overview

FieldDetails
CVE IDCVE-2026-64560
Titleposix-cpu-timers: Prevent UAF caused by non-leader exec() race
TypeUse-After-Free (CWE-416), race condition
CNAkernel.org (Linux CNA)
CVSS v3.17.8 High — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0 (SUSE)8.5 High — CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
EPSS~0.12% (2nd percentile, as of 2026-08)
CISA KEVNot listed
Public disclosure date2026-07-29
Fix commit (mainline)920f893f735e92ba3a1cd9256899a186b161928d
Introduced-by commit (Fixes:)55e8c8eb2c7b (v5.7, 2020) — "posix-cpu-timers: Store a reference to a pid not a task"
Fixed byThomas Gleixner <[email protected]>
Reported byWongi Lee <[email protected]>, Jungwoo Lee <[email protected]>
Affected fileskernel/exit.c, kernel/signal.c, kernel/time/posix-cpu-timers.c

Affected Versions

The vulnerability was introduced in v5.7 (2020-05), and the fix has been backported to the following stable branches:

BranchAffectedFixed version (≥)Stable fix commit
5.10 LTS5.7 ~ 5.10.2615.10.26267aa823e3e8c
5.15 LTS~ 5.15.2125.15.213d8bcb28abad8
6.1 LTS~ 6.1.1796.1.180cc35ddbc4973
6.6 LTS~ 6.6.1466.6.14712a891c773ae
6.12 LTS~ 6.12.996.12.100e74443f5db00
6.18~ 6.18.406.18.416a7ecc25abe6
7.1~ 7.1.47.1.5ad1cafa1bdaa
mainline< 7.2-rc37.2-rc3920f893f735e

Android Relevance

Android GKI kernels are based on 5.10 / 5.15 / 6.1 / 6.6 / 6.12 LTS, all of which are affected. Since the mainline fix commit was published on 2026-07-29, Android devices with an SPL (Security Patch Level) of 2026-08-01 or earlier have almost certainly not incorporated this fix. On the device, confirm the kernel version and SPL with adb shell cat /proc/version and getprop ro.build.version.security_patch.


2. Technical Details

2.1 Background: posix CPU timers and sighand

POSIX CPU timers (timer_create(CLOCK_PROCESS_CPUTIME_ID, ...) / timer_create(CLOCK_THREAD_CPUTIME_ID, ...)) are managed in the kernel by kernel/time/posix-cpu-timers.c. Each k_itimer remembers its target task via it.cpu.pid; timer operations require lock_task_sighand(p, &flags) to acquire that task's sighand->siglock in order to protect the timerqueue.

The 2020 commit 55e8c8eb2c7b replaced the task pointer cached in timers with a pid reference (to fix a problem introduced by the 2010 workaround e0a70217107e), performing a pid_task(pid, type) lookup before each operation. This change left the race window behind this CVE.

2.2 Race scenario (non-leader thread exec)

When execve() is issued by a non-leader thread, de_thread() → switch_leader() moves the TGID from the old leader to the new leader; the old leader then goes through release_task() → __exit_signal(), which sets old_leader->sighand = NULL and calls unhash_task(old_leader).

At the same time, sys_timer_delete() → posix_cpu_timer_del() executes on another CPU:

 sys_timer_delete()                        exec()
   posix_cpu_timer_del()
   // 观察到旧 leader
   p = pid_task(pid, pid_type);            de_thread()
                                             switch_leader();
                                             release_task(old_leader)
                                               __exit_signal(old_leader)
                                                 sighand = lock(old_leader, sighand);
                                                 posix_cpu_timers*_exit();
   sighand = lock_task_sighand(p)            unhash_task(old_leader);
     sh = lock(p, sighand)                   old_leader->sighand = NULL;
                                               unlock(sighand);
     (p->sighand == NULL)
       unlock(sh)
       return NULL;

   // 直接返回,没有摘链!
   if (!sighand)
      return 0;
   free_posix_timer();   // ← k_itimer 被释放

The p found by posix_cpu_timer_del() is the old leader. At this point p->sighand == NULL, so the function assumes "the task is exiting, and the exit path will take care of unlinking", and therefore does nothing and returns success. Afterwards, free_posix_timer() frees the k_itimer.

Key point: exec() differs from exit() — during exec(), the TGID does not change, so armed timers attached at the process level (p->signal->cpu_timers) are inherited and remain queued. As a result:

  • run_posix_cpu_timers() (walks the timerqueue on each tick) accesses the freed object's timerqueue_node → UAF read/write;
  • add/delete operations on other timers likewise traverse this rbtree containing a dangling node → UAF.

Similar issues also exist in:

  • posix_cpu_timer_set(): for ordinary timers it only returns -ESRCH temporarily; however, the kernel-internal do_cpu_nanosleep() uses a stack-allocated k_itimer, which is the same UAF.
  • posix_cpu_timer_rearm(): silent rearm failure; the timer never expires again (functional bug).

2.3 Secondary issue on weakly-ordered architectures

Frederic Weisbecker pointed out that tsk->sighand = NULL in __exit_signal() is a plain store. On weakly-ordered architectures such as ARM64, when posix_cpu_timer_del() observes sighand == NULL, it is not guaranteed to observe the unlink writes that happened before posix_cpu_timers*_exit(), which can cause WARN_ON_ONCE(timer_queued(tmr)) to spuriously fire.

2.4 Fix approach

  1. Change __exit_signal() to use smp_store_release(&tsk->sighand, NULL);
  2. Add smp_acquire__after_ctrl_dep() to the !sighand path of lock_task_sighand();
  3. Add a new helper timer_lock_sighand(): it looks up the task and locks the sighand. If sighand == NULL, it does not return but retries the lookup — in the exec scenario it finds the new leader, and in the exit scenario it gives up only when the lookup fails;
  4. Switch all three affected functions (_del / _set / _rearm) to use this helper.

See patches/920f893f735e.patch for the full diff.


3. PoC Description (trigger verification, not a privilege escalation exploit)

Under poc/ there is a race trigger: two threads each loop at high intensity

  • Thread A (timer thread): repeatedly timer_create(CLOCK_PROCESS_CPUTIME_ID) → arm (very short initial expiration time) → busy-wait for expiration → timer_delete();
  • Thread B (exec thread): repeatedly fork() → in the child process, create a non-leader thread that calls execve() (non-leader exec is a necessary condition for this vulnerability); the parent immediately reaps it with waitpid().
Download Tool