
Proof-of-Concept-Exploit für CVE-2026-31431, eine lokale Privilegieneskalation im Linux-Kernel über einen AF_ALG-Page-Cache-Write, die auf gängigen Distributionen Root-Rechte erlangt.
algif_aead-Page-Cache-Schreibvorgang („Copy Fail")
Autor: Van Glenndon Enad
Ursprüngliche Entdeckung: Theori / Xint Code Research Team (Taeyang Lee)
Veröffentlicht: 29. April 2026
Schweregrad: Hoch
CVSS v3.1-Score: 7.8
CVSS v3.1-Vektor: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CWE: CWE-787 (Schreiben außerhalb der Grenzen), CWE-269 (Fehlerhaftes Privilegienmanagement)
CVE-2026-31431, öffentlich als „Copy Fail" bezeichnet, ist eine lokale Schwachstelle mit hohem Schweregrad zur Privilegieneskalation (LPE) im algif_aead-Modul des Linux-Kernels – der AEAD-Chiffrierschnittstelle der Userspace-Krypto-API des Kernels (AF_ALG). Der Fehler stammt aus einer Leistungsoptimierung („In-Place-Operation"), die 2017 über den Commit 72548b093ee3 eingeführt wurde und versehentlich ermöglichte, dass Page-Cache-gestützte Dateiseiten während einer AEAD-Kryptooperation in die beschreibbare Ziel-Scatterlist eingefügt werden konnten.
Durch die Verkettung von drei Kernel-Subsystemen – AF_ALG-Sockets, den Systemaufruf splice() und das Scratch-Schreibverhalten des authencesn-Algorithmus – kann ein nicht privilegierter lokaler Benutzer einen kontrollierten 4-Byte-Schreibvorgang in den Page-Cache einer beliebigen lesbaren Datei durchführen. Wenn ein setuid-Binärprogramm wie /usr/bin/su als Ziel gewählt wird, korrumpiert dieser Schreibvorgang das In-Memory-Ausführungsimage, ohne die Datei auf der Festplatte zu verändern, wodurch Dateiintegritätstools auf der Festplatte umgangen werden. Die daraus resultierende Privilegieneskalation zu root ist deterministisch – keine Race Condition, keine distributionsspezifischen Kernel-Offsets und keine speziellen Privilegien sind erforderlich. Ein öffentlich veröffentlichter 732-Byte-Python-PoC-Exploit liefert Root-Shells auf Ubuntu, Amazon Linux, RHEL und SUSE in einem einzigen unveränderten Lauf.
| Komponente | Details |
|---|---|
| Betroffenes Subsystem | crypto/algif_aead.c – Linux-Kernel-AF_ALG-AEAD-Schnittstelle |
| Schwachstelle eingeführt | Linux-Kernel 4.14 (2017), Commit 72548b093ee38a6d4f2a19e6ef1948ae05c181f7 |
| Behobene Versionen | 6.18.22, 6.19.12, 7.0 |
| Fix-Commit | a664bf3d603dc3bdcf9ae47cc21e0daec706d7a5 |
| Verifizierte Distributionen | Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 10.1, SUSE 16 |
| Implizit betroffen | Debian, Arch, Fedora, Rocky, AlmaLinux, Oracle Linux und jede Distribution mit einem ungepatchten Kernel, der seit 2017 gebaut wurde |
Die Schwachstelle ist seit fast neun Jahren stillschweigend in jeder gängigen Linux-Distribution vorhanden. Laut Theori ist AF_ALG in der Standard-Kernelkonfiguration praktisch jeder Distribution aktiviert, was bedeutet, dass keine speziellen Build-Flags oder Konfigurationen erforderlich sind, damit ein System verwundbar ist.
Der Linux-Kernel stellt Userspace-Anwendungen kryptografische Primitive über die AF_ALG-Socket-Schnittstelle (crypto/algif_aead.c) zur Verfügung. 2017 wurde eine Leistungsoptimierung eingeführt, die es algif_aead ermöglichte, AEAD-Operationen in-place durchzuführen – den Quellspeicherpuffer als Ziel wiederzuverwenden –, um unnötiges Datenkopieren zu vermeiden.
Der Fehler tritt auf, wenn Userspace-Eingaben über den Systemaufruf splice() in den AF_ALG-Socket eingespeist werden. In diesem Fall sind die in die Quell-Scatterlist eingefügten Seiten Page-Cache-Seiten – gemeinsamer, kernelverwalteter Speicher, der die gespleißte Datei unterstützt. Aufgrund der In-Place-Optimierung, die req->src = req->dst setzt, landen diese Page-Cache-Seiten in der beschreibbaren Ziel-Scatterlist. Der authencesn-Algorithmus führt anschließend einen Scratch-Schreibvorgang bei dst[assoclen + cryptlen] durch, der sich in einen Offset innerhalb dieser Page-Cache-Seiten auflöst – wodurch effektiv Angreifer-kontrollierte Daten in das In-Memory-Image der gespleißten Datei geschrieben werden.
Da der Page-Cache auf dem gesamten Host einschließlich Containern gemeinsam genutzt wird, wirkt sich ein Schreibvorgang eines Prozesses auf die gecachten Seiten dieser Datei für jeden Prozess und Container auf demselben Kernel aus.
Die problematische Änderung in algif_aead.c setzte req->src = req->dst und verkettete Tag-Seiten aus der Quell-Scatterlist über sg_chain() in die Ausgabe-Scatterlist:
/* In-Place-Optimierung von 2017 – Commit 72548b093ee3 */
req->src = req->dst; /* Quelle == Ziel */
sg_chain(dst, n + 1, src_tag); /* Tag-Seiten in beschreibbares dst verkettet */
Wenn splice() verwendet wird, um eine Datei in den Socket einzuspeisen, sind die Scatterlist-Seiten Page-Cache-gestützt, nicht privater anonymer Speicher. Ihre Verkettung in die beschreibbare dst-Scatterlist verletzt die Annahme, dass das Ziel beschreibbarer privater Speicher ist.
authencesn-Scratch-SchreibvorgangDie authencesn-Vorlage schreibt einen Sequenznummer-Scratch-Wert (seqno_lo, Bytes 4–7 der AAD) bei dst[assoclen + cryptlen]. Da dst nun Page-Cache-Seiten aus der gespleißten Datei enthält, landet dieser Schreibvorgang an einem Angreifer-kontrollierten Offset innerhalb des In-Memory-Images der Datei:
/* authencesn-Scratch-Schreibvorgang – Offset bestimmt durch assoclen + cryptlen */
scatterwalk_map_and_copy(seqno, dst,
req->assoclen + req->cryptlen,
sizeof(seqno), 1); /* schreibt in den Page-Cache */
Die geschriebenen 4 Bytes entsprechen seqno_lo, das der Angreifer über die durch sendmsg() gesendete AAD-Payload kontrolliert.
AF_ALG-Socket (SOCK_SEQPACKET)
│
│ splice() – liefert dateigestützte Seiten in den Socket
▼
algif_aead-In-Place-Optimierung
│ req->src = req->dst
│ Page-Cache-Seiten landen in der beschreibbaren Scatterlist
▼
authencesn-Scratch-Schreibvorgang
│ schreibt seqno_lo bei dst[assoclen + cryptlen]
│ = Angreifer-gewählte 4 Bytes an Angreifer-gewähltem Datei-Offset
▼
Page-Cache-Korruption (keine Änderung auf der Festplatte)
Der Fix (a664bf3d603d) macht die In-Place-Optimierung vollständig rückgängig – algif_aead arbeitet jetzt immer out-of-place und weist einen separaten Zielpuffer zu. Da Quelle und Ziel nun aus unterschiedlichen Zuordnungen stammen, können Page-Cache-Seiten in src niemals über den dst-Schreibpfad erreicht werden.