← All Advisories
Reported from OT-Advisories.com as of

CVE-2026-99170

Last refreshed2026-10-31

Status: UPDATED  |  Advisory ID: CVE-2026-99170

Key Details

CVECVE-2026-99170
CVSS Score / Version
8.8 (High) / CVSS v3.1
Updated2026-10-31
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CVSS Prose
attack vector is local; attack complexity is low; privileges required is low; user interaction is none; scope is changed; confidentiality impact is high; integrity impact is high; availability impact is high.
Affected products
Linux Kernel

Affected Products, Subsystems & Sectors

VendorProductAffected VersionsPatch Status
LinuxLinux Kernel
SubsystemsOT Supporting Infrastructure
SectorsAll Sectors

What to Know

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

namespace: a mount that copy_tree() leaves out can't take over a lock

Since commit c62a4766937e ("move_mount: transfer MNT_LOCKED") a mount

can be moved beneath a locked mount. The lock moves from the old cover

to the new mount which takes over the job of hiding what's under it and

the old cover can be unmounted. That works as long as the new mount

stays. But the caller picks the new mount and copy_tree() leaves a

mount of a mount namespace file out of every copy made without

CL_COPY_MNT_NS_FILE, together with everything mounted on it, and never

looks at MNT_LOCKED. unshare(CLONE_NEWNS) and mount propagation make

such copies.

So a task that is root in its own user namespace gets rid of a locked

cover on a file without a race and without touching the filesystem

below it. It makes a child with a mount namespace of its own, binds the

child's /proc/<pid>/ns/mnt beneath the cover with MOVE_MOUNT_BENEATH,

which hands the lock to that bind, and calls unshare(CLONE_NEWNS). The

new mount namespace has nothing on the file. That's the usual way to

mask a single file, a bind of /dev/null or of an empty file. With a

bind of an ordinary file the file stays covered.

copy_tree() already refuses to leave out a locked unbindable mount with

-EPERM since commit df7342b24018 ("mount: Don't allow copying

MNT_UNBINDABLE|MNT_LOCKED mounts"). Do the same for a locked mount of a

mount namespace file. That also covers a tree copied with

CL_COPY_MNT_NS_FILE and attached into a mount namespace of another user

namespace where lock_mnt_tree() locks it. Note that unshare(CLONE_NEWNS)

and clone(CLONE_NEWNS) fail with EPERM from such a mount namespace from

then on. The mount can't be left out and it can't be unmounted.

And refuse to move a mount of a mount namespace file beneath a locked

mount in the first place. Otherwise the task ends up with a mount it

can't unmount and an unshare() that fails for good.

Chris also found a second mount that goes away by itself, a clone of an

automounted mount that shrink_submounts() took along with its parent.

Commit f78ddcc87224 ("namespace: never expire a locked mount") took

care of that one.

Chris's reproducer is appended. Mode nsfile reads SECRET after the

unshare() on 7.3-rc7, with this patch the move_mount() fails with

EINVAL and the file stays covered. nsfile-control uses an ordinary file

and reads MASK both ways.

// SPDX-License-Identifier: GPL-2.0

/*

* Get rid of a locked cover with MOVE_MOUNT_BENEATH.

*

* The "admin" (root) makes a tmpfs W:

* W/D file, holds SECRET, covered by a bind of a file with MASK

* W/Dd/inner file, holds SECRET, Dd is covered by a bind of a directory

* whose "inner" holds MASK

* W/own directory of uid 1000 with the file "mine" and the

* directory "minedir", whose "inner" holds MINE

* W/dbg debugfs, mode 755. dbg/tracing is an automount point

* The "attacker" is uid 1000. It enters a new user namespace with a new mount

* namespace, so W and both covers are locked there.

*

* usage: prog MODE

* plain put a bind of own/mine beneath the cover of D, unmount the cover

* nsfile put a bind of the mount namespace file of a child beneath the

* cover of D, then unshare(CLONE_NEWNS)

* nsfile-control the same with a bind of own/mine

* shrink put a bind of the automounted tracefs beneath the cover of Dd,

* unmount the cover, put a tmpfs beneath W, call umount(W), which fails

* shrink-control the same with a bind of own/minedir

* The environment variable AUTOMOUNT_DIR names another automount point for "shrink".

*/

#define _GNU_SOURCE

#include <errno.h>

#include <fcntl.h>

#include <grp.h>

#include <sched.h>

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

---truncated--- (NVD)

What to Do

Monitor Linux's web page for any future patch releases.

References

SourceReference
NVDhttps://nvd.nist.gov/vuln/detail/CVE-2026-99170
CVEhttps://www.cve.org/CVERecord?id=CVE-2026-99170
Report compilation © 2026 OT-Advisories.com  ·  CC BY 4.0  ·  Source materials remain the property of their respective publishers as cited.