Skip to main content

Linux Kernel EUVDEUVD-2026-93184

| CVE-2026-98256 HIGH
2026-10-06 Linux GHSA-jj25-6g4q-4cf8
7.8
CVSS 3.1 · Vendor: Linux
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Gain local unprivileged code execution
  2. Delivery
    Create SIGEV_THREAD_ID timer on group leader tid
  3. Exploit
    Force non-leader execve() to stale the pid mapping
  4. Execution
    Race release_task() flush with blocked timer expiry
  5. Persist
    Trigger use-after-free write via tgkill()
  6. Impact
    Corrupt freed kernel slab for privilege escalation

Vulnerability Assessment

Exploitation Conditions

Requires local code execution as an unprivileged user on an affected kernel (PR:L, AV:L) and the ability to use POSIX timers (timer_create with SIGEV_THREAD_ID) and tgkill. The specific trigger condition is a non-leader thread calling execve() (de_thread() exchanging tids before release_task(leader)) while a timer signal targeting the old leader's tid is left blocked so its sigqueue stays queued on task::pending - the attacker must then win the race between release_task()'s unlocked signal flush and the next timer expiry. Limiting factors: exploitation is a timing/memory-ordering race (most impactful on weakly-ordered/SMP systems), there is no remote vector, authentication/local access is required, and the bug is only present in kernels containing the recent change that moved the sigqueue flush out of the sighand-locked region.

Impact

