SecPod

Learn Search

Search across all Learn content

← Back to Security Research

CVE-2026-31431: Hardening Linux Against Copy Fail - Patching, Containment, and Defense-in-Depth

Jun 29, 2026
CVE-2026-31431 Copy Fail | Part 4 of 4 - Closing the Door
SecPod Labs | CVE-2026-31431 Copy Fail | Part 4 of 4

CVE-2026-31431 Copy Fail - Closing the Door: Patching, Mitigations, Hardening, and Vulnerability Chaining

May 2026 HIGH, CVSS 7.8 Remediation Guide Hardening Part 4 of 4 - Series Final

Parts 1 through 3 established what Copy Fail is, how it works mechanically, and how to detect it. Part 4 is the operational close: verified patch procedures for every affected distribution, the interim mitigation that requires no reboot for most environments, seccomp and AppArmor policy to harden the AF_ALG attack surface, Kubernetes-specific controls, vulnerability chaining risks with CVE-2026-43284 (Dirty Frag), and the long-term hardening principles that prevent the next Copy Fail from being equally severe.

Patch Required
Available Now
All major distros released patches within 72 hours of disclosure
Reboot Required to Patch
Yes
Kernel update requires reboot; KernelCare livepatch is rebootless
Interim Mitigation Available
Yes
algif_aead module blacklist closes the exploit path without rebooting
Mitigation Production Impact
Near Zero
algif_aead is not used by dm-crypt, LUKS, SSH, OpenSSL, or kTLS
Related CVE to Address
CVE-2026-43284
Dirty Frag - same algif_aead module, separate bug, separate patch

Remediation Priority Framework

Not every host in a fleet has the same exposure level. The following framework assigns remediation priority based on the combination of kernel patch status, host role, and network reachability. Apply patches in this order to reduce overall risk fastest.

Patch Immediately (P0)
Internet-facing Linux servers with local user access
Kubernetes worker nodes in multi-tenant clusters
CI/CD runners that execute untrusted or third-party code
Shared hosting and VPS environments
WSL2 hosts used by developers with access to sensitive credentials
Linux systems with domain or cloud credential access
Patch Within 48 Hours (P1)
Internal Linux servers with local user accounts
Kubernetes worker nodes in single-tenant clusters
Build servers and artifact repositories
Developer workstations running Linux natively
Database servers with local service accounts
Patch Within 1 Week (P2)
Isolated Linux appliances with no local user login
Air-gapped systems with physical access controls
Single-purpose embedded systems (verify vendor advisory first)
P2 does not mean low risk. Any system where a local code execution vulnerability can be reached - however indirectly - should be treated as P0 or P1. "Isolated" and "no local users" are operational claims that need to be verified against actual access paths, not assumed. Misclassifying a CI runner as a P2 system is how Copy Fail turns into a supply chain incident.

Per-Distribution Patch Verification

Applying the patch is step one. Verifying the patch is step two. The following procedures confirm the running kernel contains the fix for each major distribution. All commands should be run on the target host after the update and reboot cycle is complete.

Ubuntu

Ubuntu - Update, Reboot, and Verify Ubuntu / Debian
# Step 1: Apply all available security updates sudo apt update && sudo apt upgrade -y # Step 2: Reboot to activate the new kernel sudo reboot # Step 3: After reboot, verify the running kernel version uname -r Expected: 6.8.0-60-generic or later (Ubuntu 24.04) Expected: 5.15.0-130-generic or later (Ubuntu 22.04 LTS) # Step 4: Confirm the algif_aead module ships the patched version # The fix reverts commit 72548b093ee3 -- req->src and req->dst are now separate modinfo algif_aead | grep -E "filename|version" # Step 5: Verify no previous kmod blacklist entry conflicts with the patched module grep -r algif_aead /etc/modprobe.d/ If a blacklist entry is present from the interim mitigation, remove it after confirming the kernel itself is patched.

