Critical Flaw in Linux Kernel's AEAD Sockets: Arbitrary Page Cache Writes Expose Systems to Attack

From Tsd1588, the free encyclopedia of technology

Overview of the AEAD Sockets Vulnerability

In a significant disclosure, security analysis firm Xint has revealed a critical flaw in the Linux kernel that has persisted since 2017. The vulnerability enables an attacker to perform arbitrary 4-byte writes to the kernel's page cache, bypassing standard memory protections. This bug, which has been addressed in the latest mainline kernel releases, poses a serious risk to system integrity by potentially allowing privilege escalation or data corruption.

Critical Flaw in Linux Kernel's AEAD Sockets: Arbitrary Page Cache Writes Expose Systems to Attack
Source: lwn.net

How Splice Works: The Core Primitive

At the heart of this vulnerability lies the splice() system call, a powerful mechanism for high-performance data transfer between file descriptors and pipes. Unlike conventional read/write operations that copy data through user-space buffers, splice() transfers data by passing references to kernel page cache pages directly into pipe buffers. This zero-copy technique avoids unnecessary duplication, making it ideal for tasks like network file serving or inter-process communication.

When a user invokes splice() to move data from a file into a pipe and then into an AF_ALG socket (used for cryptographic operations like AEAD encryption), the socket's input scatterlist gains direct access to the kernel's cached pages of that file. Crucially, these are the exact same physical pages used by every read(), mmap(), or execve() call on that file. The pages are not copied; the scatterlist entries point at the original page frames, creating a shared, mutable reference to the file's cached data.

Exploitation: Corrupting Setuid Binaries

Xint's proof-of-concept (PoC) script demonstrates how to weaponize this bug. By requesting an AEAD-encrypted socket from user space and splicing a carefully crafted payload into it, an attacker can overwrite parts of a setuid binary file that is cached in memory. The arbitrary 4-byte writes allow modifying executable code or configuration data while it appears in the page cache. Since execve() reads directly from these same pages, a corrupted binary can execute under elevated privileges, granting the attacker root access or similar capabilities.

Importantly, the attack works across multiple Linux distributions, indicating that the bug is independent of vendor-specific patches or configurations. The PoC targets a setuid binary—a file that runs with the owner's permissions (often root)—making it a prime vector for privilege escalation.

Impact and Scope

The vulnerability affects all Linux kernels from version 4.12 (released in 2017) up to the point of the fix in mainline. Systems running these kernels and enabling AF_ALG sockets are potentially exposed. The scope is broad: any environment using cryptographic operations via AF_ALG—including cloud servers, embedded devices, and desktop systems—could be at risk if an attacker gains local access. The arbitrary 4-byte write capability, while limited in size, is sufficient to corrupt critical data structures, especially when combined with precise targeting of setuid binaries or key system files.

Beyond privilege escalation, an attacker might tamper with configuration files, database pages, or even the kernel's own data structures cached in the page cache, leading to denial of service or persistent system compromise.

Remediation and Patching

Xint disclosed the bug to the Linux kernel security team, and a fix has been integrated into the mainline kernel. Users and administrators are strongly advised to update their kernels to a version that includes the patch. The fix addresses the root cause by ensuring that pages spliced into AF_ALG sockets are properly duplicated or protected from being corrupted via write access originating from user space.

For systems that cannot be immediately patched, a possible workaround is to disable the AF_ALG socket family if it is not required. However, this may break legitimate cryptographic operations. Monitoring for unusual splice() calls or suspicious modifications to setuid binaries can also help detect exploitation attempts.

Lessons for Kernel Security

This vulnerability highlights the inherent risks of zero-copy data paths within the kernel. The splice() mechanism, while efficient, creates shared references to memory that must be carefully managed across different subsystems—here, between file I/O and cryptographic sockets. The bug underscores the need for rigorous validation of memory ownership and access permissions when transitioning data between kernel interfaces.

Moreover, the long lifetime of the flaw (since 2017) points to a gap in code auditing for interactions between seemingly unrelated kernel mechanisms. As Linux continues to power everything from smartphones to supercomputers, the security community must prioritize cross-subsystem fuzzing and static analysis to uncover similar vulnerabilities before they can be exploited.

For more technical details, refer to Xint's supplemental blog post on the discovery and remediation.