
Copy Fail (CVE-2026-31431): A Universal Linux Privilege Escalation Vulnerability
Executive Summary

Copy Fail (CVE-2026-31431) is a Linux local privilege escalation vulnerability where an unprivileged process can modify privileged file content in memory (via the page cache) and then leverage that change to execute code as root.
At its core, Copy Fail turns a single kernel logic flaw into a reliable page-cache write primitive, collapsing the gap between local access and root.
What makes it matter in real environments isn’t just “root on a box.” It’s the combination of:
- Cross-distro reliability (a common kernel interface, not an app-specific bug)
- No race-condition dependence (predictable exploitation paths)
- Memory-only modification (fewer traditional forensic artifacts)
If you run multi-user Linux systems, shared runners, container hosts, or CI/CD build agents, this is the class of kernel bug that turns “low privilege” into “full control” fast.
Public reporting also suggests why defenders should treat this as high urgency: exploitation can be compact and repeatable, with minimal per-host tuning compared to the “race-condition era” of kernel LPEs.
Note: This write-up focuses on technical clarity and defensive impact. It intentionally avoids exploit code and step-by-step weaponization.
Attack Flow (one diagram, no fluff) 📌
This is the chain defenders should keep in their heads:
unprivileged process
│
├─► AF_ALG (algif_aead) socket setup
│
├─► splice() data movement (kernel-side)
│
├─► page cache overwrite (file-backed pages)
│
├─► execute privileged target (e.g., setuid-root)
│
└─► root code execution
Technical Overview (root cause, simplified)
At a high level, Copy Fail is a kernel data integrity failure involving four building blocks:
AF_ALG/algif_aead: a Linux kernel crypto API interface exposed via sockets, used to perform cryptographic operations from user space.splice(2): a zero-copy data transfer mechanism that can move data between file descriptors inside the kernel.- Page cache: the in-memory cache of file-backed pages used for performance.
- Write-protection expectations: even if a file is read-only (or owned by root), user space shouldn’t be able to alter its file-backed cached pages.
The simple mental model 🧠
Normally:
- A read-only, root-owned binary on disk is immutable to an unprivileged user.
- The page cache mirrors that file’s content in memory.
- The kernel ensures you can’t “trick” it into writing into those cached pages unless you have legitimate write permissions.
Copy Fail breaks that expectation.
What goes wrong (conceptually)
The vulnerability is triggered by a particular interaction between AF_ALG (specifically the algif_aead path) and splice, resulting in a situation where data can be copied into file-backed cached pages without going through the normal write permission checks.
Once an attacker can influence the page cache for a privileged file, they don’t need to persist changes to disk to get impact. They only need:
- A privileged executable page-cached in memory, and
- A way to execute it while the modified pages are still present.
That’s why this is often described as “memory-only”: the on-disk file may remain unchanged, while the kernel executes a modified in-memory view.
Exploitation Primitive (why this works so well) 🎯
Here’s the technical punchline security engineers look for:
At its core, Copy Fail exposes a deterministic, repeatable 4-byte write primitive into the Linux file-backed page cache (often described as a 4-byte arbitrary write).
That matters because a small, reliable primitive is exactly what turns an interesting kernel bug into an operationally useful privilege escalation:
- Deterministic: you’re not “winning a race,” you’re applying a broken invariant.
- Repeatable: the primitive can be invoked multiple times to shape memory state.
- High leverage: page cache targets are executable file pages, not just anonymous memory.
I’m intentionally not detailing payload construction here, but from an attacker mindset this is why weaponization tends to be straightforward: small writes + repeatability + privileged execution target = a clean escalation path.
Exploitation Flow (high-level, defender-friendly)
Below is the exploitation chain in plain, operational terms. This is the sequence defenders should understand and threat-model against.
Prepare kernel primitives
- The attacker opens an
AF_ALGsocket configured for an AEAD algorithm (viaalgif_aead).
- The attacker opens an
Create a controlled copy path
- Using
splice, the attacker moves data through kernel-managed buffers in a way that triggers the vulnerable copy behavior.
- Using
Target a privileged file-backed page
- The attacker references a root-owned executable that is commonly present and executable on most systems (often a setuid-root binary) and ensures its pages are faulted into the page cache.
Modify the page cache, not the disk
- The vulnerable path allows the attacker’s bytes to land in the cached page(s) backing that privileged file.
Execute the privileged code path
- The attacker runs the target binary. The kernel executes the modified in-memory pages, resulting in code execution with elevated privileges.
Clean-up and persist (optional)
- Because the modification is memory-only, a reboot or cache eviction can remove the evidence. Attackers may still establish persistence after gaining root (that part is a separate problem).
The key point: this is not “exotic crypto.” AF_ALG is just the entry point; the exploit’s power comes from violating the invariants around the page cache and permission boundaries.
Why This Vulnerability Is Dangerous
1) Cross-distro reliability ✅
This isn’t a bug in a specific package manager, SSH daemon, or container runtime. It lives in kernel plumbing that is broadly shared.
That tends to mean:
- Similar behavior across major distros
- Similar success rates across cloud images
- Similar blast radius on shared hosts
2) No race condition (predictable exploitation) 🎯
A lot of kernel privilege escalations are hard to operationalize because they depend on timing.
Copy Fail is dangerous because it can be exploited as a controlled, deterministic chain: you’re not “winning a race,” you’re abusing a broken invariant.
3) Memory-only modification (weak disk forensics) 🕵️
Many orgs still rely heavily on disk artifacts:
- file hashes
- package integrity tools
- “was anything modified on disk?” checks
Copy Fail can undermine that mental model. If the on-disk file isn’t changed, classic integrity checks may show “everything looks fine,” even while a privileged binary was temporarily modified in memory.
Real-World Impact
CI/CD pipelines and shared runners 🧱
This is a portfolio-relevant risk because modern CI systems often run untrusted or semi-trusted code:
- forks / external PRs
- third-party build steps
- supply-chain scripts
A local kernel LPE turns a build job into:
- runner compromise
- secret theft (signing keys, cloud tokens)
- lateral movement into artifact stores or deployment systems
A concrete scenario I’ve seen teams underestimate:
- A malicious pull request runs on a shared runner.
- It leverages Copy Fail to escalate to root on the runner host.
- It extracts CI secrets (OIDC tokens, cloud creds, signing keys) and pivots into deployment systems.
The technical details vary by environment, but the pattern is consistent: kernel LPEs convert “build isolation” into “infrastructure compromise.”
Kubernetes and containers 🧬
Containers don’t “fix” kernel bugs. If an attacker can execute code in a container and the host kernel is vulnerable, the question becomes:
- Is the container blocked from creating
AF_ALGsockets? - Are syscalls like
splicerestricted by seccomp? - Does the workload have access patterns that make privileged host binaries reachable/executable?
Even when container escape is not trivial, the node is the security boundary. Kernel LPEs are exactly how that boundary fails.
Multi-user systems and bastions 👥
On shared hosts (jump boxes, research servers, dev boxes), a single compromised user account can become root.
For organizations, that’s not just a host issue—it’s an identity and access issue:
- a stolen developer SSH key becomes root
- a mis-scoped service account becomes root
Detection Challenges
Why traditional tools struggle
- No on-disk modification required: file integrity monitoring may not fire.
- Short-lived changes: the “modified” state may exist only for seconds.
- Looks like normal syscalls:
socket,splice,execveare legitimate primitives.
Practical signals defenders can monitor 🔍
If you operate Linux fleets at scale, focus on behavioral detection:
- Unexpected
AF_ALGusage in environments that don’t need it- e.g., build agents, web servers, app nodes
modprobe/ module load events foraf_alg/algif_aead- especially on minimal images where crypto sockets are uncommon
- Process sequences that combine:
socket(AF_ALG, ...)→splice(...)→ execution of privileged binaries
- Container syscall telemetry (where available)
- eBPF-based sensors can catch unusual syscall mixes per workload
This isn’t about one “magic signature.” It’s about spotting rare kernel API usage that correlates strongly with exploitation chains.
Mitigation & Defense
1) Patch (the real fix) 🩹
Patch the kernel as soon as vendor updates are available for your distro and kernel line. For this class of issue, “we’ll patch next quarter” is not a great strategy.
In practice:
- Patch hosts first (especially CI runners, Kubernetes nodes, bastions)
- Then patch developer endpoints and any shared environments
2) Temporary mitigations (risk reduction)
If you need short-term containment while patching:
Disable or blacklist the relevant kernel modules (environment-dependent)
- Common approaches include blacklisting
af_algand/oralgif_aead - Trade-off: may break legitimate crypto consumers
- Common approaches include blacklisting
Restrict
AF_ALGsocket creation- In containers: ensure your seccomp profile blocks
socket(AF_ALG, ...)if not required - On hosts: consider LSM policies (AppArmor/SELinux) to reduce reachability
- In containers: ensure your seccomp profile blocks
Harden high-risk environments
- Treat CI runners and Kubernetes nodes as hostile-by-default
- Reduce the likelihood that untrusted code executes on privileged kernels
3) Defensive best practices (still matter)
Even though this is a kernel bug, the impact is shaped by your operational posture:
- Keep runners ephemeral; rotate secrets aggressively
- Use least-privilege identities for CI/CD and cluster components
- Separate untrusted workloads from sensitive infrastructure
- Monitor for unusual kernel-module activity and syscall patterns
Key Takeaways (fast scan) ✅
- Copy Fail is a Linux kernel LPE that enables root via page-cache modification.
- The core risk is the reliable page-cache write primitive that can be chained into privileged execution.
- It’s dangerous because it’s reliable, cross-distro, and can be memory-only.
- CI runners and Kubernetes nodes are high-value targets because they execute untrusted code.
- Traditional file integrity monitoring may miss it; prioritize syscall and behavior telemetry.
- Patch quickly; use module and seccomp restrictions to reduce exposure during rollout.
Personal Insight: what Copy Fail says about modern security
Copy Fail is a good example of a bigger shift I’ve been seeing in Linux exploitation.
Older kernel LPEs often felt like probabilistic engineering: timing, heap grooming, races, and “try until it lands.” You could understand the bug and still struggle to weaponize it reliably.
Bugs in the Dirty Pipe family (and now Copy Fail) feel different. They’re closer to reliable primitives than “lucky wins.” And I think that’s the real trend:
We’re moving from probabilistic exploitation to deterministic, repeatable primitives.
That shift changes how we should talk about risk in modern environments:
- “Local execution” is no longer a low-severity event in CI/CD and containerized fleets.
- The boundary that matters is often the node/kernel, not the container.
- When a kernel interface yields a reliable primitive, the time from initial access → root can be very short.
My opinionated takeaway: treat kernel patching, syscall surface reduction (seccomp), and workload isolation as first-class security controls—not just ops hygiene.
The uncomfortable line is the one defenders need to internalize:
In modern environments, “local execution” is often one syscall chain away from root.