Linux Kernel Security Research: Page Cache Vulnerability Class
The Vulnerability Class
Every "dirty" Linux kernel privilege escalation shares a single anti-pattern:
-
User-controlled
splice()orsendfile()plants a page cache page reference into a kernel buffer (pipe_buffer,sk_bufffrag, scatterlist, etc.) -
A kernel subsystem performs in-place modification on that buffer (crypto transform, checksum, compression)
-
No check verifies page exclusivity before writing
-
Result: a read-only page cache page is silently corrupted in RAM
The page cache is the recurring battleground because it backs both file I/O and memory-mapped files.
Corrupt it and you can modify /etc/passwd, /usr/bin/su, or any SUID binary in RAM without touching disk.
Known Exploits
| Vulnerability | Year | Target Structure | Mechanism |
|---|---|---|---|
Dirty COW |
2016 |
Page table entries |
Race condition in COW fault handler (CVE-2016-5195) |
Dirty Pipe |
2022 |
|
|
CopyFail |
2026 |
Page cache via |
In-place AEAD crypto on shared page cache page (CVE-2026-31431) |
Dirty Frag |
2026 |
Page cache via |
In-place crypto on `splice()’d page cache ref in ESP/RxRPC (CVE-2026-43284, CVE-2026-43500) |
CopyFail — CVE-2026-31431
Disclosed April 29, 2026.
A logic flaw in algif_aead.c — the kernel’s AF_ALG socket interface for AEAD cryptography.
An unprivileged local user can write 4 controlled bytes into the page cache of any readable file.
Root cause: Three independently reasonable kernel changes created a dangerous combination:
-
authencesnAEAD wrapper added (2011) -
AF_ALG AEAD socket support added (2015)
-
An in-place optimization in
algif_aead.c(2017) — this commit made it exploitable
Severity:
-
Deterministic — no race condition. A 732-byte Python script gets root. Every time.
-
No disk trace — corruption happens in the page cache (RAM-resident file data), not on disk
-
9 years of exposure — kernel 4.14 through 6.18.21 / 6.19.11 / pre-7.0
-
CISA confirmed active exploitation May 5, 2026; federal patch deadline May 15
Fix: One-line revert of the 2017 optimization (commit a664bf3d603d).
The modprobe blacklist workaround for algif_aead does nothing on RHEL-family distros because the module is compiled into the kernel (CONFIG_CRYPTO_USER_API_AEAD=y).
The commands succeed silently, giving a false sense of security.
|
Dirty Frag — CVE-2026-43284 + CVE-2026-43500
Disclosed May 7, 2026.
Two page-cache write primitives chained together — one in ESP (IPsec, esp4/esp6) and one in RxRPC.
Both exploit splice() zero-copy send paths where the kernel performs in-place crypto operations on frag members of struct sk_buff that reference read-only page cache pages.
Why two CVEs: Each variant covers the other’s blind spots:
-
ESP variant needs
CAP_NET_ADMIN(obtainable via unprivileged user namespaces) -
RxRPC variant works without user namespaces but requires
rxrpc.ko -
Ubuntu blocks user namespace creation — RxRPC path works
-
RHEL allows user namespaces — ESP path works
Relationship to CopyFail: Same vulnerability class.
Dirty Frag explicitly bypasses CopyFail’s mitigation — the algif_aead blacklist is irrelevant here.
Patch status (as of 2026-05-08):
-
ESP half patched in mainline (commit
f4c50a4034e6) -
RxRPC half (CVE-2026-43500) — no patch yet. PoC is public. This is a live zero-day.
What Makes This Class Exploitable
The common thread across all four vulnerabilities:
kernel receives page reference via splice()/sendfile()
→ page belongs to the page cache (shared, read-only)
→ subsystem treats it as a private buffer
→ writes through the reference
→ page cache is corrupted for all consumers
The correct kernel behavior is to copy before modifying — call skb_cow_data(), alloc_page() + memcpy, or equivalent.
The vulnerability exists wherever this guard is absent.