Lucene search
+L

Linux Distros Unpatched Vulnerability : CVE-2026-98981

🗓️ 23 Oct 2026 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 1 Views

Race condition in Linux kernel dentry handling allows uncovering hidden mounts.

Related
Refs
Code
ReporterTitlePublishedViews
Family
circl
Circl
CVE-2026-98981
23 Oct 202613:27
–circl
cve
CVE
CVE-2026-98981
23 Oct 202612:19
–cve
cvelist
Cvelist
CVE-2026-98981 namespace: unhash a dentry before detaching the mounts on it
23 Oct 202612:19
–cvelist
debiancve
Debian CVE
CVE-2026-98981
23 Oct 202612:19
–debiancve
euvd
EUVD
EUVD-2026-108775
23 Oct 202612:19
–euvd
nvd
NVD
CVE-2026-98981
23 Oct 202613:17
–nvd
osv_debian
osv_debian
DEBIAN-CVE-2026-98981
23 Oct 202613:17
–osv_debian
ptsecurity
Positive Technologies
PT-2026-121958
23 Oct 202600:00
–ptsecurity
susecve
SUSE CVE
SUSE CVE-2026-98981
23 Oct 202623:52
–susecve
#%NASL_MIN_LEVEL 80900
##
# (C) Tenable, Inc.
##

include('compat.inc');