RHEL / AlmaLinux / Rocky Linux

RHEL Family - Update, Reboot, and Verify RHEL / AlmaLinux
# Step 1: Apply kernel security update sudo dnf update -y kernel kernel-core kernel-modules # Step 2: Verify the new kernel is staged for next boot sudo grubby --info DEFAULT | grep kernel Confirm the version matches the patched release in the vendor advisory # Step 3: Reboot sudo reboot # Step 4: After reboot, confirm running kernel uname -r rpm -q kernel --last | head -3 Verify the timestamp matches your update window # Step 5: Check for the specific CVE fix in the kernel changelog rpm -q --changelog kernel | grep -i "31431\|copy.fail\|algif_aead" | head -5

Amazon Linux 2023

Amazon Linux 2023 - Update and Verify Amazon Linux
# Step 1: Update kernel packages sudo yum update -y kernel # Step 2: Reboot the instance sudo reboot # Step 3: Verify kernel version post-reboot uname -r Check against the AL2023 security advisory for the minimum patched version # Step 4: For EC2 instances, verify from Systems Manager if direct access is unavailable aws ssm send-command \ --document-name "AWS-RunShellScript" \ --parameters 'commands=["uname -r"]' \ --targets "Key=tag:Env,Values=prod"

Windows WSL2

WSL2 Kernel - Verify and Update WSL2
# WSL2 kernel is updated through Windows Update (May 2026 Patch Tuesday) # Run these commands from inside the WSL2 environment # Step 1: Check current WSL2 kernel version uname -r Patched version: 5.15.167.4-microsoft-standard-WSL2 or later Any kernel dated before May 2026 Patch Tuesday is vulnerable # Step 2: If not yet patched, update from Windows (run in PowerShell as Admin) wsl --update wsl --shutdown # Restart WSL2, then re-check uname -r # Step 3: Verify the algif_aead module is the patched version modinfo algif_aead 2>/dev/null | grep filename

Interim Mitigation - algif_aead Module Blacklist

If kernel patching cannot be completed within the required window - due to change management cycles, maintenance windows, or operational constraints - the algif_aead module can be blacklisted to remove the exploit path entirely. This mitigation does not require a kernel update, but it does require a reboot to take effect (or alternatively, an immediate module unload if the module is not currently in use).

Compatibility Assessment Before Applying

The blacklist is safe for the vast majority of production environments because algif_aead is rarely used directly. Verify against your environment before applying:

Technology Uses algif_aead Impact of Blacklist
dm-crypt / LUKS disk encryption No None - dm-crypt uses its own kernel crypto API path, not AF_ALG
OpenSSL (default build) No None - default OpenSSL uses userspace crypto, not AF_ALG
GnuTLS (default build) No None - same as OpenSSL; AF_ALG backend is opt-in, not default
OpenSSH No None - SSH uses userspace crypto implementations
kTLS (kernel TLS) No None - kTLS uses tls.ko, not algif_aead
IPsec (strongSwan / Libreswan) No None - IPsec uses xfrm subsystem, not AF_ALG userspace sockets
WireGuard No None - WireGuard uses its own internal Zinc crypto library
Applications explicitly using AF_ALG AEAD sockets Yes AEAD operations via AF_ALG will fail - rare in production web or app stacks
How to check if anything in your environment uses algif_aead: Run lsmod | grep algif_aead. If the module is not loaded, nothing is currently using it. If it is loaded, check the "Used by" count in the output. A count of zero means it is loaded but idle. To confirm which processes have AF_ALG sockets open, run ss -a | grep AF_ALG or lsof | grep AF_ALG.

Applying the Blacklist

