Deltadga

Linux Kernel AEAD Socket Bug: A Detailed Q&A on the Page Cache Vulnerability

Linux kernel bug from 2017 allows 4-byte writes to page cache via AEAD sockets and splice(). Fixed; PoC corrupts setuid binaries.

Deltadga · 2026-05-02 04:42:10 · Cybersecurity

In 2028, security researchers at Xint disclosed a critical vulnerability in the Linux kernel that had lurked since 2017. The flaw allows an attacker to perform arbitrary 4-byte writes to the page cache by abusing AEAD-encrypted sockets in combination with the splice() system call. This Q&A breaks down the bug, its exploitation, and its fix.

What exactly is the AEAD socket security bug in the Linux kernel?

The bug resides in how the Linux kernel handles Authenticated Encryption with Associated Data (AEAD) sockets when used with the splice() system call. AEAD sockets, part of the AF_ALG family, are designed for cryptographic operations. The vulnerability allows a local attacker to write four bytes of arbitrary data into the kernel's page cache. Because the page cache is shared by all processes reading from or mapping files, corrupting it can alter file content—including executables—without the kernel noticing. The write occurs when user space requests an AEAD-encrypted socket and then splices a carefully crafted payload into it. The kernel's input scatterlist ends up pointing directly to the pages in the page cache, and the AEAD operation can modify those pages in-place. This bypasses normal copy-on-write protections and enables persistent data corruption.

Linux Kernel AEAD Socket Bug: A Detailed Q&A on the Page Cache Vulnerability
Source: lwn.net

How does the splice() system call contribute to this vulnerability?

splice() is a zero-copy mechanism that transfers data between file descriptors and pipes without copying data between kernel and user space. It moves page cache references directly into a pipe's buffer. When a file is spliced into a pipe and then that pipe is spliced into an AF_ALG socket, the socket's internal scatterlist holds direct references to the kernel's cached pages of the original file. These pages are not duplicated—they are the same physical pages that back every read(), mmap(), and execve() of that file. Thus, any write through the AEAD socket's cryptographic operation directly modifies the page cache, affecting all subsequent accesses to that file. The design assumption that splice() is safe for read‑only operations is violated when combined with AEAD sockets that perform in‑place encryption or decryption.

What is the potential impact of this bug on system security?

The impact is severe because the attacker can corrupt any file that is cached in the page cache, including system binaries. By targeting a setuid binary (e.g., /usr/bin/su), an attacker can replace a few bytes of the executable with malicious code, elevating privileges to root. The write is only four bytes, but that is enough to change instructions, bypass checks, or corrupt metadata. Since the page cache is shared, the corruption persists until the page is evicted or the system is rebooted. Any process that subsequently accesses the corrupted file—including execve() for a setuid binary—will load the tampered content. This makes it a powerful privilege escalation vector on multi‑user systems, containers, or even desktop environments. The bug affects all Linux distributions running kernels between 2017 and the 2028 fix.

When was this bug introduced, and how long was it present?

The vulnerability was introduced in the Linux kernel in 2017, likely as part of changes to the AF_ALG subsystem or the splice() implementation. It remained undetected for over a decade until security firm Xint discovered and disclosed it in 2028. The bug exists in all mainline kernel versions from its introduction until the fix was applied. This means millions of devices—including servers, desktop systems, and IoT devices—were at risk. The long incubation period underscores the complexity of auditing zero‑copy paths and cryptographic interfaces. Researchers noted that the bug was not obvious because the combination of splice() and AEAD sockets is rarely used together in production environments. The disclosure came with a proof‑of‑concept that demonstrated reliable exploitation on multiple distributions.

How was the vulnerability fixed?

The Linux kernel maintainers applied a fix to the mainline kernel as soon as the bug was reported. The patch likely prevents the AEAD socket operation from writing directly to page cache pages by ensuring that pages are copied or that write permissions are properly gated. One approach could be to use copy‑on‑write for pages that enter an AF_ALG scatterlist, or to invalidate the page cache entries after encryption. The exact patch details are available in the supplemental blog post referenced by Xint. Users are strongly advised to update to a kernel version containing the fix. Distributions have backported the fix to their stable releases. The fix does not disable AEAD sockets or splice(), but closes the specific hole where a user‑controlled payload can corrupt the page cache through the cryptographic operation.

Is there a proof-of-concept exploit for this bug?

Yes, Xint released a proof‑of‑concept (PoC) script alongside the disclosure. The PoC demonstrates how to corrupt a setuid binary on multiple Linux distributions by constructing a special payload that is spliced into an AEAD socket. The exploit works by first locating a target file (e.g., an executable with the setuid bit set), then using splice() to bring its page cache pages into an AEAD socket's scatterlist. The AEAD operation—typically encryption or decryption—modifies those pages directly. By carefully choosing the plaintext and the cryptographic parameters, the attacker can write exactly four bytes of arbitrary data into the file's page cache. The PoC shows that the corruption is persistent and can be used to gain root privileges. It is a strong demonstration of the real‑world risk, and Xint's supplemental blog post provides a deeper technical analysis.

How does the page cache become corrupted through this flaw?

The page cache stores kernel's cached copies of files on disk. When a file is spliced into a pipe, the pipe's buffer holds references to the physical pages backing that file, not copies. These references are then passed to an AF_ALG socket via another splice() call. The socket's AEAD operation (encrypt or decrypt) processes the data in place using the scatterlist. Because the scatterlist points to the original page cache pages, any modification during encryption or decryption overwrites the cached file content. Normal file access paths like read() or execve() read from these same pages, so the corrupted content is instantly visible. If the file is later flushed to disk, the corruption becomes permanent. The bug is that the kernel does not ensure that pages entering an AEAD socket are writable only to the socket's temporary buffer; instead, it permits direct manipulation of shared, cached pages.

Recommended