Linux Page Cache Under Attack: What You Need to Know
Two recently disclosed Linux kernel vulnerabilities — Copy Fail (CVE-2026-31431) and DirtyFrag — are drawing urgent attention from the security community. Both vulnerabilities exploit subtle page cache corruption bugs to create reliable, practical paths to root access on widely deployed Linux distributions including Ubuntu, Amazon Linux, RHEL, and SUSE. Copy Fail has already been confirmed as exploited in the wild and added to CISA's Known Exploited Vulnerabilities (KEV) catalog, making rapid detection and response a priority for defenders everywhere.
What makes these vulnerabilities particularly dangerous is not just their severity, but their accessibility. Public proof-of-concept (PoC) code exists in Python, Go, Rust, C, and even Metasploit modules, meaning the barrier to exploitation is extremely low. This post breaks down how each vulnerability works, what makes them difficult to detect with naive approaches, and — most importantly — how defenders can build robust detection logic that outlasts any single PoC implementation.
Copy Fail: Corrupting Setuid Binaries in Memory
Copy Fail is a logic bug residing in the Linux kernel's authencesn cryptographic template. The attack chain leverages two kernel interfaces that individually appear harmless:
- AF_ALG — the kernel's userspace crypto API socket family
- splice() — a zero-copy data transfer syscall
By chaining these two primitives, an unprivileged attacker can perform a controlled 4-byte write into the page cache of any readable file on the system. In practice, this means corrupting the in-memory representation of a setuid binary such as /usr/bin/su — without ever touching the file on disk. The on-disk binary remains clean; only the kernel's cached copy is poisoned. The result is privilege escalation to root that leaves minimal forensic evidence and bypasses integrity checks that inspect file contents directly.
The public exploit is a compact 732-byte Python script. The simplicity and portability of this exploit underscore why defenders cannot rely on blocking a single PoC implementation — reimplementations are trivial.
DirtyFrag: Expanding the Attack Surface into the Network Stack
DirtyFrag takes the same bug class and extends it into the Linux networking stack, introducing two distinct exploitation paths:
The ESP Path (AF_NETLINK / XFRM)
This variant uses XFRM security associations via AF_NETLINK to perform in-place cryptographic operations on spliced pages. The attacker overwrites /usr/bin/su with a minimal root-shell ELF — again entirely in memory — before executing it to gain a root shell.
The RxRPC Fallback Path (AF_RXRPC)
When AF_ALG is unavailable, DirtyFrag falls back to AF_RXRPC with the pcbc(fcrypt) cipher to corrupt /etc/passwd, clearing root's password field and enabling direct su without credentials.
Both DirtyFrag paths require calling unshare(CLONE_NEWUSER | CLONE_NEWNET) to acquire namespace capabilities before triggering the page-cache write — a behavioral signal that becomes a key detection anchor.
Critical note for patch managers: DirtyFrag does not depend on the algif_aead module. Systems that applied only the Copy Fail mitigation by disabling that module remain fully exposed to DirtyFrag exploitation.
Why PoC-Matching Detection Fails
A naive detection strategy that pattern-matches against known exploit scripts is already obsolete. Copy Fail alone has at least five public reimplementations across different languages, and DirtyFrag ships as a C PoC. The moment defenders write a signature for one implementation, another surfaces. Effective detection must target the underlying syscall primitives and behavioral patterns that all implementations must use — not surface-level indicators like filenames or script hashes.
Detection Strategy: Syscall-Level Primitives with Auditd and EQL
Both Copy Fail and DirtyFrag share a common set of low-level syscall primitives that no reimplementation can avoid:
socket(AF_ALG)— hex value0x26in thea0argumentsocket(AF_RXRPC)— hex value0x21, used by DirtyFrag's fallback pathsplice()— called from a non-root process to inject pages into crypto buffers
These events, visible through auditd syscall auditing, can be correlated with a final privilege escalation step — a process gaining effective UID 0 from a non-root caller — using an EQL sequence rule with a 60-second maximum span. This sequence-based approach is robust: it catches the full exploit chain regardless of how the individual steps are implemented, and avoids false positives by requiring the privilege escalation outcome to follow the suspicious primitives.
Detection Strategy: Namespace Creation for DirtyFrag
DirtyFrag's reliance on unshare(CLONE_NEWUSER | CLONE_NEWNET) provides a highly specific detection signal. Legitimate software rarely calls unshare with both user and network namespace flags from a non-root context and then immediately spawns a root-owned process. An EQL sequence correlating the unshare event (matching argument bitmasks such as 0x10000000, 0x50000000, or 0x70000000) with a subsequent root process execution within a 30-second window — scoped to the same host, parent PID, and user — yields a tight, actionable alert with minimal noise.
Detection Strategy: Generic SUID Binary Abuse via Process Events
For environments where auditd syscall auditing is not enabled, a process execution-level detection covers the final stage of both exploits. The detection targets suspicious SUID binary executions characterized by all of the following:
- The process runs as effective UID 0
- The real user is non-root
- The parent process is also non-root
- The SUID binary (
su,sudo,pkexec,passwd,chsh,newgrp) is invoked with minimal arguments - The parent is a scripting runtime, interactive shell one-liner, or executable from a user-writable path
This behavioral fingerprint captures the essence of what these exploits do at their final stage without depending on any exploit-specific artifact.
Recommended Defensive Actions
- Patch immediately — apply kernel updates addressing CVE-2026-31431 and the DirtyFrag variants for your distribution.
- Do not rely solely on disabling algif_aead — this mitigates Copy Fail but leaves DirtyFrag's RxRPC path fully open.
- Enable auditd syscall auditing — specifically for
socket,splice, andunsharecalls from non-root processes. - Deploy EQL sequence rules — use the detection logic published by Elastic Security Labs to catch the full exploit chain in correlated context.
- Monitor SUID binary executions — even without syscall auditing, process-level telemetry can catch the final privilege escalation step.
Conclusion
Copy Fail and DirtyFrag represent a maturing class of Linux kernel exploits that weaponize legitimate kernel interfaces to corrupt memory in ways that are invisible on disk and difficult to attribute. The fact that Copy Fail is already in active exploitation — and that both vulnerabilities have accessible public PoCs across multiple languages — means the threat is immediate and broadly distributed, not limited to sophisticated nation-state actors.
The most durable defense is behavioral detection anchored to the syscall primitives and exploitation patterns that every implementation must use. By building detection logic around AF_ALG socket creation, splice abuse, namespace manipulation, and anomalous SUID escalation sequences, defenders can stay ahead of the inevitable wave of reimplementations and variants. Patch, audit, and hunt proactively — the exploit code is already in the wild.