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

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

Auswirkungsanalyse

MetrikDetails
CVENoch keines (NVD hatte keine Zeit vor dem Embargo-Bruch)
SchwachstellentypDeterministischer Logikfehler, keine Race-Condition
Erfolgsrate100%, garantierter Erfolg bei erster Ausführung
Betroffener BereichFast alle Mainstream-Distributionen seit 2017 (Stand Mai 2026, Kernel 7.0.3 ebenfalls betroffen)
Exploit-Methode192-Byte-Payload, Zusammenbau einer Root-Shell-ELF durch 48 4-Byte-Schreibvorgänge
FestplattenspurenKeine — nur In-Memory-Page-Cache wird verunreinigt, umgeht inotify; nach Neustart wiederhergestellt
Umgeht Copy-Fail-Mitigationalgif_aead-Deaktivierung ist vollständig wirkungslos

Vergleich mit historischen Kernel-LPE-Schwachstellen:

MerkmalDirty Cow (2016)Dirty Pipe (2022)Copy Fail (2026)Dirty Frag (2026)
Race-ConditionErforderlichNicht erforderlichNicht erforderlichNicht erforderlich
Betroffener BereichBestimmte Versionen5.8+Alle Mainstream-Distros seit 2017+Alle Mainstream-Distros seit 2017+
Exploit-KomplexitätKomplexKomplex10 Zeilen PythonEinzelne C-Datei
FestplattenspurenJaJaNeinNein
Patch-StatusBehobenBehobenBehobenNoch kein offizieller Patch

Bestätigte betroffene Distributionen:

DistributionGetestete Kernel-Version
Ubuntu 24.04.46.17.0-23-generic
RHEL 10.16.12.0-124.49.1
CentOS Stream 106.12.0-224
AlmaLinux 106.12.0-124.52.3
Fedora 446.19.14-300
openSUSE Tumbleweed7.0.2-1
Arch Linux7.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:

Merkmalxfrm-ESPRxRPC
Schreibgröße4 Bytes8 Bytes
WertkontrolleDirekt (seq_hi)Indirekt (fcrypt-Schlüssel-Brute-Force)
Erforderliche PrivilegienUser-NamespaceKeine Privilegien
Einführung2017-012023-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:

SzenarioVerwendete SchwachstelleGrund
Ubuntu (AppArmor blockiert Namespaces)RxRPCrxrpc.ko standardmäßig geladen, ohne Privilegien
RHEL / Fedora / openSUSExfrm-ESPNamespaces verfügbar, ESP-Schreibvorgänge präzise kontrollierbar
Andere Distributionenxfrm-ESP oder RxRPCMindestens 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:

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:

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

Ausgabe → betroffen.

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

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:

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?

SchwachstelleEntdeckungSchlüsselwerkzeugMeldung bis öffentlich
Dirty Pipe2022Manuelles AuditStandardprozess
Copy Fail2026-04Xint Code (KI)~1 Monat
Dirty Frag2026-05Manuelles Audit8 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:

SchwachstelleSubsystemStatus
Copy FailAF_ALG + authencesnBehoben
Dirty Fragxfrm-ESP + RxRPCKein Patch
Copy Fail 2ESP-in-UDPÖffentlich
ZCRX Freelistio_uring ZCRXÖffentlich

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

KomponenteEinführungsgrundNebeneffekt
splice()Zero-Copy, PerformanceSchreibgeschützte Page-Cache-Refs an Subsysteme gesendet
AF_ALGKernel-Krypto-FähigkeitenUnprivilegierte Benutzer starten Krypto-Sessions
xfrm-ESPIPsec-BeschleunigungIn-Place-Entschlüsselung, schreibgeschützte Seiten als Ausgabepuffer
RxRPCAFS-ProtokollunterstützungDito, 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