needhelp
← Zurück zum Blog

Dirty Frag: Eine Neue Linux-Kernel Zero-Copy LPE-Schwachstelle

von xingwangzhe
Linux
Kernel
Sicherheit
LPE
Dirty Frag
CVE

Dirty Frag: Eine Schwachstellenkette im Zero-Copy-Pfad des Linux-Kernels, die Page-Cache-Schreibvorgänge vergiftet und die xfrm-ESP- und RxRPC-Schwachstellen verknüpft. Betroffen sind fast alle Mainstream-Distributionen seit 2017, was eine passwortlose Rechteausweitung auf root ermöglicht.


Schon Wieder? Lasst Ihr Uns Nie in Ruhe?

Ehrlich gesagt hätte ich nicht gedacht, dass ich so schnell wieder einen Artikel über Kernel-Rechteausweitung schreiben muss.

Es sind erst acht Tage seit dem Copy-Fail-Artikel. Acht Tage! Die algif_aead-Blacklist von Copy Fail war kaum ins Terminal getippt, der Patch noch nicht einmal warm, und dann — Dirty Frag schlägt ein.

Noch absurder: Copy Fails Gegenmaßnahmen sind gegen Dirty Frag vollständig wirkungslos. Diesmal zielt der Angriff auf völlig andere Kernel-Subsysteme — die xfrm-ESP- und RxRPC-Verschlüsselungspfade — sodass es völlig egal ist, ob algif_aead deaktiviert ist oder nicht.

Dirty Pipe (2022), Copy Fail (2026.04), Dirty Frag (2026.05)… Jedes Mal heißt es „betrifft fast alle Distributionen seit 2017“. Wisst ihr, was das bedeutet? Es bedeutet, dass in den letzten fast zehn Jahren jeder, der sich in irgendeinem unprivilegierten Konto auf eurem System angemeldet hat, die Chance hatte, still und leise root zu werden.

Aber ist das wirklich allein die Schuld der Kernel-Entwickler? Nicht unbedingt.

Die explosionsartige Verbreitung KI-gestützter Code-Audit-Tools ermöglicht es Sicherheitsforschern, fast ein Jahrzehnt lang verborgene Schwachstellen innerhalb von Stunden aufzuspüren. Bugs, die früher eine manuelle zeilenweise Überprüfung erforderten, werden jetzt von KI massenhaft aufgedeckt. Copy Fail wurde vom KI-Tool Xint Code in einer Stunde lokalisiert. Dirty Frag stammt zwar aus dem manuellen Audit des koreanischen Forschers Hyunwoo Kim, aber die ausgenutzten Codepfade gehören zur selben Familie wie Copy Fail — Page-Cache-Schreibvorgänge im Zero-Copy-Pfad — was zeigt, dass dieser Konstruktionsfehler alles andere als ein Einzelfall ist.

Noch beunruhigender ist der Offenlegungsprozess. Der Forscher hatte die Details mit einem vereinbarten 5-Tage-Embargo an das Kernel-Sicherheitsteam übermittelt, um den Distributionen Zeit zum Patchen zu geben. Doch am selben Tag veröffentlichte ein unbeteiligter Dritter die vollständigen Details und den Exploit der ESP(xfrm)-Schwachstelle. Kein CVE, kein Patch, aber der PoC war für jedermann verfügbar. Das ist keine verantwortungsvolle Offenlegung — das ist ein Dolchstoß in den Rücken jedes Linux-Benutzers. Das Patchfenster wurde zerstört, alle mussten nackt weiterrennen.

Gut, genug geschimpft. Sehen wir uns ernsthaft an, worum es bei dieser Schwachstelle geht.


Zeitstrahl

