Copy Fail (CVE-2026-31431): Four Bytes That Quietly Steal the Root Throne
Copy Fail is a Linux kernel vulnerability that allows an ordinary user—without any write permission on a file—to temporarily tamper with that file's contents in memory, then leverage the corruption to achieve arbitrary code execution and obtain root privileges. The disk file is never modified; only its cached representation in the page cache is poisoned.
Background: File Permissions vs. the Page Cache
Linux file permissions normally prevent unprivileged users from writing to sensitive files or setuid binaries. For performance, however, the kernel caches frequently accessed file contents in memory as the page cache. Programs often operate on this in-memory copy rather than re-reading from disk. If the cached copy is altered while the disk original stays intact, everything a process actually executes comes from the corrupted cache—this is the core trick of Copy Fail.
The Five Building Blocks of the Attack
1. setuid trust — setuid programs run with the file owner's privileges (typically root), e.g., passwd writing to /etc/shadow. The system trusts these binaries because users cannot modify the on-disk file.
2. splice() zero-copy — splice() attaches page cache pages directly to pipe buffers (pipe_buffer holds only a reference to a struct page, no data copy), bypassing the kernel-to-user copy that read() performs.
3. AF_ALG — a socket address family that lets userspace hand data to the kernel's crypto subsystem. Copy Fail targets its AEAD (Authenticated Encryption with Associated Data) interface.
4. algif_aead in-place optimization — a 2017 performance change lets input and output share the same buffer, assuming the caller's buffer is writable. Buffers arriving via splice() point at read-only page cache pages, but the module does not distinguish their origin.
5. authencesn write — the authencesn AEAD template (authenc + extended sequence number, used in IPsec ESP) writes a 4-byte (32-bit) sequence number at an offset derived from the associated-data and ciphertext lengths. With in-place handling, this write lands on the page cache page itself—and it occurs before the authentication tag is verified, so the cache is corrupted even when the kernel returns EBADMSG.
The Full Attack Chain
1. Pick a readable but non-writable file, e.g., a setuid binary.
2. Use splice() to attach portions of the file to a pipe—the pipe references the page cache pages directly.
3. Feed the pipe data into AF_ALG as AEAD input.
4. algif_aead processes it in-place; authencesn writes the 4-byte sequence number into what it believes is the output buffer—actually the page cache.
5. Repeat at chosen offsets to patch the cached image of the setuid binary.
6. Execute the setuid program: the disk file and its permissions are untouched, but the kernel runs the poisoned cached version—granting root.
The entire exploit modifies no files on disk and changes no permissions—purely in-memory.
Mitigation
- Apply the kernel patch: the fix removes the in-place logic in
algif_aead, separating input and output buffers so the read-only page cache is respected. - Interim mitigation: restrict or disable the AF_ALG interface / related crypto modules if patching is not immediately possible.
Takeaway
Copy Fail is a reminder that every performance optimization must be security-reviewed: zero-copy references, in-place processing, and implicit writability assumptions combined to dissolve the boundary between an unprivileged user and root—over just four bytes.
------
References
1. Linux kernel documentation on the splice() zero-copy mechanism.
2. AF_ALG socket interface and the kernel AEAD crypto framework.
3. authencesn template implementation analysis (2017 kernel optimization change).
4. Security-boundary research on the setuid privilege model.
5. Page cache and pipe_buffer reference mechanics; Copy Fail / CVE-2026-31431 kernel patch notes.