Here we go again.
Every few years, the Linux kernel produces a new catchy-named privilege escalation with a dedicated website, a logo, and the same familiar summary: unprivileged local user, root on every major distribution, sitting in the code for years. Dirty Cow in 2016. Dirty Pipe in 2022. Now Copy Fail in 2026. They all target the page cache. They all exploit the intersection of features that each looked reasonable in isolation. And they’re all exactly as bad as they sound.
CVE-2026-31431 is real, it has been patched, and if you’re running any Linux kernel from 2017 through last week’s update, you’re affected. Let me walk through what actually happened and why this one feels a little different.
What happened
The bug lives in the authencesn AEAD template in the Linux kernel’s crypto subsystem. authencesn is an IPsec implementation detail - it handles authentication with extended sequence numbers per RFC 4303. It has existed since 2011. For most systems, nothing ever calls it directly.
The problem isn’t authencesn alone. The problem is what happened when three independent features converged over fifteen years.
In 2015, the kernel’s AF_ALG interface - which exposes the crypto subsystem to unprivileged userspace via sockets - gained AEAD support, including a splice() path that lets you feed page cache pages directly into the crypto engine.
In 2017, a performance optimization made AEAD operations in-place in algif_aead. Instead of copying data into separate source and destination buffers, the kernel chained page cache pages directly into the writable destination scatterlist.
The Theori researchers describe it plainly in their writeup: “Nobody connected the 2017 in-place optimization to authencesn’s scratch writes or to the splice path’s use of page cache pages.” Each change was isolated and reasonable. The vulnerability lived at their convergence.
The result: an unprivileged user opens an AF_ALG socket bound to authencesn, constructs sendmsg() plus splice() pairs that position page cache pages at the right offsets, triggers AEAD decryption - and the kernel writes four controlled bytes into the cached memory of any readable file on the system. Including setuid binaries like /usr/bin/su. The on-disk file is untouched. The page cache version is compromised immediately, system-wide, and every process reading that file now sees the attacker’s version.
The resulting exploit is 732 bytes of Python 3. Standard library only. No race condition, 100% reliable, across Ubuntu 24.04, Amazon Linux 2023, RHEL 10.1, and SUSE 16, on every kernel version since the 2017 optimization.
How it was found
This is the part of the story I want to stay with for a moment.
Theori researcher Taeyang Lee identified AF_ALG plus splice() as an underexplored attack surface - the idea that userspace could feed page cache pages into the crypto engine, where the kernel might do something unexpected with them, felt worth investigating. He built that intuition into Xint Code, an automated security analysis tool, and pointed it at the kernel’s crypto/ subsystem. The scan took approximately one hour. Copy Fail was the highest-severity finding.
The HN thread picked up on this immediately. If a one-hour automated scan of a single subsystem surfaces a critical privilege escalation that has been sitting in production kernels for nine years, the uncomfortable implication is that there are probably more of these. The Xint team says explicitly that the same scan surfaced other high-severity bugs still in coordinated disclosure.
I don’t know what those look like yet. But this is not a one-time finding - it’s a change in the cost of finding this class of vulnerability.
Who is actually exposed
The severity breakdown from the researchers works like this.
High risk: multi-tenant systems where users share a kernel. Kubernetes clusters running workloads from multiple tenants, CI/CD runners executing pull requests from outside contributors, SaaS platforms running untrusted workloads in containers. If your isolation boundary is namespaces and cgroups, a compromised container can become root on the host. The HN discussion noted at least one tester found rootless Podman and user namespaces did confine the exploit - so the container escape picture is more nuanced than the initial headlines suggested. Full container escape details are forthcoming from the Theori team.
Medium risk: single-tenant production servers. This is not a remote exploit by itself. An attacker needs local access first. But once they have it, privilege escalation is deterministic and fast. It chains cleanly with any other vector that gets an attacker a local foothold.
Lower risk: isolated single-user or single-tenant systems where an attacker already has local access. Still bad. Just not a cross-tenant incident.
MicroVM-based isolation - Firecracker, gVisor - is unaffected because each workload gets its own kernel. The exploit requires reaching the host kernel. If you can’t, the blast radius is contained to your own workload.
The disclosure gap
There is a part of the story worth separating out, because it changes the exposure picture considerably.
When Theori published on April 29, three kernel versions had the fix backported: 6.18.22, 6.19.12, and 7.0. Five of the seven actively supported long-term stable branches - 6.12, 6.6, 6.1, 5.15, and 5.10 - did not. The exploit was public. The PoC was 732 bytes of Python. The kernels that most production infrastructure actually runs on were still unpatched.
This happened because the Linux kernel project has no formal process for notifying distribution maintainers when a security-critical patch lands. The linux-distros mailing list exists precisely for this kind of coordination - it gives Debian, Red Hat, SUSE, Gentoo, and others advance notice before a vulnerability goes public, so they can have backports and packages ready. But using it requires the researcher to opt in. As Sam James from Gentoo wrote on oss-security the day after disclosure: “Linux kernel vulnerabilities, unless the reporter chooses to bring it to the linux-distros ML, there is no heads-up to distributions. It did not happen here.”
The patch commit message compounded the problem. It reads: “There is no benefit in operating in-place in algif_aead since the source and destination come from different mappings.” A performance observation. Nothing about privilege escalation, page cache writes, or exploitability. A distribution maintainer scanning the kernel changelog for security-relevant changes had no signal to act on. The only way to know this patch mattered was to already know what it was fixing.
The result: a working root exploit dropped into a world where five of seven LTS kernels were still vulnerable, and the people responsible for backporting those fixes hadn’t been specifically told there was something to backport. The subsequent HN discussion named it plainly - for kernel vulnerabilities, the default is no distribution notification unless the researcher makes it happen.
What to do
Update your kernel. The mainline fix is commit a664bf3d603d. Kernel versions 6.18.22, 6.19.12, and 7.0 included the fix at the time of public disclosure. If you’re running an LTS kernel - 6.12, 6.6, 6.1, 5.15, or 5.10 - verify that your distribution has shipped a backport before assuming you’re covered. The fact that the patch exists in mainline does not mean it has reached your kernel version.
If you need an interim mitigation before you can patch:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true
The practical impact of disabling algif_aead is minimal for most systems. dm-crypt, LUKS, IPsec, kTLS, OpenSSL, and SSH are all unaffected by this module. The only workloads that require AF_ALG directly are systems using OpenSSL’s afalg engine or custom embedded crypto offload - rare configurations. As the HN thread observed, real-world AF_ALG usage is essentially limited to iwd and non-default cryptsetup configurations.
One note for RHEL and derivatives: some modules are compiled in rather than loadable, so rmmod may fail. In that case, kernel update is the only path.
The pattern
Dirty Cow was a race condition in the copy-on-write mechanism. Dirty Pipe was an uninitialized flags field in a pipe buffer structure that let an attacker overwrite arbitrary read-only files. Copy Fail is a scatterlist aliasing bug triggered through the crypto API. All three are page-cache write primitives. All three lived in the kernel for years - Dirty Cow for nine years before disclosure, Dirty Pipe for about two, Copy Fail for nine. All three, in retrospect, feel like the kind of thing a sufficiently focused review might have caught.
The kernel is enormous. The crypto/ subsystem alone is complex enough that the security community is openly questioning whether AF_ALG should exist at all - it adds significant attack surface for an interface that almost nobody uses. That’s a fair critique, but it also applies to a lot of kernel surface. You cannot retroactively un-expose an interface that has been default-enabled for a decade.
The lesson isn’t that Linux is uniquely bad at security. Large, general-purpose codebases accumulate feature intersections that nobody modeled when each piece was introduced. That’s a property of complexity, not of malice. The people who wrote authencesn, who added AF_ALG AEAD support, and who introduced the 2017 in-place optimization were all doing reasonable things with reasonable intent.
What these vulnerabilities keep surfacing is a structural question about where isolation boundaries live. Shared-kernel infrastructure - anything where multiple tenants share a single kernel - inherits every kernel vulnerability as a potential cross-tenant incident. That’s not a criticism of any specific provider. It’s a property of the architecture.
The fix is a kernel patch. The longer-term question is what your exposure window looks like between the moment a vulnerability is discovered and the moment a patch reaches your fleet. For shared-kernel environments, that window is the window where a “local privilege escalation” is actually a cross-tenant incident waiting to happen.
Patch your kernels. It’s the right move regardless of anything else.
Here we go… again.
I want to explain this one with an analogy, because the technical details can obscure what is actually a pretty simple problem once you see it. And I think this analogy will stick with you.
Picture a law firm. A big one - hundreds of employees across several floors. Like any large organization, they have a central infrastructure team whose job is to keep the operation running: security, access control, document authentication. The kind of back-office function most employees don’t think about, but that everything depends on.
There are three things you need to picture clearly before we go any further.
First: the service desk. This is where formal verification work happens. When an employee needs a document certified, an identity confirmed, or a credential validated, they bring it to the desk. Specialists process the work there. In our case, the service desk is the Linux kernel’s cryptography subsystem - a shared facility that any program running on your computer can send requests to.
Second: the archive room. It’s locked, and only the desk specialists can enter. This is where the firm’s most sensitive records live - documents that define what every employee is authorized to do. In kernel terms, this is the operating system’s working memory, where it holds active copies of the most sensitive files on the system, including the programs that can run with full administrator privileges on behalf of any user.
Third: the work surface - a large shared table at the service desk. When specialists need to reference archive documents while processing a request, they bring them out and lay them on this table. In memory terms, this is the address space where processing happens. The table is shared. It sits between the public counter and the archive door.
Everything about this setup is normal. Now here’s where it starts to unravel.
How it broke
The first change, in 2015. Up until this point, only other specialists could submit work to the service desk. The firm opens it up. Any employee with building access can now walk up to the counter and have their documents processed. In real terms, the kernel gained an interface that let ordinary user programs - anyone logged in, no special permissions - send data to the crypto engine. It was designed so developers could use the kernel’s encryption infrastructure for their own legitimate work.
The second change, in 2017. The firm makes a process efficiency call. Previously, when specialists referenced archive documents during processing, they made a photocopy to annotate, keeping the originals untouched. New management decides this is wasteful. From now on, specialists work directly on documents as they’re laid out on the shared table. In kernel terms, a performance optimization made the crypto engine process data in-place. Instead of copying data into a separate working buffer, it operated directly in the original memory location.
Neither change, on its own, is a problem.
What nobody modeled was what they produce together. If an employee submits a specific type of request - one that causes the specialists to do their work on the shared table at exactly the same time archive documents are laid out there - the processing leaves marks on whatever is on that surface. Before 2017, it was the photocopy. After 2017, it’s the original. In real terms: send the right request to the crypto interface, and the kernel writes a few controlled bytes directly into the in-memory copy of a protected file. The file on disk is untouched. But the version the operating system is actually running? That’s yours to modify.
The archive room is still locked. The specialists are doing their jobs correctly. No security rule is visibly being broken. But an employee who knows the right way to structure their submission can alter records they were never authorized to touch. They never enter the archive. They just fill out the right paperwork and slide it across the counter.
That’s Copy Fail. CVE-2026-31431. The service desk has been running this way since 2017. Nine years. 732 bytes of Python. No race condition. 100% reliable. Works on every major operating system distribution.
How it was found
This is the part that gave me pause.
A security researcher named Taeyang Lee had a straightforward question: what happens if you submit a type of request to the service desk that the specialists haven’t fully accounted for? He built that question into an automated scanning tool called Xint Code and pointed it at the right part of the kernel. The scan ran for approximately one hour. Copy Fail was the top result.
One hour.
The same tool surfaced other high-severity vulnerabilities still in coordinated disclosure. We don’t know what those are yet. But the implication is uncomfortable: if one hour of scanning one area of the kernel finds something sitting there for nine years, there are probably other service desks with the same work surface problem.
This isn’t a one-time discovery. It’s a change in what it costs to find this class of vulnerability.
Who has the most immediate problem
It depends on how many firms share the building.
If you’re running infrastructure where multiple organizations share the same kernel - Kubernetes clusters, CI/CD platforms handling outside contributors, container environments with multiple customers - your exposure is highest. One employee from one firm uses this to gain access to the building manager’s office. From there, they reach the archive rooms for every other firm in the building. In practical terms: a process in one container becoming root on the host, with access to every other tenant’s data.
Single-tenant production servers are a real but lower risk. You still need someone to already be in the building - this isn’t a remote attack on its own. But once they’re inside, the path to the archive is fast and works every time.
The good news: some infrastructure models give every firm its own completely separate building. Technologies like Firecracker and gVisor run each workload on its own isolated kernel. No shared service desk. No shared work surface. The archive can’t be reached from another firm’s counter.
What to do
The service desk has been redesigned.
Update and reboot. The fix changes how the crypto subsystem handles memory during processing so archive documents can no longer end up on the shared work surface. If you’re running a newer kernel version (6.18 or later), the fix arrived promptly. If you’re running a long-term stable version - the kind most production infrastructure runs on - check that your distribution has specifically shipped the backport. Not all branches had it when the announcement dropped.
If you need a short-term measure while you schedule the maintenance window, there’s a configuration change that closes the public counter to employee submissions entirely. Almost nobody in real-world production actually needs this particular interface. The practical impact of closing it is minimal.
One note for Red Hat users: the relevant component may be built directly into the kernel rather than as a separately loadable piece, so the short-term workaround may not apply. In that case, the kernel update is the only path.
What nobody told the branch offices
I left something out of this story the first time, and I should correct it.
When the announcement went public on April 29, the service desk at the head office had been fixed. The new work surface was safe. But five of the seven branch offices - the ones running older, stable versions of the firm’s operating procedures - still had the broken setup. The exploit was public. The branches were unpatched. And nobody had told them to prioritize this particular repair.
This is not a metaphor. The Linux kernel project has no formal process for notifying distribution maintainers when a security-critical patch lands. There is a mailing list that exists for exactly this purpose - where researchers coordinate with Debian, Red Hat, SUSE, and others before going public, so packages can be ready when the announcement drops. But opting in to that list is the researcher’s choice, not a requirement. As Sam James from Gentoo wrote the day after disclosure:
Linux kernel vulnerabilities, unless the reporter chooses to bring it to the linux-distros ML, there is no heads-up to distributions. It did not happen here.
The maintenance note posted on the internal bulletin board said the service desk had been adjusted “for efficiency.” No mention of the archive room. No mention of the employee who had been sliding the wrong paperwork across it. A branch office manager scanning the maintenance log had no signal to act on.
So when the public map to the archive room was released, five branch offices were still running the old desk. The head office was fixed. The branches had to figure it out from the public announcement, after the fact.
This matters because most production infrastructure runs on the stable, long-term versions of the firm’s protocols - not the latest head-office edition. The disclosure window isn’t just the time between vulnerability disclosure and your next maintenance window. It’s also the time between when the upstream fix lands and when anyone actually tells you something critical has changed.
The pattern I can’t stop thinking about
Dirty Cow in 2016. Dirty Pipe in 2022. Copy Fail in 2026. Three different vulnerabilities, all in the same area of the kernel, all discovered over a ten-year span. All three were ways an attacker could write into memory that was supposed to be protected - different routes into the archive room, via different shared work surfaces. All three sat in production kernels for years before anyone noticed. In each case, the individual decisions made sense. Nobody was doing anything wrong. The problem lived at the intersection.
The lesson isn’t that Linux is uniquely bad at this. Large systems accumulate intersections. The specialist who redesigned the work surface process in 2017 wasn’t thinking about the public counter policy from 2015. The archive room predated both of them. Three people, each doing their jobs well, nobody comparing notes.
What these vulnerabilities keep surfacing is a structural question about shared infrastructure. When multiple tenants share the same kernel, every kernel vulnerability becomes a potential cross-tenant incident. That’s not a criticism of any specific provider. It’s a property of the architecture.
The gap between “someone knows how to fill out the paperwork” and “the service desk has been fixed” is the gap where a privilege escalation is actually a cross-tenant incident waiting to happen.
The service desk has been fixed. Patch your kernels.