# CVE-2026-93066: x86/mm/pat: Take cpa_lock around large-page collapse

> A race condition in the Linux kernel x86/mm/pat module allows local attackers to trigger a use-after-free, potentially leading to privilege escalation or code execution.

- **Severity:** Not scored
- **Exploited in the wild:** Not known
- **Login needed:** Not needed
- **Attackable:** Local or same network only
- **Victim action needed:** Not needed
- **Fix available:** Yes
- **Published:** 17 Sep 2026
- **Updated:** 19 Oct 2026
- **Also known as:** BELL-CVE-2026-93066, DEBIAN-CVE-2026-93066, GHSA-cfxg-jwq4-727c, UBUNTU-CVE-2026-93066

## What is CVE-2026-93066?

CVE-2026-93066 is an use after free vulnerability in Linux, published on 17 Sep 2026. It can only be exploited from the same machine or local network, with no action from the victim.

### Official description

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.

## Which versions are affected by CVE-2026-93066?


## How do I fix CVE-2026-93066?

Apply the vendor's patch.

## Is CVE-2026-93066 being exploited?

There is no known exploitation of CVE-2026-93066 in the wild and no public exploit code.

## Fix prompt for AI coding agents

```text
Check this codebase for CVE-2026-93066 and fix it if it is affected.

What it is: CVE-2026-93066 is an use after free vulnerability in Linux, published on 17 Sep 2026. It can only be exploited from the same machine or local network, with no action from the victim.
Exploitation: There is no known exploitation of CVE-2026-93066 in the wild and no public exploit code.

Affected product: Linux. No package-level version data is available, so check the vendor advisory linked from the reference page.

Task:
1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.
2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.
3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.
4. Run the tests and summarise what changed and why.
5. If nothing in the project is affected, say so and change nothing.

Reference: https://insights.sbomify.com/CVE-2026-93066/ (Markdown: https://insights.sbomify.com/CVE-2026-93066/index.md)
```

## Sources

- CVE record: https://www.cve.org/CVERecord?id=CVE-2026-93066
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-93066
- OSV: https://osv.dev/vulnerability/CVE-2026-93066

---
From sbomify Insights: https://insights.sbomify.com/CVE-2026-93066/
Summaries are generated and may contain mistakes; the official description above is the record.
