CVE-2026-93066 in Linux
Summary
by MITRE • 09/17/2026
In the Linux kernel, the following vulnerability has been resolved:
x86/mm/pat: Take cpa_lock around large-page collapse
Loading and unloading modules concurrently on several CPUs on a KASAN build, with a short delay injected at the CPA page-table lookup to widen the window, faults within minutes:
BUG: KASAN: use-after-free in __change_page_attr+0x7cc/0x7e0 Write of size 8 at addr ffff888181139718 by task modprobe ... The buggy address belongs to the physical page: pfn:0x181139 ... page_type: f2(table)
cpa_collapse_large_pages() rebuilds a leaf PMD from its 4K PTEs and frees the old PTE-table pages, while __change_page_attr() fetches a PTE pointer from a lockless lookup_address_in_pgd_attr() and writes it with set_pte_atomic() only later. When module text is served from a shared large ROX mapping the two run on the same PMD:
CPU A (module load) CPU B (module finalize) ------------------- ----------------------- execmem_make_temp_rw set_memory_nx __change_page_attr split 2M -> 4K table P kpte = &P[i] (lockless)
execmem_restore_rox set_memory_rox (CPA_COLLAPSE) cpa_collapse_large_pages rebuild leaf PMD flush_tlb_all pagetable_free(P) set_pte_atomic(kpte, ...) -> writes into freed P
P is a page-table page (page_type: table), reused at once, so the write corrupts whatever got the page next: a bad-pte or bad-page splat, or a fatal fault once P has been turned into read-only text.
The flush_tlb_all() before the free does not close this: its IPI only serializes against page-table walkers that run with interrupts off (e.g. GUP-fast); the walk in __change_page_attr() runs with interrupts on, so nothing stops it from holding a stale pointer into P.
Serialize the collapse - the PMD rebuild, TLB flush and PTE-table free - under cpa_lock, the same lock __change_page_attr() now takes unconditionally since commit ("x86/mm/pat: stop gating cpa_lock on debug_pagealloc_enabled()"), so a concurrent walker can no longer hold a pointer into a table the collapse is about to free.
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 09/17/2026
The Linux kernel vulnerability identified in the x86 memory management subsystem involves a critical race condition within the page attribute change (CPA) mechanism, specifically affecting large-page collapsing operations. This flaw manifests when modules are loaded and unloaded concurrently across multiple CPUs on systems utilizing Kernel Address Sanitizer builds with injected delays to widen timing windows. The core issue arises from an insufficient synchronization model during the transition between different memory protection states, leading to a use-after-free condition that can trigger kernel panics or data corruption within minutes of operation under heavy concurrent module activity.
The technical root cause lies in the interaction between two distinct code paths: one responsible for collapsing small page table entries into large pages and another handling attribute changes such as setting memory regions as non-executable or read-only. The function cpa_collapse_large_pages rebuilds a leaf Page Middle Directory entry from its constituent 4K Page Table Entries while simultaneously freeing the old PTE-table pages. Concurrently, __change_page_attr performs a lockless lookup of page table pointers to modify attributes using set_pte_atomic. When module text resides in shared large read-only execute mappings, both operations may target the same PMD structure. CPU A executing module load procedures initiates attribute changes that require splitting large pages into smaller ones, while CPU B finalizing modules triggers a collapse operation that reassembles those pages and frees the underlying memory structures before the first CPU completes its write operation.
This race condition results in a use-after-free scenario where one processor writes to page table entries using pointers obtained from a lockless lookup, only for another processor to free those exact memory pages during the collapse process. The freed PTE-table pages are immediately reused by subsequent allocations, meaning that stale pointer writes corrupt whatever data structure subsequently occupies that physical memory region. This corruption can manifest as bad-pte errors, bad-page splats indicating invalid page states, or fatal faults when the corrupted memory is eventually mapped back into read-only text segments for execution. The existing mitigation of issuing a full TLB flush before freeing pages proves insufficient because it only serializes against page-table walkers running with interrupts disabled, such as GUP-fast operations, while __change_page_attr operates with interrupts enabled and thus remains vulnerable to concurrent access.
The operational impact extends beyond immediate system crashes to potential security implications involving memory corruption that could be exploited for privilege escalation or denial of service attacks. Attackers leveraging this vulnerability through rapid module loading and unloading cycles can destabilize the kernel, causing unpredictable behavior across the entire operating system environment. The lack of proper locking around critical sections allows concurrent modifications to shared page table structures without adequate synchronization barriers, violating fundamental principles of safe memory management in multi-core environments where cache coherency and atomicity must be strictly maintained through explicit locking mechanisms rather than relying solely on hardware-level TLB invalidation sequences.
The resolution involves serializing the entire collapse operation including PMD rebuilds, TLB flushes, and PTE-table deallocations under cpa_lock synchronization primitives. This change ensures that __change_page_attr also acquires this lock unconditionally during attribute modifications, preventing concurrent walkers from holding stale pointers into memory structures currently being freed by collapsing operations. By aligning the locking strategy with existing patterns established in related commits addressing debug page allocation behaviors, the kernel establishes a consistent protection model for all CPA-related activities regardless of debugging configurations. This fix eliminates the race window entirely by ensuring mutual exclusion between readers and writers accessing shared page table hierarchies during dynamic memory attribute changes.
From an industry standards perspective this vulnerability aligns with CWE-416 Use After Free, representing improper resource management where pointers continue to be used after they have been freed leading to undefined behavior and potential exploitation vectors. The attack pattern corresponds to ATT&CK technique T1059 Command and Scripting Interpreter through automated module loading scripts that exploit timing windows for denial of service or further compromise attempts. Mitigation strategies include applying the kernel patch immediately, implementing strict rate limiting on module load operations in production environments where possible, and monitoring system logs for early indicators such as KASAN reports indicating use-after-free conditions within memory management subsystems before full exploitation occurs.