Method 1 - grubby (Recommended for RHEL Family) RHEL / AlmaLinux
# Append initcall_blacklist to kernel command line for all installed kernels # This prevents algif_aead from initializing at boot time sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init" # Verify the argument was added to the default kernel entry sudo grubby --info DEFAULT | grep args # Reboot to activate sudo reboot # After reboot: confirm the module did not load lsmod | grep algif_aead Expected: no output (module not loaded) cat /proc/cmdline | grep initcall_blacklist Expected: initcall_blacklist=algif_aead_init in the output
Method 2 - kmod blacklist file (Ubuntu / Debian) Ubuntu / Debian
# Create a modprobe blacklist entry for algif_aead echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/copyfail-mitigation.conf # Prevent the module from being loaded even if requested as a dependency echo "install algif_aead /bin/false" | sudo tee -a /etc/modprobe.d/copyfail-mitigation.conf # Rebuild initramfs to embed the blacklist (required for it to take effect at boot) sudo update-initramfs -u -k all # Reboot sudo reboot # After reboot: verify module is blocked lsmod | grep algif_aead Expected: no output sudo modprobe algif_aead Expected: modprobe: ERROR: could not insert 'algif_aead': Operation not permitted
Method 3 - Immediate Unload (No Reboot, If Module Is Currently Idle) Emergency / All Distros
# Check if the module is loaded and if anything is using it lsmod | grep algif_aead Column 3 shows "Used by" count. Must be 0 to safely unload. # If Used by count is 0, unload immediately (no reboot required) sudo rmmod algif_aead # Confirm it is gone from the running kernel lsmod | grep algif_aead Expected: no output # IMPORTANT: still apply the persistent blacklist above # rmmod does not survive a reboot -- the module will reload at next boot # unless a modprobe blacklist or initcall_blacklist entry is in place

Reverting the Mitigation After Patching

Remove Blacklist After Kernel Is Patched Cleanup
# After confirming the patched kernel is running (uname -r shows patched version) # remove the blacklist to restore normal algif_aead availability # For grubby-based mitigation (RHEL family) sudo grubby --update-kernel=ALL --remove-args="initcall_blacklist=algif_aead_init" sudo reboot # For kmod-based mitigation (Ubuntu/Debian) sudo rm /etc/modprobe.d/copyfail-mitigation.conf sudo update-initramfs -u -k all sudo reboot # Verify algif_aead is available again after reboot sudo modprobe algif_aead lsmod | grep algif_aead Expected: algif_aead listed with size and dependency information

Long-Term Hardening - Restricting the AF_ALG Attack Surface

Patching removes CVE-2026-31431 specifically. Restricting the AF_ALG interface for workloads that do not need it removes the entire attack surface class. If a future vulnerability in algif_aead, algif_hash, algif_skcipher, or any other AF_ALG module is discovered, these controls will mitigate it without requiring an emergency patch cycle.

seccomp Profile - Block AF_ALG Socket Creation

A seccomp profile that restricts socket() calls with AF_ALG (family 38) prevents any process running under that profile from opening an AF_ALG socket, regardless of kernel patch status. This is the most robust long-term control.

seccomp Profile - Deny AF_ALG socket() for Container Workloads seccomp JSON
// seccomp profile fragment: deny socket(AF_ALG, ...) for untrusted workloads // Add to your existing container seccomp profile or use as a standalone profile // Compatible with Docker, containerd, Podman, and Kubernetes SecurityContext { "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["socket"], "action": "SCMP_ACT_ERRNO", "errnoRet": 1, "args": [ { "index": 0, "value": 38, "op": "SCMP_CMP_EQ" } ], "comment": "Block AF_ALG socket creation (CVE-2026-31431 and future algif_* bugs)" } ] }
Applying the seccomp Profile in Docker Docker
# Save the profile above as /etc/docker/seccomp-deny-afalg.json # Apply it when running containers docker run --security-opt seccomp=/etc/docker/seccomp-deny-afalg.json your-image:tag # Verify the block is active from inside the container python3 -c "import socket; socket.socket(38, 5, 0)" Expected: [Errno 1] Operation not permitted