Datum Ereignis
2017-01 xfrm-ESP-Schwachstelle mit Commit cac2661c53f3 eingeführt (lag 9 Jahre verborgen)
2023-06 RxRPC-Schwachstelle mit Commit 2dc334f1a63a eingeführt
2026-04-29 Koreanischer Forscher Hyunwoo Kim (@v4bel) meldet RxRPC-Schwachstelle und vollständigen Exploit an security@kernel.org
2026-05-07 Details an linux-distros-Mailingliste mit vereinbartem 5-Tage-Embargo übermittelt
2026-05-07 Am selben Tag veröffentlicht Dritter ESP(xfrm)-Details, Embargo sofort gebrochen
2026-05-07 Nach Rücksprache mit Distributionsmaintainern vollständige Dirty-Frag-Dokumentation veröffentlicht. Kein CVE, kein offizieller Patch
2026-05-08 Zum Zeitpunkt des Schreibens warten die großen Distributionen noch auf den Upstream-Patch

Auswirkungsanalyse

Metrik Details
CVE Noch keines (NVD hatte keine Zeit vor dem Embargo-Bruch)
Schwachstellentyp Deterministischer Logikfehler, keine Race-Condition
Erfolgsrate 100%, garantierter Erfolg bei erster Ausführung
Betroffener Bereich Fast alle Mainstream-Distributionen seit 2017 (Stand Mai 2026, Kernel 7.0.3 ebenfalls betroffen)
Exploit-Methode 192-Byte-Payload, Zusammenbau einer Root-Shell-ELF durch 48 4-Byte-Schreibvorgänge
Festplattenspuren Keine — nur In-Memory-Page-Cache wird verunreinigt, umgeht inotify; nach Neustart wiederhergestellt
Umgeht Copy-Fail-Mitigation algif_aead-Deaktivierung ist vollständig wirkungslos

Vergleich mit historischen Kernel-LPE-Schwachstellen:

Merkmal Dirty Cow (2016) Dirty Pipe (2022) Copy Fail (2026) Dirty Frag (2026)
Race-Condition Erforderlich Nicht erforderlich Nicht erforderlich Nicht erforderlich
Betroffener Bereich Bestimmte Versionen 5.8+ Alle Mainstream-Distros seit 2017+ Alle Mainstream-Distros seit 2017+
Exploit-Komplexität Komplex Komplex 10 Zeilen Python Einzelne C-Datei
Festplattenspuren Ja Ja Nein Nein
Patch-Status Behoben Behoben Behoben Noch kein offizieller Patch

Bestätigte betroffene Distributionen:

Distribution Getestete Kernel-Version
Ubuntu 24.04.4 6.17.0-23-generic
RHEL 10.1 6.12.0-124.49.1
CentOS Stream 10 6.12.0-224
AlmaLinux 10 6.12.0-124.52.3
Fedora 44 6.19.14-300
openSUSE Tumbleweed 7.0.2-1
Arch Linux 7.0.3

Von 6.12 bis 7.0, von Ubuntu bis Arch — vollständige Plattformabdeckung. Ja, so ziemlich jede Mainstream-Distribution, die ihr installiert habt, ist wahrscheinlich betroffen.


Technische Grundlagen: Warum „Dirty Frag“?

Der Kern in einem Satz

splice() pflanzt eine Page-Cache-Referenz einer schreibgeschützten Datei in den Frag-Slot des Netzwerk-Sendepuffers (skb) ein → der empfangende Kernel führt kryptografische In-Place-Operationen auf dem Frag aus (src == dst, gleicher Speicher) → die vermeintliche Entschlüsselung wird zur STORE-Primitive, die direkt in den schreibgeschützten Page-Cache schreibt → der Maschinencode von su wird durch eine Root-Shell-ELF ersetzt.

„Dirty“ steht für die Page-Cache-Vergiftung, „Frag“ für die Ausnutzung des skb-Fragmentmechanismus. Zusammen — Dirty Frag.

skb-Frag-Vergiftung im Zero-Copy-Pfad

Dieser Teil ist der Schlüssel zum Verständnis der gesamten Schwachstelle.

