Linux Copy Fail CVE-2026-31431: KEV Privilege Escalation on Shared Build Hosts
CISA added Linux kernel CVE-2026-31431 to KEV on 2026-05-01. Theori's Copy Fail research ties the bug to AF_ALG AEAD in-place operation and shows why shared CI runners, Kubernetes nodes, and multi-tenant Linux hosts need kernel patch proof or AF_ALG mitigation.
On this page 0% read
Executive Summary
CISA added CVE-2026-31431 to KEV on 2026-05-01 with a due date of 2026-05-15 CISA KEV. CISA describes it as a Linux kernel incorrect resource transfer vulnerability that can allow privilege escalation CISA KEV.
Theori’s Copy Fail research explains the root cause in the Linux crypto subsystem: an AF_ALG AEAD in-place optimization could place page-cache pages into a writable scatterlist, enabling an unprivileged write primitive against read-only file mappings under the right conditions Theori. The upstream fix is commit a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5, which removes the in-place behavior in algif_aead Linux commit.
Key Facts
Cve: CVE-2026-31431
Product: Linux kernel
Kev Added: 2026-05-01
Kev Due: 2026-05-15
Cwe: CWE-669
Component: AF_ALG AEAD / algif_aead
Fix Commit: a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5
Introducing Commit Reference: 72548b093ee3
Impact:
- local privilege escalation
- shared CI runner escalation
- Kubernetes node and container boundary risk where kernel exposure exists
Temporary Mitigation:
- patch the distribution kernel
- block AF_ALG socket creation through sandbox policy where feasible
- disable algif_aead module where operationally safe
Evidence Assessment
- confirmed: CISA KEV lists CVE-2026-31431 as known exploited CISA KEV.
- confirmed: Linux CVE announcement identifies the issue and points operators at stable Linux update guidance Linux CVE announcement.
- confirmed: Theori’s Copy Fail post explains the AF_ALG, splice, scatterlist, and page-cache primitive and lists the coordinated disclosure timeline Theori.
- confirmed: The upstream Linux fix commit removes the AEAD in-place operation path Linux commit.
- confirmed: NVD tracks CVE-2026-31431 with the same affected product and references NVD.
- unknown: Public sources reviewed here do not provide a reliable exploitation victim list or a universal affected-version matrix for every distribution kernel backport.
Impact Determination
| Classification | Criteria | Required evidence | Handling decision |
|---|---|---|---|
| Confirmed compromise | Local exploit execution, suspicious AF_ALG AEAD use, unexpected setuid/root file changes, or container-to-host escalation evidence appears on a vulnerable kernel. | Process, syscall, EDR, auditd, file integrity, package, and kernel version evidence. | Isolate the host, preserve volatile evidence, rebuild from trusted media if root compromise is plausible. |
| Presumed exposed | Shared Linux host, CI runner, Kubernetes node, or developer box has untrusted local code execution and lacks patched-kernel proof. | Kernel package version, distro advisory, workload schedule, runner logs, and user/container access records. | Patch or cordon/rebuild the host; rotate credentials available to jobs or containers on the node. |
| Potentially exposed | Linux assets exist but kernel build, AF_ALG exposure, or untrusted-code execution path is incomplete. | Asset inventory, package manager output, kernel config, module status, seccomp profile, workload mapping. | Collect kernel and workload evidence before narrowing scope. |
| Not exposed | Patched kernel or vendor backport is proven and no vulnerable local execution window exists. | Distro advisory match, package changelog, booted kernel version, and negative workload review. | Preserve closure evidence. |
| Unknown | Kernel package, booted kernel, workload placement, or audit telemetry is unavailable. | Named telemetry gap with owner and retention window. | Keep shared hosts and credentials in scope until evidence is recovered. |
Timeline
- 2026-03-23: Theori reports the vulnerability to the Linux kernel security team Theori.
- 2026-04-01: Theori’s timeline records mainline patch commit activity Theori.
- 2026-04-22: Linux CVE announcement for CVE-2026-31431 is published Linux CVE announcement.
- 2026-05-01: CISA adds CVE-2026-31431 to KEV CISA KEV.
- 2026-06-01: This Halting Problems refresh found no existing local post for CVE-2026-31431 or Copy Fail.
Technical Analysis
Copy Fail matters for supply-chain and CI/CD response because local privilege escalation on shared build hosts can turn a compromised project, malicious package install, or untrusted pull-request job into host-level control. The vulnerable surface involves AF_ALG AEAD and splice() interactions with page-cache-backed scatterlists Theori. A runner that executes attacker-controlled build scripts and shares a kernel with secrets, caches, sibling jobs, or Kubernetes node credentials should be treated as high-value. [1]
The upstream fix commit states that there is no benefit in operating in-place in algif_aead because source and destination come from different mappings, and it changes the request setup to use out-of-place operation Linux commit. For defenders, patched distribution kernel evidence is more useful than raw upstream version comparison because vendors backport security fixes. [1]
Detection and Hunting
Hunt Manifest: linux-copy-fail-cve-2026-31431-kev-hunt-1
- Title: local repository and exported telemetry scope
- Question: Does the telemetry scope contain patterns associated with Linux Copy Fail CVE-2026-31431: KEV Privilege Escalation on Shared Build Hosts?
- Telemetry Family: file
- Telemetry Context: host filesystem or log export
- Positive Signal: Indicators of compromise matched in telemetry: local repository and exported telemetry scope
#!/usr/bin/env python3
import os
import sys
from pathlib import Path
ROOT = sys.argv[1] if len(sys.argv) > 1 else "."
LOG_ROOT = os.environ.get("LOG_ROOT", "")
OUT = Path(os.environ.get("OUT", "hp-linux-copy-fail-cve-2026-31431-kev-scope"))
DOMAINS = ["www.cisa.gov","xint.io","github.com","lore.kernel.org","nvd.nist.gov"]
URLS = ["https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json","https://xint.io/blog/copy-fail-linux-distributions","https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5","https://lore.kernel.org/linux-cve-announce/2026042214-CVE-2026-31431-3d65@gregkh/","https://nvd.nist.gov/vuln/detail/CVE-2026-31431"]
HASHES = ["a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5"]
# Collect unique indicators
indicators = set()
for group in [DOMAINS, URLS, HASHES]:
for val in group:
if val:
indicators.add(val)
with open(indicators_file, "w") as f:
for ind in sorted(indicators):
f.write(ind + "\n")
print(f"[+] Written unique selectors to {indicators_file}")
# Walk local directory
print(f"[+] Scanning directory: {ROOT} for selectors...")
matches = []
exclude_dirs = {"node_modules", "vendor", "dist", ".git"}
for root, dirs, filenames in os.walk(ROOT):
dirs[:] = [d for d in dirs if d not in exclude_dirs]
for filename in filenames:
filepath = Path(root) / filename
try:
content = filepath.read_text(errors="ignore")
for ind in indicators:
if ind in content:
matches.append(f"{filepath}: found '{ind}'")
except Exception:
pass # pass # return or raise not needed here # pass # return or raise not needed here
if matches:
(OUT / "repository-indicator-matches.txt").write_text("\n".join(matches) + "\n")
print(f"[!] Found {len(matches)} matches in codebase!")
# Optional Log Scanning
if LOG_ROOT and os.path.exists(LOG_ROOT):
print(f"[+] Scanning telemetry log directory: {LOG_ROOT}...")
log_matches = []
for root, _, filenames in os.walk(LOG_ROOT):
for filename in filenames:
filepath = Path(root) / filename
try:
content = filepath.read_text(errors="ignore")
for ind in indicators:
if ind in content:
log_matches.append(f"{filepath}: found '{ind}'")
except Exception:
pass # pass # return or raise not needed here # pass # return or raise not needed here
if log_matches:
(OUT / "exported-telemetry-indicator-matches.txt").write_text("\n".join(log_matches) + "\n")
print(f"[!] Found {len(log_matches)} matches in logs!")
if PACKAGES:
registry_dir = OUT / "registry"
registry_dir.mkdir(exist_ok=True)
print(f"[+] Wrote scope artifacts under {OUT}")
Downstream Abuse Audits
Compromised workstations expose active API credentials, requiring immediate rotated revocation. The following platforms are at risk:
- GitHub OIDC and PATs: Attackers harvested SSH private keys and Git Personal Access Tokens. Auditors must inspect recent action runs and release logs during the exposure window.
- Cloud IAM Credentials: AWS, Azure, and GCP session tokens. CloudTrail and Activity Logs should be queried for AssumeRole or write operations originating from unexpected IP addresses.
- NPM and Package Registries: Publishing tokens and credentials. Registry profiles must be audited for unauthorized version publishes or token additions.
Remediation and Closure
Patch the distribution kernel and reboot into the patched kernel. Where immediate patching is not feasible, block AF_ALG socket creation through sandbox policy or disable algif_aead if workloads do not require it. Closure requires patched booted-kernel proof, host workload mapping, negative file-integrity review, and downstream credential decisions for affected jobs and pods.
Sources
IOC Clipboard
11 IOCswww.cisa.gov www[.]cisa[.]gov xint.io xint[.]io github.com github[.]com lore.kernel.org lore[.]kernel[.]org nvd.nist.gov nvd[.]nist[.]gov https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json hxxps://www[.]cisa[.]gov/sites/default/files/feeds/known_exploited_vulnerabilities[.]json https://xint.io/blog/copy-fail-linux-distributions hxxps://xint[.]io/blog/copy-fail-linux-distributions https://github.com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 hxxps://github[.]com/torvalds/linux/commit/a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 https://lore.kernel.org/linux-cve-announce/2026042214-CVE-2026-31431-3d65@gregkh/ hxxps://lore[.]kernel[.]org/linux-cve-announce/2026042214-CVE-2026-31431-3d65@gregkh/ https://nvd.nist.gov/vuln/detail/CVE-2026-31431 hxxps://nvd[.]nist[.]gov/vuln/detail/CVE-2026-31431 a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5