Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessGain local unprivileged shell
-
DeliveryClone mount tree and overmount target file
-
ExploitRace unlink/rmdir against concurrent lookups
-
ExecutionResolve stale hashed positive dentry
-
ImpactRead 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. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – 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
Affected Packages
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
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
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.
Primary rating from Vendor (Linux).
CVSS VectorVendor: Linux
Lifecycle Timeline
4DescriptionCVE.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
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.
Apply vendor patch.
Threat Intelligence Overview
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.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
EUVD-2026-108775
GHSA-9hg7-cp6v-469m
NVD
CVE.org
EPSS
Exploit-DB