Normalerweise kopiert der Kernel Daten aus dem Userspace in seinen skb, wenn man in einen Socket schreibt. Aber splice() nimmt den Zero-Copy-Pfad — es stopft den Zeiger auf die Page-Cache-Seite (page-Struktur + Offset) direkt ins frag-Array des skb, ohne die Daten selbst zu kopieren:

struct skb_shared_info {
struct sk_buff *frag_list; // frag-verkettete Liste
skb_frag_t frags[MAX_SKB_FRAGS]; // jedes = {page, offset, size}
// ...
};

Der entscheidende Punkt: Die an splice() übergebene page ist die In-Memory-Page-Cache-Seite der Datei (z.B. /usr/bin/su) — man hat nur Leseberechtigung, aber eine Referenz auf diese Seite ist bereits im skb des Netzwerkprotokollstapels eingepflanzt.

Danach hängt es davon ab, ob der empfangende Netzwerkstack „die Finger nicht stillhalten kann“ und auf diese Seite schreibt.

Schwachstelle 1: xfrm-ESP Page-Cache-Schreibvorgang

Die erste Schwachstelle liegt im IPsec-ESP-Entschlüsselungspfad (Encapsulating Security Payload).

esp_input() entschlüsselt verschlüsselte Daten. Normalerweise sollte der Kernel, wenn der Datenbereich des skb mit einem Frag geteilt würde, zuerst skb_cow_data() (Copy-on-Write) aufrufen. Es existiert jedoch ein Codepfad, der COW umgeht:

static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
{
if (!skb_cloned(skb)) {
if (!skb_is_nonlinear(skb)) {
// [1] Linearer skb: nur Head-Daten, kein Frag, sicher
nfrags = 1;
goto skip_cow;
} else if (!skb_has_frag_list(skb)) {
// [2] Hat Frags, aber kein frag_list → überspringt COW direkt!
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
goto skip_cow; // DIE BOMBE
}
}
err = skb_cow_data(skb, 0, &trailer);
}

Wenn der skb nichtlinear ist (hat Frags mit dem Page-Cache) aber frag_list leer ist, springt der Code direkt zu skip_cow. Danach führt crypto_authenc_esn_decrypt() eine In-Place-AEAD-Entschlüsselung durch — src und dst zeigen auf dieselbe Scatterlist, die vom Angreifer implantierte Page-Cache-Seite.

Die kritische Zeile:

scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);

Schreibt 4 Bytes nach dst (die Page-Cache-Seite von su) am Offset assoclen + cryptlen. Der Wert stammt aus den oberen 32 Bit der ESP-Header-Sequenznummer — vom Angreifer vollständig kontrollierbar über XFRMA_REPLAY_ESN_VAL.seq_hi.

Der Angreifer kontrolliert gleichzeitig:

  • Wohin geschrieben wird (Datei-Offset, über Payload-Länge positioniert)
  • Welcher Wert geschrieben wird (4 Bytes, über seq_hi)

48 XFRM-SAs registrieren, jede mit seq_hi = einem 4-Byte-Fragment der ELF, 48 Iterationen → vollständige Root-Shell-ELF im Page-Cache von su.

Einschränkung: Registrierung von XFRM-SAs erfordert CAP_NET_ADMIN. Erhältlich durch unshare(CLONE_NEWUSER | CLONE_NEWNET) — aber Ubuntus AppArmor blockiert Network-Namespaces für unprivilegierte Benutzer. Daher die zweite Schwachstelle.

Schwachstelle 2: RxRPC Page-Cache-Schreibvorgang

Die zweite Schwachstelle liegt im Kerberos-Authentifizierungs-Entschlüsselungspfad des RxRPC-Protokolls.

rxkad_verify_packet_1() führt In-Place-pcbc(fcrypt)-Entschlüsselung auf den ersten 8 Bytes durch:

skcipher_request_set_crypt(req, sg, sg, 8, iv.x);
// ^^ ^^
// src==dst → In-Place-Operation!
ret = crypto_skcipher_decrypt(req); // 8-Byte-Schreibvorgang

