data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2026-90003 in the interactive tracker

CVE-2026-90003

futex: Prevent rcuwait use-after-free during requeue PI

7.8 EPSS 0.2% AV:L

Published 2026-09-16 (33 days ago) by the Linux kernel CNA. Subsystem kernel/futex. Debian urgency: not yet assigned.

What to do, per Debian release

Debian's own status for CVE-2026-90003 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormfixedDLA-4841-1 · 2026-10-17 · text6.1.190-1Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts.
Debian 13trixiefixedDSA-6528-1 · 2026-09-29 · text6.12.111-1Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts.
Debian 14forkyfixed7.2.6-1Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed7.2.6-1Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts.
Debian 12bookworm · linux-6.12fixedDLA-4817-1 · 2026-10-04 · text6.12.111-1~deb12u1Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

On PREEMPT_RT, FUTEX_CMP_REQUEUE_PI can trigger a KASAN report (slab-out-of-bounds) in futex_requeue_pi_complete() invocation of rcuwait_wake_up(). The futex_q used by futex_wait_requeue_pi() is allocated on the waiter's stack. An early wakeup can race with a PI requeue as follows: waiter requeue task ------ ------------ futex_wait_requeue_pi() futex_do_wait() schedule() futex_requeue futex_proxy_trylock_atomic() futex_requeue_pi_prepare() Q_REQUEUE_PI_NONE -> Q_REQUEUE_PI_IN_PROGRESS * timeout/ signal wakes waiter * futex_requeue_pi_wakeup_sync() Q_REQUEUE_PI_IN_PROGRESS -> Q_REQUEUE_PI_WAIT requeue_pi_wake_futex futex_requeue_pi_complete() cmpxchg Q_REQUEUE_PI_WAIT -> Q_REQUEUE_PI_LOCKED rcuwait_wait_event() if (atomic_read(&q->requeue_state) != Q_REQUEUE_PI_WAIT) break /* no schedule() */ /* q.pi_state->owner == current */ futex_private_hash_put() /* return from syscall */ rcuwait_wake_up(&q->requeue_wait) /* q is gone */ futex_requeue_pi_complete() publishes Q_REQUEUE_PI_LOCKED before calling rcuwait_wake_up(). The waiter observes this state in rcuwait_wait_event() before invoking schedule() in rcuwait_wait_event(). Here, the waiter is free leave the syscall before requeue task can complete the wake. To address this race skip rcuwait_wake_up() in the Q_REQUEUE_PI_LOCKED case. This state is only published by requeue_pi_wake_futex(), which saves q->task before futex_requeue_pi_complete() and wakes the waiter via wake_up_state(). This wake is intended to wake the waiter from its futex_do_wait() sleep. If the waiter is still sleeping there, it can not get into the Q_REQUEUE_PI_WAIT state (and require this removed wake). Should the waiter be woken up from futex_do_wait() by other means (as in this example) and sleep in futex_requeue_pi_wakeup_sync() then the wake_up_state() from requeue_pi_wake_futex() will wake it, too. Should the waiter task terminate before wake_up_state() had a chance to wake the task then the task pointer does not become invalid because the futex_hash_bucket::lock is held and the task pointer is RCU protected. [bigeasy: Updated comment and commit message]

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

kernel/futex/requeue.c

What this is
FUTEX SUBSYSTEMMAINTAINERS section matched on kernel/futex/* · linux-kernel@vger.kernel.org · Maintained

Check it on the machine

grep -w CONFIG_FUTEX /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

Show whether Debian builds this, per release

Debian builds this code. Every release below compiles the affected file into the kernels it ships.

  • bookworm, trixie, forky, sid, bookworm · linux-6.12y
y
built into the kernel image on every flavour - only a patch removes it
Build switch
CONFIG_FUTEX

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2026-09-16 (33 days ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.16%, higher than 5.2% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
not yet assignedsource
Subsystem
kernel/futex

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
5.156.1.188220ee9e04ca3
5.156.6.15781aadbd09bf1
5.156.12.110244f301759fd
5.156.18.517d1559126d86
5.157.2.5e4a4ccfa470f
5.157.3a3b8d46fe401

Debian advisories

AdvisoryDateShipped toDebian
DLA-4841-12026-10-17bookworm 6.1.190-1tracker
DLA-4817-12026-10-04bookworm 6.12.111-1~deb12u1tracker
DSA-6528-12026-09-29trixie 6.12.111-1tracker

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
The bug is reached only through the local futex(2) syscalls FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI into kernel/futex/requeue.c; there is no network, Bluetooth, or physical-device path.
AC:LAttack complexity, low
The attacker controls both sides of the race: a waiter thread using FUTEX_WAIT_REQUEUE_PI with an attacker-chosen timeout or signal, and a concurrent FUTEX_CMP_REQUEUE_PI from another thread, and can retry with CPU pinning until the waiter returns before rcuwait_wake_up() on PREEMPT_RT.
PR:LPrivileges required, low
Any unprivileged local user can invoke futex() with FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI; do_futex() and futex_requeue() perform no capability or credential checks, CONFIG_FUTEX_PI is default-y, and the path is reachable from containers without elevated privileges.
UI:NUser interaction, none
The attacker's own threads perform the wait, timeout or signal, and PI requeue; no victim action such as mounting a filesystem or opening a file is required.
S:UScope, unchanged
The use-after-free corrupts kernel memory (the waiter's stack-allocated futex_q and a type-confused task_struct) within the same kernel security authority; this is a standard local privilege-escalation issue, not a VM, IOMMU, or hypervisor escape.
C:HConfidentiality impact, high
This is a use-after-free of the waiter's stack-allocated futex_q.requeue_wait; rcuwait_wake_up() reads a stale, attacker-refilled task_struct pointer and dereferences it in try_to_wake_up(), enabling arbitrary kernel-memory disclosure.
I:HIntegrity impact, high
The stale futex_q lives on the attacker's own kernel stack, which a following syscall can refill with controlled bytes, so rcuwait_wake_up() passes an attacker-chosen pointer into try_to_wake_up(), which writes task state and makes indirect scheduler calls, enabling privilege escalation.
A:HAvailability impact, high
In the unexploited case, rcuwait_wake_up() dereferences a wild pointer from reused stack memory and causes a kernel oops or panic; any use-after-free of this kind is a High availability impact.