---
id: CVE-2026-31397
title: |-
  In the Linux kernel, the following vulnerability has been resolved:

  mm/huge_memory: fix use of NULL folio in move_pages_huge_pmd()

  move_pages_huge_pmd() handles UFFDIO_MOVE for both normal THPs and huge
  zero pages
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  mm/huge_memory: fix use of NULL folio in move_pages_huge_pmd()

  move_pages_huge_pmd() handles UFFDIO_MOVE for both normal THPs and huge
  zero pages.  For the huge zero p…
severity: high
cvss: 7.8
cvssVector: 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H'
cwe:
  - CWE-476
vendor: linux
product: linux_kernel
affected:
  - 'linux_kernel >= 6.16, < 6.18.20'
  - 'linux_kernel >= 6.19, < 6.19.10'
  - linux_kernel = 7.0
patched:
  - linux_kernel 6.19.10
published: '2026-04-03'
updated: '2026-07-24'
source: NVD
sourceUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-31397'
references:
  - url: 'https://git.kernel.org/stable/c/e3133d0986dc5a231d5419167dbac65312b28b41'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
  - url: 'https://git.kernel.org/stable/c/f3caaee0f9e489fd2282d4ce45791dc8aed2da62'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
  - url: 'https://git.kernel.org/stable/c/fae654083bfa409bb2244f390232e2be47f05bfc'
    label: 416baaa9-dc9f-4396-8d5f-8c081fb06d67
tags:
  - nvd
epss: 0.00119
epssPercentile: 0.01988
ingestedAt: '2026-07-25T22:05:04.182Z'
---

## Overview

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

mm/huge_memory: fix use of NULL folio in move_pages_huge_pmd()

move_pages_huge_pmd() handles UFFDIO_MOVE for both normal THPs and huge
zero pages.  For the huge zero page path, src_folio is explicitly set to
NULL, and is used as a sentinel to skip folio operations like lock and
rmap.

In the huge zero page branch, src_folio is NULL, so folio_mk_pmd(NULL,
pgprot) passes NULL through folio_pfn() and page_to_pfn().  With
SPARSEMEM_VMEMMAP this silently produces a bogus PFN, installing a PMD
pointing to non-existent physical memory.  On other memory models it is a
NULL dereference.

Use page_folio(src_page) to obtain the valid huge zero folio from the
page, which was obtained from pmd_page() and remains valid throughout.

After commit d82d09e48219 ("mm/huge_memory: mark PMD mappings of the huge
zero folio special"), moved huge zero PMDs must remain special so
vm_normal_page_pmd() continues to treat them as special mappings.

move_pages_huge_pmd() currently reconstructs the destination PMD in the
huge zero page branch, which drops PMD state such as pmd_special() on
architectures with CONFIG_ARCH_HAS_PTE_SPECIAL.  As a result,
vm_normal_page_pmd() can treat the moved huge zero PMD as a normal page
and corrupt its refcount.

Instead of reconstructing the PMD from the folio, derive the destination
entry from src_pmdval after pmdp_huge_clear_flush(), then handle the PMD
metadata the same way move_huge_pmd() does for moved entries by marking it
soft-dirty and clearing uffd-wp.

## Affected

- `linux_kernel >= 6.16, < 6.18.20`
- `linux_kernel >= 6.19, < 6.19.10`
- `linux_kernel = 7.0`

## Remediation

Upgrade past the affected range:

- `linux_kernel 6.19.10`