AppArmor Profile - Deny AF_ALG for Specific Applications

AppArmor Profile Snippet - Deny network af_alg AppArmor
# Add to any AppArmor profile for an application that should not use AF_ALG # The "deny network af_alg," rule blocks socket(AF_ALG, ...) for the profiled process profile your-application /path/to/binary { # ... existing rules ... # Deny AF_ALG socket creation to remove Copy Fail and future algif_* attack surface deny network af_alg, # ... remaining rules ... } # Reload the profile after modification sudo apparmor_parser -r /etc/apparmor.d/your-application # Verify the profile is enforced sudo aa-status | grep your-application Expected: your-application (enforce)

Kubernetes SecurityContext - Per-Pod and Cluster-Wide Controls

Pod SecurityContext - Apply seccomp Profile Kubernetes YAML
# Apply the AF_ALG-blocking seccomp profile at the pod level # First, place the profile on all nodes at the expected path # /var/lib/kubelet/seccomp/deny-afalg.json apiVersion: v1 kind: Pod metadata: name: hardened-workload annotations: # Legacy annotation method (Kubernetes < 1.19) seccomp.security.alpha.kubernetes.io/pod: "localhost/deny-afalg.json" spec: securityContext: # Modern seccompProfile field (Kubernetes >= 1.19) seccompProfile: type: Localhost localhostProfile: "deny-afalg.json" containers: - name: app image: your-image:tag securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true capabilities: drop: ["ALL"]
Cluster-Wide Enforcement via Kyverno Policy Kyverno
# Kyverno ClusterPolicy: require seccomp profile on all pods # Blocks any pod that does not specify a seccomp profile (which would use the default) apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-seccomp-profile spec: validationFailureAction: enforce background: false rules: - name: check-seccomp match: any: - resources: kinds: [Pod] validate: message: "Pods must specify a seccomp profile. RuntimeDefault or Localhost required." pattern: spec: securityContext: seccompProfile: type: "RuntimeDefault | Localhost"
RuntimeDefault vs Localhost: The RuntimeDefault seccomp profile is provided by the container runtime (containerd or CRI-O) and blocks a broad set of dangerous syscalls including socket(AF_ALG, ...) in most configurations. However, do not assume it blocks AF_ALG in all runtime versions - test with a probe before relying on it. The Localhost profile with an explicit AF_ALG-blocking rule is the verified path.

Vulnerability Chaining - CVE-2026-43284 (Dirty Frag)

Copy Fail was not the only vulnerability discovered in the algif_aead module during the security audit its disclosure triggered. CVE-2026-43284, disclosed in late May 2026 and nicknamed Dirty Frag, is a separate bug in the same kernel subsystem. Understanding how they relate affects patch prioritization and hardening scope.

CVE-2026-31431 (Copy Fail)
authencesn scratch write via merged scatterlist

Root cause: the 2017 optimization commit collapsing req->src and req->dst into a single scatterlist, allowing the authencesn algorithm to write into the page cache via its scratch write path. Fixed by commit a664bf3d603d which restores separate src/dst scatterlists.

CVE-2026-43284 (Dirty Frag)
Fragmented scatterlist handling in algif_aead recvmsg

Root cause: a separate memory handling error in algif_aead's recvmsg path when processing fragmented scatterlists. The bug allows a different class of page cache modification under specific conditions. Separate patch required - the Copy Fail fix does not cover Dirty Frag.

CVE-2026-31431 (Copy Fail) CVE-2026-43284 (Dirty Frag)
Affected module algif_aead algif_aead
Vulnerable function algif_aead_sendmsg (via authencesn scratch) algif_aead_recvmsg (fragmented scatterlist)
Root cause commit 72548b093ee3 (2017) Separate commit in recvmsg path
Fix commit a664bf3d603d Separate patch (check vendor advisory)
Same patch covers both No - separate patches required No - separate patches required
algif_aead blacklist covers both Yes Yes - blacklisting the module removes both exploit paths
Two CVEs, two patches: Patching Copy Fail alone does not patch Dirty Frag. If your environment applied the Copy Fail kernel update and considered the algif_aead module fully remediated, verify separately that the Dirty Frag patch is also included in your running kernel. Check your vendor's advisory for CVE-2026-43284 specifically. The algif_aead blacklist mitigation covers both during the interim period.

