CVE-2026-23077 (GCVE-0-2026-23077)
Vulnerability from cvelistv5
Published
2026-02-04 16:08
Modified
2026-08-05 12:20
Summary
In the Linux kernel, the following vulnerability has been resolved: mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted merge Patch series "mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted merge", v2. Commit 879bca0a2c4f ("mm/vma: fix incorrectly disallowed anonymous VMA merges") introduced the ability to merge previously unavailable VMA merge scenarios. However, it is handling merges incorrectly when it comes to mremap() of a faulted VMA adjacent to an unfaulted VMA. The issues arise in three cases: 1. Previous VMA unfaulted: copied -----| v |-----------|.............| | unfaulted |(faulted VMA)| |-----------|.............| prev 2. Next VMA unfaulted: copied -----| v |.............|-----------| |(faulted VMA)| unfaulted | |.............|-----------| next 3. Both adjacent VMAs unfaulted: copied -----| v |-----------|.............|-----------| | unfaulted |(faulted VMA)| unfaulted | |-----------|.............|-----------| prev next This series fixes each of these cases, and introduces self tests to assert that the issues are corrected. I also test a further case which was already handled, to assert that my changes continues to correctly handle it: 4. prev unfaulted, next faulted: copied -----| v |-----------|.............|-----------| | unfaulted |(faulted VMA)| faulted | |-----------|.............|-----------| prev next This bug was discovered via a syzbot report, linked to in the first patch in the series, I confirmed that this series fixes the bug. I also discovered that we are failing to check that the faulted VMA was not forked when merging a copied VMA in cases 1-3 above, an issue this series also addresses. I also added self tests to assert that this is resolved (and confirmed that the tests failed prior to this). I also cleaned up vma_expand() as part of this work, renamed vma_had_uncowed_parents() to vma_is_fork_child() as the previous name was unduly confusing, and simplified the comments around this function. This patch (of 4): Commit 879bca0a2c4f ("mm/vma: fix incorrectly disallowed anonymous VMA merges") introduced the ability to merge previously unavailable VMA merge scenarios. The key piece of logic introduced was the ability to merge a faulted VMA immediately next to an unfaulted VMA, which relies upon dup_anon_vma() to correctly handle anon_vma state. In the case of the merge of an existing VMA (that is changing properties of a VMA and then merging if those properties are shared by adjacent VMAs), dup_anon_vma() is invoked correctly. However in the case of the merge of a new VMA, a corner case peculiar to mremap() was missed. The issue is that vma_expand() only performs dup_anon_vma() if the target (the VMA that will ultimately become the merged VMA): is not the next VMA, i.e. the one that appears after the range in which the new VMA is to be established. A key insight here is that in all other cases other than mremap(), a new VMA merge either expands an existing VMA, meaning that the target VMA will be that VMA, or would have anon_vma be NULL. Specifically: * __mmap_region() - no anon_vma in place, initial mapping. * do_brk_flags() - expanding an existing VMA. * vma_merge_extend() - expanding an existing VMA. * relocate_vma_down() - no anon_vma in place, initial mapping. In addition, we are in the unique situation of needing to duplicate anon_vma state from a VMA that is neither the previous or next VMA being merged with. dup_anon_vma() deals exclusively with the target=unfaulted, src=faulted case. This leaves four possibilities, in each case where the copied VMA is faulted: 1. Previous VMA unfaulted: copied -----| ---truncated---
Impacted products
Vendor Product Version
Linux Linux Version: 879bca0a2c4f40b08d09a95a2a0c3c6513060b5c
Version: 879bca0a2c4f40b08d09a95a2a0c3c6513060b5c
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "mm/vma.c",
            "mm/vma.h"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "a4d9dbfc1bab16e25fefd34b5e537a46bed8fc96",
              "status": "affected",
              "version": "879bca0a2c4f40b08d09a95a2a0c3c6513060b5c",
              "versionType": "git"
            },
            {
              "lessThan": "61f67c230a5e7c741c352349ea80147fbe65bfae",
              "status": "affected",
              "version": "879bca0a2c4f40b08d09a95a2a0c3c6513060b5c",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "mm/vma.c",
            "mm/vma.h"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "6.16"
            },
            {
              "lessThan": "6.16",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.18.*",
              "status": "unaffected",
              "version": "6.18.8",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "6.19",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.18.8",
                  "versionStartIncluding": "6.16",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.19",
                  "versionStartIncluding": "6.16",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nmm/vma: fix anon_vma UAF on mremap() faulted, unfaulted merge\n\nPatch series \"mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted\nmerge\", v2.\n\nCommit 879bca0a2c4f (\"mm/vma: fix incorrectly disallowed anonymous VMA\nmerges\") introduced the ability to merge previously unavailable VMA merge\nscenarios.\n\nHowever, it is handling merges incorrectly when it comes to mremap() of a\nfaulted VMA adjacent to an unfaulted VMA.  The issues arise in three\ncases:\n\n1. Previous VMA unfaulted:\n\n              copied -----|\n                          v\n\t|-----------|.............|\n\t| unfaulted |(faulted VMA)|\n\t|-----------|.............|\n\t     prev\n\n2. Next VMA unfaulted:\n\n              copied -----|\n                          v\n\t            |.............|-----------|\n\t            |(faulted VMA)| unfaulted |\n                    |.............|-----------|\n\t\t                      next\n\n3. Both adjacent VMAs unfaulted:\n\n              copied -----|\n                          v\n\t|-----------|.............|-----------|\n\t| unfaulted |(faulted VMA)| unfaulted |\n\t|-----------|.............|-----------|\n\t     prev                      next\n\nThis series fixes each of these cases, and introduces self tests to assert\nthat the issues are corrected.\n\nI also test a further case which was already handled, to assert that my\nchanges continues to correctly handle it:\n\n4. prev unfaulted, next faulted:\n\n              copied -----|\n                          v\n\t|-----------|.............|-----------|\n\t| unfaulted |(faulted VMA)|  faulted  |\n\t|-----------|.............|-----------|\n\t     prev                      next\n\nThis bug was discovered via a syzbot report, linked to in the first patch\nin the series, I confirmed that this series fixes the bug.\n\nI also discovered that we are failing to check that the faulted VMA was\nnot forked when merging a copied VMA in cases 1-3 above, an issue this\nseries also addresses.\n\nI also added self tests to assert that this is resolved (and confirmed\nthat the tests failed prior to this).\n\nI also cleaned up vma_expand() as part of this work, renamed\nvma_had_uncowed_parents() to vma_is_fork_child() as the previous name was\nunduly confusing, and simplified the comments around this function.\n\n\nThis patch (of 4):\n\nCommit 879bca0a2c4f (\"mm/vma: fix incorrectly disallowed anonymous VMA\nmerges\") introduced the ability to merge previously unavailable VMA merge\nscenarios.\n\nThe key piece of logic introduced was the ability to merge a faulted VMA\nimmediately next to an unfaulted VMA, which relies upon dup_anon_vma() to\ncorrectly handle anon_vma state.\n\nIn the case of the merge of an existing VMA (that is changing properties\nof a VMA and then merging if those properties are shared by adjacent\nVMAs), dup_anon_vma() is invoked correctly.\n\nHowever in the case of the merge of a new VMA, a corner case peculiar to\nmremap() was missed.\n\nThe issue is that vma_expand() only performs dup_anon_vma() if the target\n(the VMA that will ultimately become the merged VMA): is not the next VMA,\ni.e.  the one that appears after the range in which the new VMA is to be\nestablished.\n\nA key insight here is that in all other cases other than mremap(), a new\nVMA merge either expands an existing VMA, meaning that the target VMA will\nbe that VMA, or would have anon_vma be NULL.\n\nSpecifically:\n\n* __mmap_region() - no anon_vma in place, initial mapping.\n* do_brk_flags() - expanding an existing VMA.\n* vma_merge_extend() - expanding an existing VMA.\n* relocate_vma_down() - no anon_vma in place, initial mapping.\n\nIn addition, we are in the unique situation of needing to duplicate\nanon_vma state from a VMA that is neither the previous or next VMA being\nmerged with.\n\ndup_anon_vma() deals exclusively with the target=unfaulted, src=faulted\ncase.  This leaves four possibilities, in each case where the copied VMA\nis faulted:\n\n1. Previous VMA unfaulted:\n\n              copied -----|\n                       \n---truncated---"
        }
      ],
      "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 - The vulnerability is triggered via the mremap() syscall, which requires local access to the system. There is no network or adjacent network path to reach this code.\nAC:L - The attacker can deterministically set up the required VMA layout (faulted VMA adjacent to unfaulted VMA) and trigger the bug with mremap(MREMAP_DONTUNMAP). Syzbot found this automatically, confirming reliable reproducibility.\nPR:L - The mremap() syscall is available to any unprivileged local user. No special capabilities or root privileges are required to trigger this vulnerability.\nUI:N - No user interaction is required. The attacker can trigger the vulnerability entirely through their own syscall sequence.\nS:U - This is a standard kernel memory corruption vulnerability. It does not cross security boundaries like VM escape or IOMMU bypass.\nC:H - The use-after-free on anon_vma gives the attacker control over freed object contents via heap spraying, enabling arbitrary kernel memory reads through the dangling folio references.\nI:H - The use-after-free enables heap spraying where attacker-controlled data replaces the freed anon_vma, providing arbitrary write primitives and potential control flow hijacking through corrupted kernel structures.\nA:H - The use-after-free causes kernel crashes when the dangling anon_vma pointers are accessed, leading to kernel oops or panic. Syzbot confirmed crashes from this bug."
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-05T12:20:13.107Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/a4d9dbfc1bab16e25fefd34b5e537a46bed8fc96"
        },
        {
          "url": "https://git.kernel.org/stable/c/61f67c230a5e7c741c352349ea80147fbe65bfae"
        }
      ],
      "title": "mm/vma: fix anon_vma UAF on mremap() faulted, unfaulted merge",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-23077",
    "datePublished": "2026-02-04T16:08:02.274Z",
    "dateReserved": "2026-01-13T15:37:45.959Z",
    "dateUpdated": "2026-08-05T12:20:13.107Z",
    "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…