This is a kernel use-after-free (write of 8 bytes into a freed POSIX timer sigqueue) reachable by a local, low-privileged user, consistent with the supplied CVSS 3.1 vector CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (base 7.8, HIGH) and its C:H/I:H/A:H impact typical of kernel memory corruption that can lead to local privilege escalation. However, the signals point to low real-world urgency: EPSS is only 0.17% (6th percentile), there is no CISA KEV listing (not actively exploited), and no public PoC is referenced - the only artifacts are three kernel.org stable fix commits. One notable tension: the input CVSS scores this AC:L, but the description is explicitly a tight race condition (non-leader exec() de_thread()/release_task() flush racing a blocked timer's expiry on a weakly-ordered memory model), which in practice is hard to win reliably and argues for AC:H - I assess AC:H below. A second flag: the only technique tag is 'Information Disclosure', yet the root cause is a UAF write enabling memory corruption / potential LPE, not primarily disclosure - treat the tag as imprecise. Net: a legitimate HIGH-severity local kernel bug worth patching in the normal cycle, but not an emergency given low EPSS, no KEV, no PoC, and a non-trivial race requirement.

Exploit ScenarioDerived

A local unprivileged attacker already executing code on the host creates a SIGEV_THREAD_ID POSIX timer bound to a thread-group leader's tid, then forces a non-leader execve() so the stale struct pid points at the surviving thread; by keeping the timer signal blocked and winning the race between release_task()'s signal flush and a later timer expiry, the attacker leaves a sigqueue entry linked into a freed timer. A subsequent tgkill() then performs a list_add_tail() that follows the dangling pointer into RCU-freed kernel memory. No public exploit is referenced, and reliable exploitation requires winning a timing/memory-ordering race.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 07, 2026

Use-after-free write in the Linux kernel's signal delivery path lets a local, unprivileged user corrupt a freed POSIX timer sigqueue and potentially escalate privileges on the host. The race triggers when a non-leader thread calls execve() while a blocked SIGEV_THREAD_ID timer signal aimed at the old thread-group leader's TID is being flushed, so the kernel can re-queue the sigqueue onto a task::pending list that release_task()/exit_signals() is concurrently tearing down and then dereference the freed timer via a later tgkill(). Affected builds are those carrying the change that moved the sigqueue flush out of the sighand-locked region (EUVD lists Linux 6.15 era onward); exploitation requires local access and winning a timing/memory-ordering race, no public exploit code has been identified at time of analysis, the CVE is not listed in CISA KEV, and EPSS is 0.17% (6th percentile), so the practical concern is a HIGH-severity (7.8 base, C:H/I:H/A:H) local privilege-escalation primitive rather than mass exploitation.

RemediationAI

Vendor-released patch: update to Linux 6.18.54, 7.2.8 or 7.3-rc4, or apply the matching stable backports 621c365739828900f32a0c1cdfe5387528a62176, 934bd95f1a6404dbb845951b823547abab05a649 and d2710c8d938ae6a825a6463158e6e6f31eac792a (see https://git.kernel.org/stable/c/621c365739828900f32a0c1cdfe5387528a62176); confirm in your distribution's kernel changelog that the fix is present, since it depends on moving the pending-signal flush into exit_signals() and will not apply cleanly on a tree that moved the sigqueue flush out of the sighand lock without the accompanying PF_EXITING changes. There is no sysctl, boot parameter or config toggle that closes this race, and disabling POSIX timers platform-wide is not viable for general-purpose systems, so the primary action is patching. If patching must be delayed, treat the kernel as a trust boundary: stop running untrusted local code on the host (shared CI runners, multi-tenant containers, untrusted shells), and use seccomp or a sandbox profile to deny timer_create and tgkill for untrusted workloads, accepting that this breaks legitimate multithreaded applications, runtimes and profilers that use POSIX timers or thread-directed signals. Isolating tenants in separate kernels (VMs, microVMs) or applying strict mandatory access control confinement reduces exposure but does not remove it until the update is installed, and because the trigger is a local timing race that is most reliable on SMP/weakly-ordered systems, prioritize patch cycles for multi-tenant, container-hosting and desktop/workstation hosts; the low EPSS (0.17%) and the absence of KEV listing or public exploit code mean broad opportunistic exploitation is unlikely, so scheduling can follow the 7.8 HIGH base score rather than emergency response. No vendor advisory in the supplied data offers an alternative mitigation beyond the kernel patch, and the NVD reference at https://nvd.nist.gov/vuln/detail/CVE-2026-98256 should be checked for updated distributor guidance.

Affected VersionsENISA

Linux patch: 0
Linux fb3bbcfe344e64a46574a638b051ffd78762c12d <621c365739828900f32a0c1cdfe5387528a62176
Linux patch: 7.2.8
Linux fb3bbcfe344e64a46574a638b051ffd78762c12d <934bd95f1a6404dbb845951b823547abab05a649
Linux 6.15
Linux fb3bbcfe344e64a46574a638b051ffd78762c12d <d2710c8d938ae6a825a6463158e6e6f31eac792a
Linux patch: 6.18.54
Linux patch: 7.3-rc4

Affected Packages

euvd linux no fix

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The flaw lives in the kernel signal subsystem and its interaction with POSIX timers and thread-group exec. de_thread() calls exchange_tids() before release_task(leader), so a struct pid held by a SIGEV_THREAD_ID timer that was created against the leader's TID now resolves through pid_task() to the thread that called execve(); lock_task_sighand() on that thread succeeds. If the timer's signal is blocked, its sigqueue stays queued on the leader's task::pending, and the next timer expiry can run concurrently with release_task() flushing that queue. posixtimer_send_sigqueue() checks whether the sigqueue is already queued with a plain list_empty(), which only reads list_head::next, while list_del_init() is not atomic and INIT_LIST_HEAD() stores next before prev, so the check can pass inside that window. list_add_tail() then queues the entry onto the live thread's task::pending, and the flush's later list_head::prev store overwrites the prev link list_add_tail() just set; because __flush_itimer_signals() ends up with a prev pointer aimed at the entry itself, its list_del_init() only rewrites the same values and fails to unlink the entry. The sigqueue survives the RCU free of the timer, and a subsequent tgkill()'s list_add_tail() follows that stale prev link into freed slab memory, producing the KASAN slab-use-after-free 8-byte write in __send_signal_locked() shown in the report. The upstream cure is structural: block queueing of task-private (PIDTYPE_PID) signals once PF_EXITING is set, in both __send_signal_locked() and posixtimer_send_sigqueue(); take sighand lock when setting PF_EXITING in exit_signals() for the thread-group-empty and group-exit cases; and flush task::pending there by moving the whole list to an on-stack head under the lock and freeing entries without the lock held, which removes the late lockless flush entirely. In class terms this is a race-condition-driven use-after-free (the memory-safety family normally tracked as CWE-416/CWE-362), although this record ships no CWE; note that the feed tag "Information Disclosure" understates the primitive, which is a write primitive into freed memory, not a read/leak. The CPE cpe:2.3:a:linux:linux:*:*:*:*:*:*:*:* reflects that this is upstream kernel code with no separate vendor component to scope.

Know when the next one hits your stack

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (Linux) PRIMARY 7.8 HIGH
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
vuln.today AI 7.0 HIGH

Local-only via syscalls so AV:L/PR:L; AC:H because it is a timing/memory-ordering race during non-leader exec; kernel UAF yields full C:H/I:H/A:H.

3.1 AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
4.0 AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (Linux).

CVSS VectorVendor: Linux

Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

4
CVSS changed
Oct 07, 2026 - 07:22 NVD
7.8 (HIGH)
Patch available
Oct 06, 2026 - 10:02 EUVD
CVE Published
Oct 06, 2026 - 08:45 cve.org
UNKNOWN (no severity yet)
CVE Published
Oct 06, 2026 - 08:45 cve.org
HIGH 7.8

DescriptionCVE.org

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

signal: Prevent exec() race

Hyunwoo debugged the following KASAN UAF splat:

BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0 Write of size 8 at addr ffff888007ed80c8 by task poc/79 ... Call Trace: __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Allocated by task 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Freed by task 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Last potentially related work creation: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0

It turned out that this happens with a non-leader exec() as Hyunwoo explained:

de_thread() calls exchange_tids() before release_task(leader), so the struct pid held by a SIGEV_THREAD_ID timer created against the leader's tid now points to the thread which called execve(). pid_task() returns that thread and lock_task_sighand() on it succeeds.

If the timer signal is blocked, its sigqueue stays queued on the leader's task::pending. The next expiry of that timer can then run while release_task() flushes the queue.

posixtimer_send_sigqueue() checks whether the sigqueue is already queued with a plain list_empty(), which only reads list_head::next. list_del_init() is not atomic and INIT_LIST_HEAD() stores list_head::next before list_head::prev, so the check can pass in between. list_add_tail() queues the entry on the task::pending of the live thread, and the list_head::prev store from the flush then overwrites the list_head::prev link that list_add_tail() has just set.

__flush_itimer_signals() does not undo that either. With list_head::prev pointing at the entry itself, its list_del_init() only stores the same values again, so the entry is not removed from the list. It is still there after the last reference is dropped and the timer is freed by RCU, and the list_add_tail() of a later tgkill() follows that list_head::prev into the freed timer.

This problem surfaced with the recent commit which moved the sigqueue flush out of the sighand lock held region.

Hyonwoo proposed to fix this by using list_del_init_careful(), but that just papers over the problem. After some disucssions and various attempts to solve it, Eric pointed out that there is no reason to flush task::pending late in release_task() and it should be done in exit_signals() already.

As nothing can collect and deliver signals which are queued in a dying task's pending queue, there is no reason to delay it further.

But it has to be ensured that no signals can be queued into it after that point. exit_signals() sets PF_EXITING in task::flags, which can be used as an indicator for this.

Cure it by:

  • Preventing signal queueing for task private signals (PIDTYPE_PID) when

the task has PF_EXITING set in __send_signal_locked() and in posixtimer_send_sigqueue().

  • Protecting the unlocked setting of PF_EXITING in exit_signals() for the

task group empty and the group exit case with sighand lock

  • Flushing task::pending signals right there.

Optimize that by moving the whole pending list to an on-stack list head under sighand lock and free the signals without the lock held.

There has been quite some discussion about the lockless flush and the non-leader exec case on weakly ordered systems. The problem is that a third party which tries to send a posix timer signal relies on the PID lookup to find the target task and that lookup might result in the new leader when the signal was originaly directed to the old leader. In case that the signal was queued on the old leader then the lockless flush raised a concern over the following situation:

old_leader new_leader third party

A: flush_list() // list_del_in ---truncated---

Executive ViewAI

Why It Matters

A high-severity Linux kernel flaw (CVE-2026-98256) gives any local account on an affected host a path to full root-level compromise by exploiting a use-after-free race in the signal-delivery path. The exposure is concentrated in 6.15-era kernel builds and is most dangerous wherever untrusted users or workloads share a kernel - multi-tenant hosts, container and Kubernetes worker nodes, CI/CD runners, and jump boxes. Because it converts an ordinary low-privilege foothold into host-wide control, leadership should treat it as a priority privilege-escalation risk rather than a routine local bug.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.2%
Top 94% exploitable
Prevalence
Ubiquitous
Linux kernel core signal/timer code, present in nearly all deployments
Data Quality
4 sources
Confidence: Medium

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Small
Automatable· derived
No
Human Impact
High

Priority Score

39
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +39
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy