Blog

Root Without a Password: How PinTheft Turns io_uring Into a Kernel Takeover Tool.

PinTheft
Uncategorized

Root Without a Password: How PinTheft Turns io_uring Into a Kernel Takeover Tool.

The server is locked down tight. Nginx behind Cloudflare, fail2ban banning bots, root SSH login disabled, every port except 22, 80, and 443 blocked by nftables. Then someone gets an unprivileged shell — through a vulnerable plugin, a weak password, whatever. They run a script. A few seconds later — root.

Welcome to PinTheft.

WHAT HAPPENED

On May 21, 2026, SecurityLab published details of a Linux kernel vulnerability named PinTheft. It was discovered by team V12 — in the RDS (Reliable Datagram Sockets) subsystem, responsible for reliable datagram delivery, primarily in intra-cluster communication.

The PoC exploit is already on GitHub. No CVE identifier has been assigned. The kernel team published a patch on May 5th — meaning the window between the patch and the public exploit was two weeks. If you have not updated your kernel in that time, you are in the risk group.

HOW IT WORKS

A double-free error was found in the zerocopy mechanism of the RDS subsystem: the same memory page is freed twice. Zerocopy is a method of transferring data between the kernel and applications without physically copying it — instead, references to memory pages are passed directly. Fast and efficient, which is exactly what makes this dangerous. On its own the bug is bad, but not catastrophic. The catastrophe starts with io_uring.

io_uring is the asynchronous I/O interface in the Linux kernel, introduced in version 5.1. It allows applications to submit queues of operations to the kernel with minimal overhead. This is the mechanism used in the attack: the attacker constructs a series of io_uring requests that land at the moment of the double-free and begin stealing references to kernel memory pages — pin stealing. By gradually accumulating control over memory pages, the attacker gains the ability to execute arbitrary code with kernel privileges. The result: root without a password.

Requirements for a successful attack:
— rds module is loaded
— io_uring is enabled
— any SUID binary exists (sudo, pkexec — any will do)
— architecture is x86_64
— local access to the system

WHO IS AFFECTED

Among popular distributions, rds loads by default only in Arch Linux — so that is where the primary impact lands. But this does not mean Debian, Ubuntu, and RHEL are safe: if rds is loaded for any reason — for instance because an application requested the corresponding socket type — the system is vulnerable.

One command to check:

lsmod | grep rds

If there is output — rds is loaded. With the other conditions in place, the system is at risk.

HOW SERIOUS IS THIS

For a typical VPS or dedicated server — medium severity. Here is why.

Mitigating factors:
— requires local access, not remotely exploitable
— on Ubuntu/Debian/RHEL rds is not loaded by default
— requires a specific combination of conditions simultaneously

What makes it serious:
— PoC is public, zero barrier to entry
— if the attacker already has an unprivileged shell (through a vulnerable WordPress plugin, for example) — this is a direct path to root
— no CVE means automated scanners cannot see it

Where it is genuinely dangerous:
— shared hosting with multiple users on one machine
— VPS with panels like cPanel/Plesk where clients have shell access
— CI/CD systems running code from repositories
— development servers with multiple SSH users

Where the risk is minimal:
— a single VPS with one administrator and no outside users: to use PinTheft, the attacker must first get onto the server — and that is already a separate problem

In short: not a catastrophe on its own, but paired with any web application vulnerability it becomes the final step of an attack chain.

WHAT TO DO RIGHT NOW

Step 1. Unload rds and block it permanently:

sudo modprobe -r rds

echo "install rds /bin/false" | sudo tee /etc/modprobe.d/disable-rds.conf
echo "blacklist rds" | sudo tee -a /etc/modprobe.d/disable-rds.conf

# Debian/Ubuntu — rebuild initramfs, otherwise the block will not survive a reboot
sudo update-initramfs -u

# RHEL/Fedora
sudo dracut -f

Why two rules instead of one: blacklist prevents automatic module loading, but the module can still be loaded manually via modprobe rds or pulled in as a dependency of another module. install rds /bin/false intercepts any loading attempt — including indirect ones — and instead of the module runs /bin/false, which exits immediately with an error. Together they close both paths.

Why initramfs rebuild is required: modprobe.d rules are read during system boot from the initramfs image. Without rebuilding it, the new rules never make it into the image, and after a reboot the system loads the old initramfs without the block in place.

Step 2. Restrict io_uring (caution — may break PostgreSQL 16+ and some container runtimes):

First check the current state:

cat /proc/sys/kernel/io_uring_disabled
# 0 = enabled for everyone
# 1 = disabled for unprivileged users
# 2 = fully disabled

For mitigation you need at minimum =1. Value =2 completely removes the attack vector but breaks anything using io_uring — including PostgreSQL 16+. If unsure, use =1: it blocks the attack vector (the attack requires an unprivileged user) with less risk to running services:

sudo sysctl -w kernel.io_uring_disabled=1
echo "kernel.io_uring_disabled=1" | sudo tee /etc/sysctl.d/99-io-uring.conf

Step 3. Update the kernel and reboot:

# Debian/Ubuntu
sudo apt update && sudo apt upgrade linux-image-generic

# RHEL/Fedora
sudo dnf update kernel

After reboot — confirm rds is no longer loading:

lsmod | grep rds
# Empty output — good

CONTEXT: THE 2026 WAVE

PinTheft is not an isolated incident. Throughout 2026, researchers have been systematically publishing vulnerabilities in the zerocopy and io_uring subsystems of the Linux kernel: DirtyDecrypt, DirtyCBC, Dirty Frag, Fragnesia, Copy Fail. This area of the kernel is under active scrutiny.

Follow [email protected] and your distribution’s security advisories. Many of these vulnerabilities appear there before they receive a CVE identifier — exactly as happened with PinTheft.

Leave your thought here

Your email address will not be published. Required fields are marked *