skb_to_sgvec() wandelt den skb-Frag (mit der Page-Cache-Seite) direkt in eine Scatterlist um, src == dst. Das „Entschlüsselungsergebnis“ wird direkt zurück in die schreibgeschützte Page-Cache-Seite geschrieben.

Vergleich:

Merkmal xfrm-ESP RxRPC
Schreibgröße 4 Bytes 8 Bytes
Wertkontrolle Direkt (seq_hi) Indirekt (fcrypt-Schlüssel-Brute-Force)
Erforderliche Privilegien User-Namespace Keine Privilegien
Einführung 2017-01 2023-06

RxRPC-Werte sind nicht direkt kontrollierbar — sie sind das Ergebnis von fcrypt_decrypt(C, K). Der Angreifer registriert einen Schlüssel K via add_key("rxrpc", ...) und brute-forced dann das K, das die gewünschten 8 Bytes erzeugt. fcrypt = 56-Bit-Schlüssel, 8-Byte-Block, Brute-Force ist kein Problem.

Entscheidend: RxRPC erfordert absolut keine Privilegien. Kein User-Namespace, kein Network-Namespace, kein CAP_NET_ADMIN. Und Ubuntu lädt rxrpc.ko standardmäßig.

Verkettungslogik

Volle Abdeckung durch Komplementarität:

Szenario Verwendete Schwachstelle Grund
Ubuntu (AppArmor blockiert Namespaces) RxRPC rxrpc.ko standardmäßig geladen, ohne Privilegien
RHEL / Fedora / openSUSE xfrm-ESP Namespaces verfügbar, ESP-Schreibvorgänge präzise kontrollierbar
Andere Distributionen xfrm-ESP oder RxRPC Mindestens ein Pfad verfügbar

Das macht Dirty Frag so furchteinflößend — egal wie ihr konfiguriert, es gibt immer einen Weg zu root.


PoC-Analyse

Vollständiger Exploit auf github.com/V4bel/dirtyfrag:

Terminal window
git clone https://github.com/V4bel/dirtyfrag.git
cd dirtyfrag && gcc -O0 -Wall -o exp exp.c -lutil && ./exp

Kernidee:

  1. Minimales 192-Byte-ELF vorbereiten — Root-Shell bei Ausführung
  2. In 48 4-Byte-Blöcke zerlegen (xfrm-ESP-Pfad)
  3. Pro Block einen XFRM-SA registrieren, seq_hi = Blockwert
  4. splice() sendet Page-Cache von su in skb → In-Place-Schreibvorgang
  5. 48 Iterationen → erste 192 Bytes des su-Page-Cache komplett ersetzt
  6. execve("/usr/bin/su") → Root-Shell

Null Festplattenzugriffe. /usr/bin/su auf der Platte unverändert, md5 original. Aber im Kernel-Page-Cache wurde es heimlich ersetzt. Wenn ein Prozess execve auf su ausführt, liest der Kernel aus dem Page-Cache — hoppla, es wird eure injizierte Binary ausgeführt. Root.


Notfallmaßnahmen: Verwundbare Module Vorübergehend Deaktivieren

Stand 8. Mai 2026: Kein offizieller Patch. Einzige temporäre Mitigation: die drei Module entladen und blacklisten.

Prüft, ob euer System betroffen ist:

Terminal window
lsmod | grep -E 'esp4|esp6|rxrpc'

Ausgabe → betroffen.

Sofort ausführen (kein Neustart nötig):

Terminal window
sudo sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf"
sudo rmmod esp4 esp6 rxrpc 2>/dev/null

Wichtig: Wenn der PoC bereits ausgeführt wurde, Page-Cache leeren:

Terminal window
echo 3 | sudo tee /proc/sys/vm/drop_caches

Ohne dies bleibt der vergiftete Page-Cache auch nach Modul-Deaktivierung im Speicher — su ausführen gibt immer noch Root-Shell.

