
Analyzes CVE-2026-31431, a Linux kernel AF_ALG AEAD vulnerability, providing a safe detector, in-lab LPE exploit, and QEMU-based A/B kernel lab for verification.
algif_aead "Copy Fail": AnalysisSecurity research on CVE-2026-31431 (CVSS 3.1 7.8 HIGH,
AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H): three composable design
flaws in the AF_ALG AEAD interface chain into a deterministic,
race-free 4-byte page-cache write at any offset of any readable
file — the disk copy stays clean, so on-disk checksums see nothing.
The public exploit ("Copy Fail", Theori/Xint) turns it into local
root (LPE) with 732 bytes of Python; the bug sat in every kernel
from 2017 to 2026.
72548b093ee3 (2017) made _aead_recvmsg decrypt in-place,
chaining the request's tag pages into the writable destination SGL.splice(file → pipe → socket) feeds those tag slots the
page-cache pages of any readable file (zero copy).authencesn writes its 4-byte ESN scratch — the value rides in
AAD[4..8) of the sendmsg payload — exactly at
, i.e. the first tag byte: your chosen
file offset. It fires tag verification, so even a
request performs the write.dst[assoclen + cryptlen]-EBADMSG| Claim | Evidence |
|---|---|
| Root cause derived from the fix commits and kernel sources, not from blogs | finding-sheet |
| Public PoC decode verified end-to-end against the syscall sequence | finding-sheet |
| Lab A/B kernels with delta = exactly the fix commit, both boot | lab/scripts/build.sh + lab/out/ab-diffstat.txt |
Vuln kernel executes authencesn AEAD decrypt via AF_ALG (smoke) | lab/scripts/run.sh vuln → SMOKE=ok |
Revert-without-companion panics in crypto_authenc_esn_decrypt (original finding) | lab/scripts/run.sh patched → NULL deref, reproducible |
| Safe detector: VULNERABLE on vuln (write fires despite EBADMSG, disk stays CLEAN), NOT-DETECTED on full-fix | poc/detector.c in the lab → DETECTOR-RESULT lines |
| In-lab LPE closure: uid 1000 patches 4 page-cache bytes of a SUID binary and reads the root-only flag; disk copy proven pristine via block-level debugfs read | poc/lpe.c + lab/rootfs/tools/secretgate.c → LPE-RESULT: ROOT-FLAG-CAPTURED, DISKCLEAN=ok |
| Reproduce the public page-cache write in a pinned lab, with attribution | detector output above + lab README |
| SGL stress: 5 shapes on both kernels — no crash, no kernel hang (honest negative) + two documented AF_ALG contract quirks | poc/sgl-stress.c in the lab → SGL-STRESS lines |
# build the three kernels + tools + probe disk in Docker (~15 min first run)
lab/scripts/build.sh
# boot the A/B/C oracle (QEMU in Docker, KVM if available)
lab/scripts/run.sh vuln # DETECTOR VULNERABLE + LPE ROOT-FLAG-CAPTURED + DISKCLEAN=ok
lab/scripts/run.sh patchedfull # DETECTOR NOT-DETECTED + LPE NOT-VULNERABLE
lab/scripts/run.sh patched # authencesn NULL deref (companion-fix gap)
The completed page-cache-write chain follows the published approach of
Theori / Xint Code ("Copy Fail", the credited reporters) with
attribution — see the finding-sheet prior-art
section. Original work in this repo: the fix-commit-anchored mechanics
map, the incomplete-fix-series finding (the revert-without-companion
authencesn panic and its stable-release window), the safe
page-cache-vs-disk differential detector that never touches files we
do not own, the in-lab LPE closure against a purpose-built SUID target
(secretgate — no real-world binary is ever targeted), the SGL edge
exploration (honest negative result plus two documented AF_ALG
contract quirks), and the verified branch attribution of all eight fix
commits.
| Doc | What it is |
|---|---|
| docs/finding-sheet.md | One-page datasheet: versions, CVSS, root cause, fix commits, attack surface |
| docs/report-ptes.md | PTES-structured report (7 phases) with lab evidence |
| docs/research-writeup.md | The investigation narrative — methodology, dead ends, portable lessons, prior-work comparison |
docs/ finding sheet · PTES report · research writeup
poc/ detector.c (safe oracle) · lpe.c (in-lab LPE) · sgl-stress.c (SGL exploration)
lab/ QEMU kernel lab: 5.15.203 ± fix (A/B) + post-companion 5.15.y (C)
lab/rootfs/ secretgate.c — purpose-built SUID target (the only thing ever attacked)
72548b093ee3 "crypto: algif_aead - copy AAD from src to dst" (2017)a664bf3d603d "crypto: algif_aead - Revert to operating out-of-place"
(+ 8 stable backports — see finding-sheet)Educational research artifact. Run only against systems you own or are explicitly authorized to test. The vulnerability is patched — run an up-to-date kernel from 2026 stable branches or later.