Skip to main content

Linux Kernel EUVDEUVD-2026-108775

| CVE-2026-98981 HIGH
2026-10-23 Linux GHSA-9hg7-cp6v-469m
8.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 shell
  2. Delivery
    Clone mount tree and overmount target file
  3. Exploit
    Race unlink/rmdir against concurrent lookups
  4. Execution
    Resolve stale hashed positive dentry
  5. Impact
    Read previously hidden overmounted file contents

Vulnerability Assessment

Exploitation Conditions

Exploitation requires local access by a user who can create/clone mount namespaces - using open_tree(OPEN_TREE_CLONE) and move_mount, generally available to unprivileged users where unprivileged user namespaces are permitted - plus a target file or directory that is a mountpoint in another mount namespace being removed via unlink(), rmdir(), or rename(), and winning the race between detach_mounts() and d_delete(). Limiting factors: the vector is local only (AV:L, no remote/UI path), it depends on the attacker-prepared overmount/bind-mount topology and concurrent lookups, and it is a timing race; however, the commit notes the race window is large (a full synchronize_rcu_expedited() grace period plus the inode_unlock()), which is why the maintainer's test achieved a high hit rate. Hosts that disable unprivileged user namespaces materially reduce exposure.

Impact

The signals pull in different directions and should be read together. The NVD CVSS of 8.8 (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) rates this highly, but every serious exploitation signal is muted: the attack vector is local (AV:L), EPSS is only 0.21% (10th percentile), there is no CISA KEV listing, and the vuln.today decision label is 'this_week' rather than act_now/emergency. There is also an internal inconsistency worth flagging: the tag and the upstream description both describe a confidentiality race - a lookup 'uncovers what the mounts hid' to read an overmounted file - yet the NVD vector asserts I:H and A:H, which the described mechanism does not clearly support; verify the integrity/availability impact with the kernel maintainers rather than treating I:H/A:H as confirmed. Net: this is a legitimate local information-disclosure race in the VFS mount-namespace path that merits patching in the normal kernel update cycle (consistent with 'this_week'), but the low EPSS, absence of KEV, local-only vector, and the required multi-namespace overmount setup make mass or remote exploitation unlikely. Treat it as a meaningful container/namespace-isolation bug for multi-tenant and sandboxed hosts, not a drop-everything emergency.

Exploit ScenarioDerived

A local unprivileged user who can create mount namespaces sets up a cloned mount tree that overmounts a sensitive file (hiding its real contents), then runs several concurrent lookups while the file's mountpoint is removed via unlink/rmdir/rename. By winning the race between detach_mounts() and d_delete(), a walker resolves the still-hashed, still-positive dentry and reads the underlying content the mount was concealing. The upstream commit message includes a reproducer that counts such reads; it is embedded demonstration code, not listed as verified weaponized exploit code, so this is best described as a public PoC reference that is not verified as a working exploit.

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 24, 2026

Linux kernel filesystem teardown can disclose content that a mount was meant to hide: when unlink(), rmdir() or rename() removes an entry that is a mountpoint in another mount namespace, the dentry remains hashed and positive between detach_mounts() and d_delete(), so a racing lookup can resolve past the mount to the underlying overmounted file or directory. A local user who can create or clone mount namespaces (open_tree(OPEN_TREE_CLONE) plus move_mount, generally permitted to unprivileged users where unprivileged user namespaces are enabled) and who races lookups against the removal obtains read access to the covered object's content. The race is timing-dependent (assessed AC:H) but the window spans a full synchronize_rcu_expedited() grace period plus the caller's inode_unlock(), so it is not narrow; a maintainer-supplied reproducer is published with the fix commit, EPSS is 0.21% (10th percentile) and the issue is not in CISA KEV at time of analysis.

RemediationAI

