PinTheft: Deconstructing the io_uring and RDS Reference-Counting LPE Chain

Security researchers have unveiled a sophisticated new Proof-of-Concept (PoC) exploit dubbed “PinTheft,” which targets a critical vulnerability in the Linux kernel. This flaw allows a local attacker to bypass standard permission boundaries and escalate their privileges to full root access on specific system configurations.

At its technical core, PinTheft is a Local Privilege Escalation (LPE) exploit that weaponizes a reference-counting error within the Reliable Datagram Sockets (RDS) zerocopy send path. The exploit creatively transforms this bug into a page-cache overwrite by leveraging the advanced io_uring subsystem and its fixed-buffer mechanics.

The vulnerability originates in the kernel function rds_message_zcopy_from_user(). During the zerocopy process, the function pins user pages individually. However, if a page fault occurs later in the sequence, the kernel’s cleanup routine mishandles the remaining pinned pages, resulting in a “double-drop” of references. Essentially, each failed zerocopy attempt “steals” a reference from the initially pinned page, allowing an attacker to engineer a controlled reference count underflow.

Technical Breakdown of the PinTheft Attack Vector

The PinTheft exploit is a multi-stage chain that bridges the gap between a memory management error and arbitrary code execution. The workflow follows a precise sequence:

  1. Buffer Preparation: The attacker registers an anonymous page as a “fixed buffer” via io_uring. This action grants the page a significant reference bias (specifically, a FOLL_PIN value of 1024).
  2. Reference Exhaustion: By repeatedly triggering failing RDS zerocopy operations, the exploit systematically consumes those 1024 references. Crucially, io_uring still maintains a raw pointer to the underlying physical page.
  3. Page Cache Hijacking: Once the references are exhausted, the attacker cleans and reclaims that physical page. Through strategic memory pressure, they force the kernel to use this reclaimed page as the first page in the page cache for a SUID-root binary.
  4. The Overwrite: Using the stale io_uring fixed-buffer entry, the exploit overwrites the hijacked page cache with a malicious, embedded ELF payload. When the SUID binary is subsequently executed, the kernel runs the attacker’s payload with root privileges.
PinTheft Linux Vulnerability Diagram
PinTheft exploitation flow (Source: V12 research team)

Exploitation Prerequisites

For the exploit to succeed, several environmental conditions must be met:

  • The kernel must be compiled with CONFIG_RDS and CONFIG_RDS_TCP enabled.
  • io_uring must be active (io_uring_disabled=0).
  • The system must support the IORING_REGISTER_CLONE_BUFFERS API (the current PoC targets Kernel 6.13 and later).
  • The attacker requires a readable SUID-root binary on an x86_64 architecture.

Researchers have noted that Arch Linux is particularly vulnerable, as the RDS module is often enabled by default. While many other mainstream distributions do not expose these modules by default, the risk remains significant for specialized or custom-built kernels.

The vulnerability was discovered by the V12 security team, led by researcher Aaron Esau, using automated analysis tools. The team released the PoC immediately following the availability of a kernel patch.

Executing the PoC

The exploit code is hosted in the v12-security GitHub repository. On a vulnerable system, the exploitation process can be demonstrated via the following commands:

git clone https://github.com/v12-security/pocs.git && cd pocs/pintheft && gcc -o exp poc.c && ./exp

The PoC is designed to be highly automated; it scans for common targets like /usr/bin/su, /bin/su, /usr/bin/mount, /usr/bin/passwd, or /usr/bin/pkexec. It creates a backup of the target binary in /tmp/ before executing the overwrite and dropping the user into a root shell.

Mitigation and Defensive Strategies

To defend against PinTheft and similar page-cache-overwrite exploits, administrators should adopt a defense-in-depth approach:

1. Immediate Patching: The primary defense is to apply the upstream kernel patches provided by your Linux distribution as soon as they are released.

2. Module Hardening: If your environment does not require RDS functionality, disable the modules immediately. You can remove them from the current session using:

rmmod rds_tcp rds

To prevent them from being reloaded (even via module autoloading), create a modprobe configuration file:

printf 'install rds /bin/false\ninstall rds_tcp /bin/false\n' > /etc/modprobe.d/pintheft.conf

3. Surface Area Reduction: Security teams should audit the SUID-root binaries present on critical hosts. By following the principle of least privilege and reducing the SUID footprint, you can significantly limit the “target list” available to an attacker attempting to weaponize memory corruption bugs.

Related Articles

Back to top button