if (description)
{
  script_id(371592);
  script_version("1.1");
  script_set_attribute(attribute:"plugin_modification_date", value:"2026/10/23");

  script_cve_id("CVE-2026-98981");

  script_name(english:"Linux Distros Unpatched Vulnerability : CVE-2026-98981");

  script_set_attribute(attribute:"synopsis", value:
"The Linux/Unix host has one or more packages installed with a vulnerability that the vendor indicates will not be
patched.");
  script_set_attribute(attribute:"description", value:
"The Linux/Unix host has one or more packages installed that are impacted by a vulnerability without a vendor supplied
patch available.

  - 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--- (CVE-2026-98981)

Note that Nessus relies on the presence of the package as reported by the vendor.");
  script_set_attribute(attribute:"see_also", value:"https://security-tracker.debian.org/tracker/CVE-2026-98981");
  script_set_attribute(attribute:"solution", value:
"There is no known solution at this time.");
  script_set_attribute(attribute:"agent", value:"unix");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P");
  script_set_cvss_temporal_vector("CVSS2#E:U/RL:U/RC:C");
  script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H");
  script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:U/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2026-98981");

  script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"false");
  script_set_attribute(attribute:"vendor_unpatched", value:"true");

  script_set_attribute(attribute:"vuln_publication_date", value:"2026/10/23");
  script_set_attribute(attribute:"plugin_publication_date", value:"2026/10/23");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"cpe", value:"cpe:/o:debian:debian_linux:12.0");
  script_set_attribute(attribute:"cpe", value:"cpe:/o:debian:debian_linux:13.0");
  script_set_attribute(attribute:"cpe", value:"p-cpe:/a:debian:debian_linux:linux");
  script_set_attribute(attribute:"generated_plugin", value:"current");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Misc.");

  script_copyright(english:"This script is Copyright (C) 2026 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("ssh_get_info2.nasl", "set_linux_os_id.nasl");
  script_require_keys("Host/cpu", "Host/local_checks_enabled", "global_settings/vendor_unpatched", "Host/OS/identifier");
  script_require_ports("Host/OS/Debian Linux-12", "Host/OS/Debian Linux-13");

  exit(0);
}

if (!get_kb_item("global_settings/vendor_unpatched")) exit(0, "Unpatched Vulnerabilities Detection not active.");
if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
if (empty_or_null(get_one_kb_item("Host/Debian/dpkg-l"))) audit(AUDIT_PACKAGE_LIST_MISSING);

include('linux_unpatched.inc');

var distro_constraints_array = {
  "Debian Linux-12": {
    "package_manager": "dpkg-l",
    "constraints": [
      {
        "release": "12",
        "pkgs": [
          {"reference": "btrfs-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "cdrom-core-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "ext4-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "fat-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "isofs-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "jfs-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "kernel-image-6.1.0-50-alpha-generic-di"},
          {"reference": "linux-doc"},
          {"reference": "linux-doc-6.1"},
          {"reference": "linux-headers-6.1.0"},
          {"reference": "linux-source"},
          {"reference": "linux-source-6.1"},
          {"reference": "linux-support-6.1.0"},
          {"reference": "loop-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "nic-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "nic-shared-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "nic-wireless-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "pata-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "ppp-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "scsi-core-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "scsi-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "scsi-nic-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "serial-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "usb-serial-modules-6.1.0-50-alpha-generic-di"},
          {"reference": "xfs-modules-6.1.0-50-alpha-generic-di"}
        ]
      }
    ]
  },
  "Debian Linux-13": {
    "package_manager": "dpkg-l",
    "constraints": [
      {
        "release": "13",
        "pkgs": [
          {"reference": "bpftool"},
          {"reference": "hyperv-daemons"},
          {"reference": "intel-sdsi"},
          {"reference": "libcpupower-dev"},
          {"reference": "libcpupower1"},
          {"reference": "linux-bpf-dev"},
          {"reference": "linux-config-6.12"},
          {"reference": "linux-cpupower"},
          {"reference": "linux-doc"},
          {"reference": "linux-doc-6.12"},
          {"reference": "linux-headers-4kc-malta"},
          {"reference": "linux-headers-5kc-malta"},
          {"reference": "linux-headers-6.12.107+deb13-4kc-malta"},
          {"reference": "linux-headers-6.12.107+deb13-5kc-malta"},
          {"reference": "linux-headers-6.12.107+deb13-alpha-generic"},
          {"reference": "linux-headers-6.12.107+deb13-alpha-smp"},
          {"reference": "linux-headers-6.12.107+deb13-amd64"},
          {"reference": "linux-headers-6.12.107+deb13-arm64"},
          {"reference": "linux-headers-6.12.107+deb13-arm64-16k"},
          {"reference": "linux-headers-6.12.107+deb13-armmp"},
          {"reference": "linux-headers-6.12.107+deb13-armmp-lpae"},
          {"reference": "linux-headers-6.12.107+deb13-cloud-amd64"},
          {"reference": "linux-headers-6.12.107+deb13-cloud-arm64"},
          {"reference": "linux-headers-6.12.107+deb13-common"},
          {"reference": "linux-headers-6.12.107+deb13-common-rt"},
          {"reference": "linux-headers-6.12.107+deb13-loong64"},
          {"reference": "linux-headers-6.12.107+deb13-loongson-3"},
          {"reference": "linux-headers-6.12.107+deb13-m68k"},
          {"reference": "linux-headers-6.12.107+deb13-mips32r2eb"},
          {"reference": "linux-headers-6.12.107+deb13-mips32r2el"},
          {"reference": "linux-headers-6.12.107+deb13-mips64r2eb"}
        ]
      }
    ]
  }
};

var distro_constraints_values = linux_unpatched::get_distro_constraints(distro_constraints_arr:distro_constraints_array);
if (empty_or_null(distro_constraints_values)) audit(AUDIT_HOST_NOT, 'affected');

var third_party_support = get_kb_item('Host/OS/extended-third-party');
if (!empty_or_null(third_party_support)) {
    var third_party_vendors = distro_constraints_values['third_party'];
    if (!empty_or_null(third_party_vendors)) {
        var vendor;
        foreach vendor (third_party_vendors) {
            if (vendor == third_party_support) exit(0, 'A third party management patch is available for this vulnerability from ' + vendor + '.\n');
        }
    }
}

var report = linux_unpatched::check_unpatched_constraints(distro_constraints_values:distro_constraints_values);

if (!empty_or_null(report))
{
  security_report_v4(
      port       : 0,
      severity   : SECURITY_WARNING,
      extra      : report
  );
  exit(0);
}
else
{
  audit(AUDIT_HOST_NOT, 'affected');
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

23 Oct 2026 00:00Current
5.8Medium risk
Vulners AI Score5.8
EPSS0.00209
1