Sceawere
Vulnerability Detail
CVE-2026-97525UPDATED Verified Sceawere Triage Sources: NVD / CISA KEV
Linux Kernel Improper PTE Allocation
Vulnerability Metadata
- Severity
- High
- Score / CVSS
- 8.2
- Creation Date
- 8h ago
- Vendor
- Linux
- Product
- Linux
- Attack Type
- N/A
- Vector String
- CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
- Attack Complexity
- LOW
Narrative and Response
Description
In the Linux kernel, the following vulnerability has been resolved: x86/mm/pat: Allocate split page tables as kernel page tables A PTE is allocated directly without going through the standard page table allocation routines (such as pte_alloc_one_kernel()) when the CPA code splits a large page (__split_large_page()). This means the page table constructor is never called nor is the page table marked as a kernel page table. The former results in the folio associated with the page table not being marked as a page table (__pagetable_ctor() is never called thus neither is __folio_set_pgtable()) nor are statistics updated to reflect it (lruvec_stat_add_folio() is never called). The latter issue of failing to mark the page table as a kernel page table (ptdesc_set_kernel() is never called) is far more problematic. Since commit: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") kernel page table freeing has been batched and since the subsequent commit: e37d5a2d60a3 ("iommu/sva: invalidate stale IOTLB entries for kernel address space") IOTLB cache entries for kernel page tables have been invalidated upon being freed. Since split page tables are freed without this invalidation, the IOTLB can contain stale entries for them. Resolve the issue by using the ordinary PTE allocation API at split time. This results in these kernel page tables invoking a page table constructor, and thus requires a page table destructor. Destructors are not always present, like for early allocated direct map page tables). Conditionally call pagetable_dtor_free() if the PG_table folio flag for the ptdesc is set, otherwise we free the page table via pagetable_free(). Regardless of which path is taken page tables marked as kernel page tables, which now includes split page tables, take the correct route through pagetable_free_kernel(). There is a user-visible side effect in that split page tables will appear in nr_page_table_pages in /proc/vmstat (as do other kernel page tables allocated after early boot), however this is a positive change. This issue started being markedly problematic after commit: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables") so choose this as the Fixes target. [ dhansen: rephrase in imperative mood ]
Executive Summary
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Technical Details
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Mitigations
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
References
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Additional Metadata
{
"score": "8.2",
"pubDate": "2026-09-25T11:17:02.647Z",
"pubdate": "2026-09-25T11:17:02.647Z",
"executiveSummary": "The vulnerability involves an improper allocation mechanism for Page Table Entries (PTEs) within the x86 Linux kernel's Change Page Attribute (CPA) logic during large page splitting operations.\nBy bypassing standard page table allocation routines, the kernel fails to initialize necessary metadata, including the page table constructor and kernel page table status flags.\nThis architectural oversight leads to a state where split page tables are incorrectly managed, resulting in a failure to perform critical IOTLB invalidation upon page table freeing.\nImpact includes memory corruption, potential kernel stability issues, and the risk of stale IOTLB entries being utilized, which could be leveraged to bypass memory protections or cause system crashes.\nThe vulnerability affects kernel versions since the introduction of deferred freeing for kernel page tables (commit 5ba2f0a15564).\nExploitation requires the kernel to perform large page splits, typically triggered by dynamic memory attribute changes (e.g., PAT updates), potentially allowing an attacker with the ability to influence kernel memory attributes to induce unstable memory states.",
"technicalDetails": "The root cause of this vulnerability lies in the __split_large_page() function within the x86 PAT (Page Attribute Table) subsystem. When splitting a large page, the function allocates a PTE manually instead of utilizing established kernel page table allocation APIs such as pte_alloc_one_kernel().\nBecause the standard allocation routines are bypassed, the following critical lifecycle hooks are missed: __pagetable_ctor() is never executed, meaning the folio is not marked as a page table (folio_set_pgtable()); ptdesc_set_kernel() is never called, leaving the page table incorrectly marked in terms of ownership; and the lruvec_stat_add_folio() accounting is bypassed, leading to incorrect memory statistics.\nThe most critical consequence relates to the memory management changes introduced in commit 5ba2f0a15564 ('mm: introduce deferred freeing for kernel page tables') and commit e37d5a2d60a3 ('iommu/sva: invalidate stale IOTLB entries for kernel address space'). These mechanisms rely on the page table being correctly identified as a kernel page table to ensure that IOTLB caches are properly invalidated when the memory is reclaimed.\nSince the split page tables are not flagged as kernel page tables, they are freed without triggering the required IOTLB invalidation sequence. Consequently, stale entries can persist in the IOTLB. If these memory addresses are subsequently reallocated and repurposed by the kernel, the stale IOTLB entries may still point to the old, freed physical pages or contain inconsistent security attributes.\nThe attack flow involves triggering a large page split through legitimate kernel operations that modify memory attributes (e.g., changing memory types or mapping permissions via mprotect or similar interfaces). Once the split page table is created improperly, the subsequent freeing of that table leaves the IOTLB in a desynchronized state. An attacker may attempt to orchestrate memory pressure or specific allocation patterns to trigger the reuse of these stale mapping entries, potentially leading to unauthorized memory access or arbitrary kernel code execution depending on what the physical page is repurposed for.\nThe fix mandates the use of the standard PTE allocation API, which ensures that page table constructors are called and that destructors are appropriately managed via pagetable_dtor_free() or pagetable_free(), ensuring that kernel page table metadata is consistently maintained across the lifecycle of the page table."
}