Vendor-released patch: upgrade to 6.6.160, 6.12.114, 6.18.57, 7.2.11 or 7.3, or apply the matching stable commit listed above (db90eecbde319527aa9480c039d32a0f5fe80574, 8d71bfc9b3fc15d7103e82ea9dc5057541866e46, d29cd99db3db74cf3447be74d25740981789d461, 8300de4aa5d09061bfcf2af5b52c0cdba3873185, 528b383dc35d1e5caf64ddf5d35f983ae543b0d0); note that the commit message says this closes only the lockless lookup path and that a follow-up patch is still required for the reference-count lookup, so the fix should not be assumed to remove every variant of the race. Where patching must be staged, the most direct exposure control is to deny unprivileged user namespaces, which removes the ability to build the open_tree(OPEN_TREE_CLONE)/move_mount topology the attack needs: set kernel.unprivileged_userns_clone=0 on Debian/Ubuntu derivatives, or user.max_user_namespaces=0 where that sysctl is authoritative. The trade-off is significant and must be weighed first: rootless containers, Flatpak, browser and build sandboxes and some CI tooling that rely on unprivileged user namespaces will stop working for non-root users until the setting is reverted or those workloads are granted the capability some other way. Detection value is limited because the race leaves no distinct VFS footprint; monitoring for unusual open_tree/move_mount activity by unprivileged users alongside file removals of mountpoints is the practical compensating signal.

Affected VersionsENISA

Linux 8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe <d29cd99db3db74cf3447be74d25740981789d461
Linux 8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe <528b383dc35d1e5caf64ddf5d35f983ae543b0d0
Linux 3.18
Linux patch: 7.2.11
Linux 8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe <db90eecbde319527aa9480c039d32a0f5fe80574
Linux patch: 0
Linux 8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe <8300de4aa5d09061bfcf2af5b52c0cdba3873185
Linux patch: 6.12.114
Linux patch: 6.6.160
Linux patch: 7.3
Linux 8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe <8d71bfc9b3fc15d7103e82ea9dc5057541866e46
Linux patch: 6.18.57

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 VFS dcache and mount-namespace teardown path rather than in any single filesystem driver. unlink(), rmdir() and rename() remove the name from the filesystem, call detach_mounts() on the entry while the inode is locked, and only call d_delete() after the inode is unlocked; in between, __detach_mounts() left the dentry hashed and positive even though nothing covers it any more, so a dcache lookup could find it and uncover whatever the overmount hid. The fix mirrors the ordering already used by d_invalidate(): d_drop() the dentry first so it can no longer be found, then detach the mounts and unlink. The reasoning in the commit is that a lookup which has not yet found the dentry will miss it in the dcache and block on the directory lock held by the caller until the name is gone, while a lockless lookup that already found it fails the mount_lock check while the dentry still counts as a mountpoint and the d_seq check once it does not, and then retries. The commit explicitly states that this closes the lockless path only and that the reference-count lookup needs a follow-up patch, so the committed fix should be treated as partial. No CWE identifier was supplied by the source data; the CPE records are cpe:2.3:a:linux:linux:*:*:*:*:*:*:*:* for the generic kernel product, and EUVD separately tracks the issue as EUVD-2026-108775.

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 8.8 HIGH
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
vuln.today AI 5.6 MEDIUM

Local race across mount namespaces needing attacker-prepared overmount and a won timing window, so AV:L/AC:H/PR:L; impact is reading hidden file contents (C:H), with no described integrity or availability effect.

3.1 AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N
4.0 AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/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
Changed
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

4
CVSS changed
Oct 24, 2026 - 14:22 NVD
8.8 (HIGH)
Patch available
Oct 23, 2026 - 13:17 EUVD
CVE Published
Oct 23, 2026 - 12:19 cve.org
HIGH 8.8
CVE Published
Oct 23, 2026 - 12:19 cve.org
UNKNOWN (no severity yet)

DescriptionCVE.org

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

namespace: unhash a dentry before detaching the mounts on it

unlink(), rmdir() and rename() remove the entry from the filesystem, call detach_mounts() on the entry with the inode locked and then call d_delete() once the inode is unlocked.

