CVE-2026-98995 (GCVE-0-2026-98995)
Vulnerability from cvelistv5
Published
2026-10-23 12:20
Modified
2026-10-24 14:09
Summary
In the Linux kernel, the following vulnerability has been resolved: namespace: reset the old parent's ->overmount in mnt_change_mountpoint() __umount_mnt() resets ->overmount of the parent when it unmounts the mount that overmounts it. mnt_change_mountpoint() doesn't. It moves the mount to its new parent and leaves the old one pointing at it. For a mount that is moved beneath in attach_recursive_mnt() that doesn't matter. The new mount has already reset ->overmount of the old parent by the time the old top mount is moved onto it. It matters for reparent() though. propagate_umount() moves a surviving overmount onto the first ancestor that isn't going to be unmounted. The mount it was taken from is unmounted immediately afterwards. If a file descriptor keeps that unmounted mount alive ->overmount points at the moved mount. That's a dangling pointer and UAF as the moved mount is unmounted and freed. do_lock_mount() follows ->overmount from the target path under mount_lock. With a file descriptor on such a mount as the target of a mount beneath topmost_overmount() walks into the freed mount and do_lock_mount() takes references on whatever it finds there. So reset ->overmount of the old parent in mnt_change_mountpoint() the same way __umount_mnt() does. A mount's ->overmount is then always a mount that is attached to it.
Impacted products
Vendor Product Version
Linux Linux Version: ffdc52fbbd5835a936ad683c943d6d103a2d4514
Version: ffdc52fbbd5835a936ad683c943d6d103a2d4514
Version: ffdc52fbbd5835a936ad683c943d6d103a2d4514
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "fs/namespace.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "5e0a1f2c753a79749bc2ead3ae2f2ede3941daa5",
              "status": "affected",
              "version": "ffdc52fbbd5835a936ad683c943d6d103a2d4514",
              "versionType": "git"
            },
            {
              "lessThan": "08d575ee89393fd812dbdca7b5d7b4574cd5a564",
              "status": "affected",
              "version": "ffdc52fbbd5835a936ad683c943d6d103a2d4514",
              "versionType": "git"
            },
            {
              "lessThan": "476ef286a7a5db8bda51325dc0c45887b4d99d9a",
              "status": "affected",
              "version": "ffdc52fbbd5835a936ad683c943d6d103a2d4514",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "fs/namespace.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.17"
            },
            {
              "lessThan": "6.17",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.18.*",
              "status": "unaffected",
              "version": "6.18.57",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "7.2.*",
              "status": "unaffected",
              "version": "7.2.11",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "7.3",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.18.57",
                  "versionStartIncluding": "6.17",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.2.11",
                  "versionStartIncluding": "6.17",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.3",
                  "versionStartIncluding": "6.17",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nnamespace: reset the old parent\u0027s -\u003eovermount in mnt_change_mountpoint()\n\n__umount_mnt() resets -\u003eovermount of the parent when it unmounts the\nmount that overmounts it. mnt_change_mountpoint() doesn\u0027t. It moves the\nmount to its new parent and leaves the old one pointing at it.\n\nFor a mount that is moved beneath in attach_recursive_mnt() that doesn\u0027t\nmatter. The new mount has already reset -\u003eovermount of the old parent by\nthe time the old top mount is moved onto it.\n\nIt matters for reparent() though. propagate_umount() moves a surviving\novermount onto the first ancestor that isn\u0027t going to be unmounted. The\nmount it was taken from is unmounted immediately afterwards. If a file\ndescriptor keeps that unmounted mount alive -\u003eovermount points at the\nmoved mount. That\u0027s a dangling pointer and UAF as the moved mount is\nunmounted and freed.\n\ndo_lock_mount() follows -\u003eovermount from the target path under\nmount_lock. With a file descriptor on such a mount as the target of a\nmount beneath topmost_overmount() walks into the freed mount and\ndo_lock_mount() takes references on whatever it finds there.\n\nSo reset -\u003eovermount of the old parent in mnt_change_mountpoint() the\nsame way __umount_mnt() does. A mount\u0027s -\u003eovermount is then always a\nmount that is attached to it."
        }
      ],
      "metrics": [
        {
          "cvssV3_1": {
            "baseScore": 7.8,
            "baseSeverity": "HIGH",
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
            "version": "3.1"
          },
          "scenarios": [
            {
              "lang": "en",
              "value": "AV:L - Local umount2() reaches do_umount()-\u003eumount_tree()-\u003epropagate_umount()-\u003ereparent()-\u003emnt_change_mountpoint(), and local move_mount(MOVE_MOUNT_BENEATH) later consumes the dangling overmount; no network or physical input reaches this path.\nAC:L - The regression test deterministically creates the propagation topology, pins X_b, frees its reparented overmount, and triggers the UAF; no race or external state is required, and any mount-cache grooming is attacker-controlled.\nPR:L - can_umount() and move_mount() require may_mount(), but the test\u0027s unshare(CLONE_NEWUSER|CLONE_NEWNS) gives an ordinary local user CAP_SYS_ADMIN in the child mount namespace, satisfying every mount-operation gate without init-namespace root.\nUI:N - The attacker personally creates the shared/private tmpfs mounts, opens the O_PATH descriptor, performs both lazy unmounts, and invokes move_mount(); no victim must mount, open, or otherwise act on anything.\nS:U - The dangling struct mount created by mnt_change_mountpoint() corrupts the same host kernel that enforces the attacker\u0027s mount namespace; this is ordinary kernel privilege escalation, not a VM, hypervisor, or IOMMU boundary crossing.\nC:H - topmost_overmount() reads freed struct mount contents, and where_to_mount() then consumes its stale overmount, mnt_mountpoint, and mnt_parent pointers; reclaiming the mnt_cache object permits redirected kernel-memory accesses and high-impact disclosure.\nI:H - do_lock_mount() calls mntget() and dget() through the freed mount-derived pointers, causing reference-count writes through stale mnt_pcp and dentry state; mount-cache reclamation and heap grooming can turn these UAF writes into control-flow corruption.\nA:H - Following the freed overmount and then dereferencing or locking the stale dentry-\u003ed_inode can produce a kernel UAF oops or panic, and the complete mount/unmount/move_mount sequence is repeatable by the same unprivileged process."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-24T14:09:55.095Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/5e0a1f2c753a79749bc2ead3ae2f2ede3941daa5"
        },
        {
          "url": "https://git.kernel.org/stable/c/08d575ee89393fd812dbdca7b5d7b4574cd5a564"
        },
        {
          "url": "https://git.kernel.org/stable/c/476ef286a7a5db8bda51325dc0c45887b4d99d9a"
        }
      ],
      "title": "namespace: reset the old parent\u0027s -\u003eovermount in mnt_change_mountpoint()",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-98995",
    "datePublished": "2026-10-23T12:20:14.155Z",
    "dateReserved": "2026-09-25T10:25:14.384Z",
    "dateUpdated": "2026-10-24T14:09:55.095Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…