Chaining Copy Fail with Application Vulnerabilities

Copy Fail requires a local foothold - an existing shell or code execution as an unprivileged user. This makes it the second stage in an attack chain, not a standalone remote exploit. The vulnerabilities it chains with most effectively are those that grant initial code execution on a shared Linux host:

Chain Type 1
Web Application RCE → Root

An RCE vulnerability in a web application (deserialization, SSTI, command injection) provides a shell as www-data or another service account. Copy Fail immediately escalates that shell to root. The application-level vulnerability that seemed low-severity in isolation becomes a full server compromise.

Chain Type 2
Malicious Dependency → Root

A malicious npm, pip, or gem package executes arbitrary code during installation or at runtime. If the host kernel is unpatched, the package payload can include the Copy Fail script and immediately escalate to root in the same process. Dependency confusion and typosquatting attacks become LPE vehicles.

Chain Type 3
Compromised SSH Credential → Root

A stolen or brute-forced SSH credential provides initial unprivileged shell access. Copy Fail converts that access to root in under five seconds, before any analyst reviewing the authentication log has had time to respond to the initial login alert.

Risk Assessment - Final Scoring

The following assessment synthesizes the full picture from all four parts of this series into a final operational risk score that accounts for factors the CVSS base score does not capture.

Risk Factor Assessment Influence on Operational Risk
CVSS 3.1 Base Score 7.8 High Baseline. Local attack vector limits the theoretical maximum score.
Exploit maturity Weaponized, public, day-zero A deterministic public exploit released simultaneously with disclosure eliminates the triage window. Risk multiplier: very high.
CISA KEV listing Confirmed active exploitation Not a theoretical risk. Real attacks have occurred within 48 hours of disclosure.
Cross-distro portability Universal (all major Linux distros) An attacker does not need to know the target distribution. The same exploit works everywhere. Reduces operational expertise required by threat actors.
Stealth characteristics In-memory only, FIM-invisible Standard file-integrity monitoring and most EDR file-watching controls are blind. Detection requires behavioral monitoring, which is less universally deployed.
Exposure years before disclosure ~9 years Maximum possible silent exploitation window. Cannot rule out prior knowledge or exploitation by sophisticated actors before public disclosure.
Blast radius in cloud and container environments Node-level and cluster-wide Kubernetes environments can translate one compromised pod into a compromised cluster node and credential access to all co-located pods.
Patch availability Full patch available All major distributions have released patched kernels. Risk reduces significantly with patching. Interim mitigation closes the attack surface immediately.
Overall operational risk Critical CVSS 7.8 significantly understates the true risk when exploit maturity, cross-distro universality, stealth, and cloud blast radius are factored in.

Remediation Action Plan - Consolidated Checklist

Immediate (Within 2 Hours)
Stop the bleeding

Deploy auditd rules for AF_ALG socket detection on all Linux hosts. Identify P0 hosts. Apply the algif_aead interim mitigation on any host that cannot be rebooted for a kernel update within 24 hours. Alert on any existing AF_ALG activity in logs going back 30 days.

Short-Term (Within 48 Hours)
Apply the patch

Complete kernel patching across P0 and P1 hosts with reboot. Verify patch with uname -r and vendor changelog confirmation. Update Kubernetes node images to patched versions and recycle nodes. Apply the May 2026 Windows Patch Tuesday update to all WSL2 hosts. Remove interim mitigations after patch confirmation.

Long-Term (Within 1 Month)
Close the attack surface class