The thing is that between detach_mounts() and d_delete() the dentry is still hashed and positive. But after detach_mounts() nothing covers the dentry anymore. A lookup that finds this dentry in the dcache can uncover what the mounts hid.

That's a problem when unlinking files or directories that are mountpoints in other mount namespaces. Everybody who had the underlying entry covered can race the detach_mount() call until d_delete() has run.

The race window isn't all that small. It encompasses namespace_unlock() with a full synchronize_rcu_expedited() grace period and the inode_unlock() of the entry.

In my experiments three walkers that kept trying read an overmounted file in 11938 of the 16140 unlinks that removed its mountpoint from a bind mount of the filesystem within a minute.

Fun fact, d_invalidate() has the same ordering problem but gets it right. It unhashes the dentry first and detaches the mounts afterwards. Let's do the same in __detach_mounts():

  • A lookup that hasn't found the dentry yet misses it in the dcache and

waits for the directory lock that the caller holds until the name is gone for good.

  • A lockless lookup that found it already fails the mount_lock check

while the dentry still counts as a mountpoint and the d_seq check once it doesn't, and retries.

This fixes the lockless path. We still need to fix the reference count lookup in a follow-up patch.

So d_drop() the dentry. The dentry stays positive and held but can't be found anymore. Then proceed with the detach and unlink.

Reproducer:

The reads were counted with the program below, three walkers for 60 s in a VM with 4 CPUs. The race window is stretched with the debug patch pasted here. fs.detach_race_walk_us sleeps in lookup_fast() once it found a mountpoint dentry and before its mounts are crossed. fs.detach_race_unlink_us sleeps in vfs_unlink() between detach_mounts() and d_delete().

// SPDX-License-Identifier: GPL-2.0 /*

  • unlink_covered: unlink a file that is a mountpoint in a detached copy of
  • its mount, against lookups that open it through that copy.

*

  • A is a tmpfs with the file f1 (content SECRET_F) and the plain file
  • MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
  • on A'/f1, held through an O_PATH fd on its root once the tree fd is
  • closed. Walkers open f1 through that fd while the driver unlinks A/f1,
  • where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
  • A read of SECRET_F is a hit: the name was found after its mount was
  • gone. The lockless walks use openat2(RESOLVE_CACHED).

*

  • usage: unlink_covered [-t seconds] [-w walkers]

*/ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <errno.h> #include <fcntl.h> #include <pthread.h> #include <stdatomic.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/syscall.h> #include <linux/openat2.h>

#ifndef __NR_open_tree #define __NR_open_tree 428 #endif #ifndef __NR_move_mount #define __NR_move_mount 429 #endif #ifndef __NR_openat2 #define __NR_openat2 437 #endif #ifndef OPEN_TREE_CLONE #define OPEN_TREE_CLONE 1 #endif #ifndef OPEN_TREE_CLOEXEC #define OPEN_TREE_CLOEXEC O_CLOEXEC #endif #ifndef MOVE_MOUNT_F_EMPTY_PATH #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 #endif

#define WORK "/tmp/uc" #define ADIR WORK "/A"

static int duration = 60, nwalkers = 3; static atomic_int stop, writer_waiting; static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER; static int cur_fd = -1; /* the root of A', -1 wh ---truncated---

Executive ViewAI

Why It Matters

CVE-2026-98981 is a high-severity Linux kernel flaw that allows local users to bypass mount isolation and read files or directories that should be hidden, such as secrets or sensitive data in overmounted paths. Any organization relying on Linux systems with unprivileged user namespaces enabled is at risk, and because a public reproducer exists and a patch is available, immediate remediation is warranted to prevent data leakage.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.2%
Top 90% exploitable
Prevalence
Ubiquitous
Linux kernel runs on the vast majority of servers, devices, and containers
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
Defer
Exploitation· derived
None
System Exposure· derived
Small
Automatable· derived
No
Human Impact
High

Priority Score

44
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +44
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