Skip to content
WatchlistHigh

CVE-2026-64560linux Vulnerability

Linux kernel: posix-cpu-timers: Prevent UAF caused by non-leader exec() race

Published Jul 29, 2026 · Updated Oct 16, 2026 · Also known as DEBIAN-CVE-2026-64560, ROOT-OS-DEBIAN-12-CVE-2026-64560, UBUNTU-CVE-2026-64560

Key Facts

Patch in the next maintenance window
  • CVE-2026-64560 is a high-severity vulnerability (CVSS 7.8 v3.1) affecting linux-6.12 (debian), linux-6.1 (debian), linux (debian) and 22 more products.
  • It is not listed in any known-exploited vulnerabilities catalog. No public exploit code is known.
  • EPSS estimates a 0.7% probability of exploitation in the next 30 days.
  • Fixed versions are available, including bpftool 1:6.1.180-225.360.amzn2023, bpftool 5.15.0-324.217.5.2.el8uek, bpftool 5.15.0-324.217.5.2.el9uek.
  • Brandefense priority: patch in the next maintenance window, because of its high severity, although no exploitation is known.

Scores

CVSS v3.1

7.8

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

EPSS (30-day exploit likelihood)

0.7%

Higher than 50.2% of all scored CVEs

Exploit maturity

Proof of concept

ATLAS score

50/100

Publication score, see How it works

Exploitation Verdict

KEV listed

Not listed

Federal due date

None

No federal due date

Ransomware use

Not reported

Attributed actors

None named

Exploit & Defence Guidance

Exploit maturity

Proof of concept

Public exploit code

10

Proof-of-concept links

In-the-wild evidence

0

Reports of active use

Description

In the Linux kernel, the following vulnerability has been resolved:

posix-cpu-timers: Prevent UAF caused by non-leader exec() race

Wongi and Jungwoo decoded and reported a non-leader exec() related race which can result in an UAF:

sys_timer_delete() exec() posix_cpu_timer_del() // Observes old 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;

// Returns without action if(!sighand) return 0; free_posix_timer();

This is "harmless" unless the deleted timer was armed and enqueued in p->signal because on exec() a TGID targeted timer is inherited.

As sys_timer_delete() freed the underlying posix timer object run_posix_cpu_timers() or any timerqueue related add/delete operations on other timers will access the freed object's timerqueue node, which results in an UAF.

There is a similar problem vs. posix_cpu_timer_set(). For regular posix timers it just transiently returns -ESRCH to user space, but for the use case in do_cpu_nanosleep() it's the same UAF just that the k_itimer is allocated on the stack.

Also posix_cpu_timer_rearm() fails to rearm the timer, which means it stops to expire.

While debating solutions Frederic pointed out another problem:

posix_cpu_timer_del(tmr) exit_signal(p) posix_cpu_timers*_exit(p); unhash_task(p); p->sighand = NULL; sh = lock_task_sighand(p) sighand = p->sighand; if (!sighand) return NULL; lock(sighand);

if (!sh) WARN_ON_ONCE(timer_queued(tmr));

On weakly ordered architectures it is not guaranteed that posix_cpu_timer_del() will observe the stores in posix_cpu_timers*_exit() when p->sighand is observed as NULL, which means the WARN() can be a false positive.

Solve these issues by:

1) Changing the store in exit_signal() to smp_store_release().

2) Adding a smp_acquireafter_ctrl_dep() into the !sighand path of lock_task_sighand().

3) Creating a helper function for looking up the task and locking sighand which does not return when sighand == NULL. Instead it retries the task lookup and only if that fails it gives up.

4) Using that helper in the three affected functions. 1/#2 ensures that the reader side which observes sighand == NULL also observes all preceeding stores, i.e. the stores in posix_cpu_timers*_exit() and the ones in unhash_task(). 3 ensures that the above described non-leader exec() situation is handled gracefully.

When the task lookup returns the old leader, but sighand == NULL then it retries. In the non-leader exec() case the subsequent task lookup will observe the new leader due to #1/#2. In normal exit() scenarios the subsequent lookup fails.

When the task lookup fails, the function also checks whether the timer is still enqueued and issues a warning if that's the case. Unfortunately there is nothing which can be done about it, but as the task is already not longer visible the timer should not be accessed anymore. This check also requires memory ordering, which is not provided when the first lookup fails.

To achieve that the check is preceeded by a smp_rmb() which pairs with the smp_wmb() in write_seqlock() in exit_signal(). That ensures that the stores in posix_cpu_timers*_exit() are visible.

The history of the non-leader exec() issue goes back to the early days of posix CPU timers, which stored a pointer to the group leader task in the timer. That obviously fails when a non-leader exec() switches the leader. commit e0a70217107e ("posix-cpu-timers: workaround to suppress the problems with mt exec") added a temporary workaround for that in 2010 which surv ---truncated---

Affected Products

2,674 affected entries in total
ProductAffected versionsFixed in
linux-6.12debianSee advisory6.12.100-1~deb12u1
linux-6.1debianSee advisory6.1.180-1~deb11u1
linuxdebianSee advisory6.1.180-1
bpftoolubuntuSee advisory7.7.0+7.0.0-38.38
linux-allwinner-5.19ubuntuSee advisoryn/a
20 more affected products in the full CVE brief

Patched Releases

bpftool

1:6.1.180-225.360.amzn2023, 5.15.0-324.217.5.2.el8uek, 5.15.0-324.217.5.2.el9uek, 6.12.103-1.ph5, 7.7.0+7.0.0-38.38

bpftool6.12

1:6.12.100-125.179.amzn2023

bpftool6.18

1:6.18.41-94.142.amzn2023

cluster-md-kmp-64kb

6.12.0-160000.37.1

cluster-md-kmp-azure

6.12.0-160000.37.1

cluster-md-kmp-default

5.14.21-150400.24.235.1, 5.14.21-150500.55.182.1, 6.12.0-160000.37.1, 6.4.0-150600.23.130.1, 6.4.0-150700.53.78.1

cluster-md-kmp-rt

6.12.0-160000.37.1, 6.4.0-150700.7.72.1

dlm-kmp-64kb

6.12.0-160000.37.1

dlm-kmp-azure

6.12.0-160000.37.1

dlm-kmp-default

5.14.21-150400.24.235.1, 5.14.21-150500.55.182.1, 6.12.0-160000.37.1, 6.4.0-150600.23.130.1, 6.4.0-150700.53.78.1

dlm-kmp-rt

6.12.0-160000.37.1, 6.4.0-150700.7.72.1

dtb-allwinner

6.12.0-160000.37.1

dtb-altera

6.12.0-160000.37.1

dtb-amazon

6.12.0-160000.37.1

dtb-amd

6.12.0-160000.37.1

dtb-amlogic

6.12.0-160000.37.1

dtb-apm

6.12.0-160000.37.1

dtb-apple

6.12.0-160000.37.1

dtb-arm

6.12.0-160000.37.1

dtb-broadcom

6.12.0-160000.37.1

dtb-cavium

6.12.0-160000.37.1

dtb-exynos

6.12.0-160000.37.1

dtb-freescale

6.12.0-160000.37.1

dtb-hisilicon

6.12.0-160000.37.1

dtb-lg

6.12.0-160000.37.1

Timeline

  1. Publicly disclosed

    Jul 29, 2026

  2. Last updated

    Oct 16, 2026

Weakness Type

  • CWE-364 Signal Handler Race Condition

References

15 more references in the full CVE brief

FAQ

Common Questions.

Is CVE-2026-64560 On Your Attack Surface?

Brandefense matches it against the products discovered on your perimeter and opens a finding the day a CVE like this is listed.

Request A Demo

Figures as of Oct 19, 2026. Compiled by Brandefense technologies from public vulnerability catalogs; scoring as described in How it works.

To report an error, contact Brandefense.