Deploy seccomp profiles blocking AF_ALG socket creation for all container workloads that do not explicitly require it. Implement Kyverno or OPA policies requiring seccomp profiles on all pods cluster-wide. Enable kernel live patching for critical infrastructure to reduce future LPE patch lag. Patch CVE-2026-43284 (Dirty Frag) separately.

Series Summary - What Copy Fail Taught Us

CVE-2026-31431 is a case study in how vulnerability risk diverges from CVSS scoring when exploit maturity, stealth properties, and environmental blast radius are considered together. A CVSS 7.8 that requires local access sounds manageable. A deterministic, 732-byte, cross-distro Python script that was publicly available before most defenders had finished reading the disclosure, confirmed in active exploitation within 48 hours, and invisible to every file-integrity monitoring tool deployed across the Linux ecosystem is something qualitatively different.

The nine-year exposure window reflects a deeper truth about kernel security: subtle behavioral dependencies between optimization commits and algorithm implementations are exactly the class of issue that standard review processes miss. The right response is not just patching this specific bug - it is treating the AF_ALG subsystem as an attack surface that requires behavioral monitoring, seccomp restriction for untrusted workloads, and proactive audit coverage.

The four controls that matter most coming out of this series: patch the kernel, deploy auditd rules for AF_ALG socket detection, apply seccomp profiles blocking family 38 for container workloads, and enable live patching for production Linux infrastructure so the next kernel LPE does not require a maintenance window to remediate.


Complete Series

Part 1
Nine Years in the Dark
Root cause commit, AF_ALG socket mechanics, page cache corruption, FIM blindness, affected distributions
Part 2
The 732-Byte Root
Complete syscall chain, page cache write mechanics, container escape, Kubernetes blast radius, WSL2, active exploitation timeline
Part 3
Finding the Footprint
auditd rules, eBPF monitoring, Wazuh SIEM correlation, YARA memory strings, IOC taxonomy, MITRE ATT&CK mapping
Part 4 - This Article
Closing the Door
Per-distro patching, algif_aead blacklist, seccomp and AppArmor hardening, Kubernetes controls, CVE-2026-43284 chaining, risk assessment
SecPod Technologies CVE-2026-31431 Research Series  |  Published May 2026 Series Complete - Parts 1 through 4

Featured Posts

Open FortiBleed: The Leak That Turned 73,000 Firewalls Into a Targeting Database
FortiBleed: The Leak That Turned 73,000 Firewalls Into a Targeting Database

CVE Research

FortiBleed: The Leak That Turned 73,000 Firewalls Into a Targeting Database

FortiBleed is a credential-exposure campaign targeting Fortinet firewalls, with over 86,000 devices compromised across 194 countries. No patch exists – attackers crack stolen password hashes and turn devices into listening posts for credential theft.

Jun 25, 2026

Open CVE-2026-31431: From 732 Bytes to Root - Anatomy of a Modern Linux Privilege Escalation

CVE-2026-31431: From 732 Bytes to Root - Anatomy of a Modern Linux Privilege Escalation

CVE Research

CVE-2026-31431: From 732 Bytes to Root - Anatomy of a Modern Linux Privilege Escalation

Jun 24, 2026

Open CVE-2026-31431: The Nine-Year Kernel Bug Hiding in Plain Sight

CVE-2026-31431: The Nine-Year Kernel Bug Hiding in Plain Sight

CVE Research

CVE-2026-31431: The Nine-Year Kernel Bug Hiding in Plain Sight

Jun 23, 2026

Open Squidbleed: A 29-Year-Old Squid Proxy Flaw That Leaks Cleartext HTTP Requests
Squidbleed: A 29-Year-Old Squid Proxy Flaw That Leaks Cleartext HTTP Requests

CVE Research

Squidbleed: A 29-Year-Old Squid Proxy Flaw That Leaks Cleartext HTTP Requests

Jun 23, 2026