Nebenwirkungen:

  • esp4/esp6 deaktiviert → IPsec-VPN-Tunnel werden unterbrochen. Desktop-Nutzer und die meisten Server nicht betroffen, aber bei Abhängigkeit von IPsec-VPN (strongSwan, Libreswan) zuerst Auswirkungen prüfen.
  • rxrpc deaktiviert → minimale Auswirkung, außer bei AFS-Nutzung.

KI-beschleunigtes Schwachstellen-Wettrüsten

Dirty Frag zwingt zu einer tieferen Frage: Warum tauchen Kernel-LPEs in letzter Zeit in Serie auf?

Schwachstelle Entdeckung Schlüsselwerkzeug Meldung bis öffentlich
Dirty Pipe 2022 Manuelles Audit Standardprozess
Copy Fail 2026-04 Xint Code (KI) ~1 Monat
Dirty Frag 2026-05 Manuelles Audit 8 Tage (Embargo am selben Tag gebrochen)

Von einer pro Jahr → eine pro Monat → eine pro Woche?

Dahinter steckt die Explosion KI-gestützter Audit-Tools. Früher las ein Mensch zeilenweise, eine Schwachstelle konnte zehn Jahre unentdeckt bleiben. Heute scannt KI ein ganzes Subsystem in Stunden. Der Kernel wurde nicht plötzlich schlechter — nur die alten, in Ecken versteckten Schulden werden von KI eine nach der anderen aufgedeckt.

Und das Offenlegungs-Ökosystem verändert sich. Dirty Frags Embargo wurde am selben Tag mutwillig gebrochen. Von der Meldung an security@kernel.org bis zu den Waffen in Hackers Händen weltweit: acht Tage. Das Patchfenster — verschwunden.

Dieselbe Schwachstellenfamilie wächst weiter:

Schwachstelle Subsystem Status
Copy Fail AF_ALG + authencesn Behoben
Dirty Frag xfrm-ESP + RxRPC Kein Patch
Copy Fail 2 ESP-in-UDP Öffentlich
ZCRX Freelist io_uring ZCRX Öffentlich

Immer das gleiche Prinzip: splice() injiziert schreibgeschützte Page-Cache-Referenzen, Subsysteme schreiben In-Place. Dieselbe Klasse von Konstruktionsfehlern:

Komponente Einführungsgrund Nebeneffekt
splice() Zero-Copy, Performance Schreibgeschützte Page-Cache-Refs an Subsysteme gesendet
AF_ALG Kernel-Krypto-Fähigkeiten Unprivilegierte Benutzer starten Krypto-Sessions
xfrm-ESP IPsec-Beschleunigung In-Place-Entschlüsselung, schreibgeschützte Seiten als Ausgabepuffer
RxRPC AFS-Protokollunterstützung Dito, ohne Namespace-Privilegien

Jedes einzelne Design ist eine vernünftige Optimierung oder funktionale Anforderung. Zusammen bilden sie eine Kette, in der jeder lokale Benutzer ohne Passwort root wird.

Solange der Upstream-Kernel das Paradigma „In-Place-Operationen auf Zero-Copy-Pfaden“ nicht grundlegend überdenkt, garantiere ich euch — das wird nicht die letzte sein.

Für normale Benutzer:

  1. Führt jetzt die Blacklist-Befehle oben aus. Rückgängig machen, wenn der offizielle Patch kommt.
  2. Überwacht Kernel-Updates genau. Sobald eine korrigierte Version verfügbar ist, sofort aktualisieren und neu starten.
  3. Regelmäßig mit lsmod | grep prüfen, ob diese Module versehentlich geladen wurden.

Referenzen


Informationsgrafiken

Dirty Frag Übersichtsdiagramm

Abbildung 1: Dirty Frag Übersicht — wie Zero-Copy Page-Cache-Referenzen über skb frags ausgenutzt werden

Diese Seite teilen