CVE-2026-93066
NoneCVSS
—
EPSS
0.2%
Published
Sep 17, 2026
CISA due date
—
Cloudanix analysis
A timing problem in how the Linux kernel manages memory page permissions on multi-processor systems can cause crashes when programs are loaded and unloaded at the same time.
- Exploitation
- Local Privilege
- Attacker needs
- High Privilege
- Complexity
- Moderate
- Impact
- Privilege Gain
- Component
- OS kernel
- Class
- Race Condition
- Remediation
- Patch
- Effort
- Medium
- Patch risk
- Low
What it actually does
Race condition in x86 page attribute handling allows concurrent CPA operations on large ROX mappings to free a page-table page while another walker holds a stale pointer, resulting in use-after-free write.
Why it matters to the business
Linux systems may experience kernel crashes, memory corruption, or denial of service during concurrent module loading and unloading on multi-CPU KASAN builds; low exploitation likelihood limits widespread operational disruption.
How an attack unfolds
An attacker triggers concurrent module load and finalize operations across CPUs while a delay widens the lookup window, causing one path to free a PTE table that the other later writes into via a stale pointer.
How to fix it
Apply the upstream kernel commit that unconditionally serializes cpa_collapse_large_pages under cpa_lock; rebuild and deploy the patched kernel image across all affected systems.
How to confirm the fix worked
Confirm the cpa_lock acquisition surrounds the entire collapse sequence including TLB flush and pagetable_free; run concurrent module load/unload stress tests under KASAN to verify absence of use-after-free reports.
Typical attack path
- Load module on CPU A triggering execmem_make_temp_rw and split to 4K tables
- Concurrently finalize module on CPU B invoking CPA_COLLAPSE to rebuild PMD and free tables
- CPU A performs lockless lookup then delayed set_pte_atomic into freed page
- Corruption manifests as bad PTE, bad page, or fault when page is reused
How to detect it
Review kernel logs for KASAN use-after-free splats referencing __change_page_attr and cpa_collapse_large_pages; inspect page_type transitions from table to other uses immediately after module finalize events.
What your security team should do
- Prioritize kernel updates on multi-CPU x86 systems running module-heavy workloads
- Monitor upstream stable branches for backports of the cpa_lock change
- Limit concurrent module operations in high-assurance environments until patched
The record
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.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|