CVE-2026-89961 PUBLISHED

powerpc/mm: fix wrong addr_pfn tracking in compound vmemmap population

Assigner: Linux
Reserved: 11.09.2026 Published: 16.09.2026 Updated: 16.09.2026

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

powerpc/mm: fix wrong addr_pfn tracking in compound vmemmap population

vmemmap_populate_compound_pages() uses addr_pfn to determine the PFN offset within a compound page and to decide whether the current vmemmap slot should be populated as a head page mapping or should reuse a tail page mapping.

However, addr_pfn is advanced manually in parallel with addr. The loop itself progresses in vmemmap address space, so each PAGE_SIZE step in addr covers PAGE_SIZE / sizeof(struct page) struct page slots. Since addr_pfn is compared against nr_pages in data-PFN units, it should advance by the same number of PFNs. The existing manual increments do not match that and therefore do not reliably track the PFN corresponding to the current addr.

As a result, pfn_offset can be computed from the wrong PFN and the code can make the head/tail decision for the wrong compound-page position.

Fix this by deriving addr_pfn directly from the current vmemmap address instead of carrying it as loop state.

Metrics

CVSS Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7.8

AV:L - The bug is in powerpc radix vmemmap_populate_compound_pages(), reached only through local ZONE_DEVICE hotplug (dev_dax_probe → devm_memremap_pages → arch_add_memory → sparse_add_section). It is not reachable from network protocols, Bluetooth, or USB. AC:L - Once device-DAX with compound vmemmap is mapped (2MB PMD on 4K kernels or 1GB PUD on 64K, the documented powerpc DAX configs), addr_pfn drifts on every loop iteration and the wrong head/tail mapping is deterministic; no race or attacker-uncontrollable layout is required. PR:L - Initial memremap requires administrator DAX setup, but on a provisioned persistent-memory or cloud POWER server an unprivileged local user with /dev/dax access can mmap the device and drive kernel use of the mis-aliased struct pages via faults and GUP without init-namespace CAP_SYS_ADMIN. UI:N - Exploitation needs no victim action; the attacker mmaps or faults the already-provisioned DAX device themselves. No mount, click, or hotplug by another user is required at exploit time. S:U - Impact is kernel struct-page aliasing and MM corruption inside the same host kernel security authority. It is not a KVM guest-to-host escape, IOMMU/DMA bypass, or sandbox boundary crossing. C:H - Wrong pfn_offset aliases distinct vmemmap pages so different DAX PFNs share struct-page backing; later memmap_init, faults, and GUP read corrupted flags, mapping, and compound-head fields, disclosing kernel memory via that metadata. I:H - The same aliases turn kernel writes (page init, folio mapping, refcount, compound head/tail linkage) into writes to the wrong struct pages, an exploitable kernel memory-corruption primitive that can hijack control flow rather than a bounded data modification. A:H - Mis-linked compound pages and aliased vmemmap cause kernel oops, BUG_ON, or panic when MM code walks folio heads, refcounts, or DAX fault handlers, fully denying availability of the affected POWER radix host.

Product Status

Vendor Linux
Product Linux
Versions Default: unaffected
  • affected from f2b79c0d79683d552369bb9a7282c1f0226fc566 to b96be860673f9fbbf12cdadb0b25fc4d6d4d207f (excl.)
  • affected from f2b79c0d79683d552369bb9a7282c1f0226fc566 to e163c7184acf36ac20a248498f4a16016057ca01 (excl.)
  • affected from f2b79c0d79683d552369bb9a7282c1f0226fc566 to 9c914b7a0bd18834505c65f22225ce22c152b2d9 (excl.)
  • affected from f2b79c0d79683d552369bb9a7282c1f0226fc566 to 7968852a7ca3ce81477ec5b4494a28d612f35a97 (excl.)
  • affected from f2b79c0d79683d552369bb9a7282c1f0226fc566 to 89a4ae32764172468dea303eb6ae90fe6c859712 (excl.)
Vendor Linux
Product Linux
Versions Default: affected
  • Version 6.6 is affected
  • unaffected from 0 to 6.6 (excl.)
  • unaffected from 6.6.157 to 6.6.* (incl.)
  • unaffected from 6.12.110 to 6.12.* (incl.)
  • unaffected from 6.18.51 to 6.18.* (incl.)
  • unaffected from 7.2.5 to 7.2.* (incl.)
  • unaffected from 7.3-rc1 to * (incl.)

References