flawopen.com/Teardowns/cve-2026-31431-linux-algif-aead-copy-fail
CVE-2026-31431: Linux Copy Fail Kernel Flaw
Copy Fail is a local privilege-escalation flaw in the Linux AF_ALG AEAD path. An in-place processing optimization confused source and destination mappings; the upstream fix restores out-of-place operation, and CISA lists the CVE in KEV.[1], [2], [5]
Imagine a librarian told to annotate a photocopy, but the copy machine's shortcut sends the pencil to the original book instead. The crypto path's in-place shortcut let a write intended for a destination land in a different mapped page. The kernel fix stops treating those mappings as interchangeable and processes source and destination separately.[3], [8]
Core Concepts & Subsystem Terms
AF_ALG- Linux's userspace cryptography socket interface. A local process can request supported crypto operations through this kernel API.[8], [3]
AEAD- Authenticated Encryption with Associated Data: encryption that also authenticates additional, unencrypted metadata.[8]
algif_aead- The AF_ALG socket implementation for AEAD algorithms, including the vulnerable source/destination handling path.[3]
Page cache- The kernel's in-memory cache of file contents. Writes to a mapped cache page can affect what processes read before a later disk write occurs.[8]
Framework mappings
- CWE reference for the weakness described in this guide: CWE-669 CWE-1288
- CISA KEV — added 2026-05-01 — CVE-2026-31431
Root Cause Analysis
The 2017 change 72548b093ee3 introduced an in-place optimization in the algif_aead path. In this flow, source and destination can come from different mappings. The authencesn processing path can write scratch data outside the intended output region; with the in-place scatterlist arrangement, the write can land in a page-cache page supplied through splice(). The Linux CVE notice describes the repair as reverting to out-of-place operation while retaining the associated-data copy. Treat the path as a local kernel privilege boundary issue: an attacker needs local access and the vulnerable kernel path enabled. The CVE assigns CVSS 7.8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H); it does not describe an unauthenticated remote entry point.[1], [3], [8], [7], [9], [10]
Step-by-Step Attack Flow
A write crosses the intended output boundary
During authencesn processing, scratch handling can write outside the intended output region. The vulnerable scatterlist arrangement can direct those bytes into a page-cache page associated with a spliced file.[8]
Source Code: Flaw vs. Secure Implementation
These excerpts are taken from the upstream stable patch for crypto/algif_aead.c. The fix builds a request-specific source scatterlist, copies only the associated data into the receive scatterlist, and passes the TX scatterlist as the crypto source while the receive scatterlist remains the destination. This restores out-of-place processing. The omitted lines allocate and initialize the request scatterlist; the shown fragments are context excerpts, not a standalone compilable function.[3], [2]
Source excerpt: crypto/algif_aead.c (_aead_recvmsg)
/* Before the fix: arrange the crypto operation in-place. */
rsgl_src = areq->first_rsgl.sgl.sg;
if (ctx->enc) {
memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, processed);
af_alg_pull_tsgl(sk, processed, NULL, 0);
} else {
memcpy_sglist(areq->first_rsgl.sgl.sg, tsgl_src, outlen);
/* Build and chain a TX scatterlist for the authentication tag. */
areq->tsgl_entries = af_alg_count_tsgl(sk, processed, processed - as);
/* ... */
}
aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src,
areq->first_rsgl.sgl.sg, used, ctx->iv);
/* After the fix: retain a per-request source scatterlist. */
processed = used + ctx->aead_assoclen;
areq->tsgl_entries = af_alg_count_tsgl(sk, processed);
/* Allocate and initialize areq->tsgl, then pull the TX pages into it. */
af_alg_pull_tsgl(sk, processed, areq->tsgl);
tsgl_src = areq->tsgl;
/* Copy associated data, but keep source and destination separate. */
rsgl_src = areq->first_rsgl.sgl.sg;
memcpy_sglist(rsgl_src, tsgl_src, ctx->aead_assoclen);
aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
areq->first_rsgl.sgl.sg, used, ctx->iv);
Engineering & System Hardening Checklist
- ✓Patch Linux kernels through the distribution's supported update channel, then verify the installed package's advisory or changelog confirms
CVE-2026-31431is fixed; do not infer status from a generic upstream version alone.[1], [5], [7] - ✓Prioritize shared-kernel systems with untrusted local users, including multi-tenant hosts, build workers, and container nodes, because a local kernel privilege boundary is involved.[5], [7]
- ✓Where immediate kernel patching is impossible, apply only a mitigation documented by the operating-system vendor and validate its impact on workloads; do not treat a module block as universally applicable when the code may be built in.[5], [7]
- ✓Review kernel inventory and package provenance across fleet images, including immutable images and long-term-support branches that may use backported fixes.[5], [7]
- ✓Keep container isolation assumptions explicit: containers share the host kernel, so a kernel-local privilege escalation can undermine namespace-based separation.[5], [8]
- ✓After patching, monitor vendor advisories for any additional backports and track unpatched hosts as remediation work rather than relying on CISA KEV inclusion alone.[1], [5]
Sources
- Linux kernel CVE notice for CVE-2026-31431
- Upstream stable patch: revert algif_aead to out-of-place operation
- Stable patch source with the algif_aead.c code diff
- CVE record and CVSS vector
- Canadian Centre for Cyber Security alert AL26-009
- CISA Known Exploited Vulnerabilities catalog entry
- Red Hat CVE analysis and affected product status
- Xint technical disclosure: Copy Fail — 732 Bytes to Root on Linux
- MITRE CWE-1288: Improper Validation of Consistency within Input
- MITRE CWE-669: Incorrect Resource Transfer Between Spheres
- NVD — CVE-2026-31431 weakness mapping (source: redhat-SADP)