Eine Funktion zweimal gegen eine andere ausgetauscht, und ein CVSS von 9.8
Vorher: kfree(). Nachher: kfree_rcu(). Das ist der gesamte Fix für CVE-2026-98432, wiederholt in zwei verschiedenen Funktionen in zwei verschiedenen Dateien. Liest man zuerst den CVSS-Wert, klingt der Fehler abstrakt: 9.8, kritisch, keine Rechte nötig, keine Benutzerinteraktion nötig. Liest man zuerst den Diff, verschwindet die Abstraktion. Der Fehler ist ein einziger Funktionsname, gegen den falschen ausgetauscht, an genau zwei Stellen.
CVE-2026-98432 ist ein Use-after-free in der Art, wie der IPv4-TCP-Stack des Linux-Kernels die IP-Optionen einer Verbindung behandelt, vorhanden seit einem Commit aus dem Jahr 2015 und inzwischen in jedem gepflegten Stable-Zweig behoben.[1] NVDs eigene CNA bewertete ihn mit 9.8, AV:N/AC:L/PR:N/UI:N: remote, geringe Komplexität, keine Rechte, keine Benutzerinteraktion. Drei Wochen nach der Offenlegung nennt Red Hats eigenes Bulletin noch immer keinen fertigen Build, und Ubuntus eigener Tracker listet noch immer jedes unterstützte Release als verwundbar oder in Arbeit.[2][3] Ein unveröffentlichtes Forschungsmodell von Anthropic soll daraus einen funktionierenden Zero-Click-Weg zu Root in unter einer Stunde gemacht haben.[4] Mehr zu dieser Behauptung weiter unten, und zwar genau, denn ein Detail, das online mitläuft, hat Anthropic so nie gesagt.
Ich habe den fixenden Commit selbst gelesen, keine Paraphrase davon. git.kernel.org lieferte auf einen direkten Abruf einen HTTP-403-Fehler, also habe ich denselben Commit, über den Hash identifiziert, aus dem öffentlichen Spiegel des Stable-Trees gelesen, den Greg Kroah-Hartman auf GitHub pflegt.[5] Ich habe das nicht in einem Labor reproduziert. Dieser Beitrag beruht auf dem vollständigen Lesen von Primärquellen, nicht auf dem Ausführen eines Exploits, und dieser Unterschied ist für alles Folgende wichtig.
// The actual kfree -> kfree_rcu swap, per the fixing commit (dossier
// S2). Surrounding code is an illustrative reconstruction of shape, not
// a literal excerpt.
net/ipv4/af_inet.c, inet_sock_destruct():
- kfree(opt)
+ kfree_rcu(opt, rcu)
net/ipv4/tcp_ipv4.c, tcp_v4_reqsk_destructor():
- kfree(opt)
+ kfree_rcu(opt, rcu)Was „später freigeben“ eigentlich bringen soll
Hier ist die Invariante, auf die sich ein großer Teil des Netzwerkcodes im Kernel verlässt, ohne lange darüber nachzudenken: Ein Leser innerhalb von rcu_read_lock() darf annehmen, dass der Speicher, den er betrachtet, noch existiert, weil die Konvention lautet, dass Schreiber ihr tatsächliches Freigeben verzögern, bis jeder Leser nachweislich fertig ist. Das ist RCU, read-copy-update, und es ist die Antwort des Kernels auf ein schwieriges Problem: Wie lässt man Leser schnell und sperrenfrei laufen, während Schreiber trotzdem Dinge löschen dürfen, ohne dass ein Leser je Speicher berührt, der schon weg ist?
Ein TCP-Request-Socket, das Objekt des Kernels für eine halboffene Verbindung während des Handshakes, kann IP-Optionen tragen: vom Angreifer oder vom Netz stammende Daten, die am IP-Header des SYN-Pakets hängen. Der Kernel speichert diese Optionen hinter einem Zeiger (ireq_opt am Request-Socket, inet_opt nach der Beförderung zu einem vollwertigen Socket) und liest sie später, beim Aufbau von SYN-ACK oder ACK, innerhalb von ip_options_build(). Dieses Lesen geschieht unter RCU. Es muss: Eine zweite CPU, die ein erneut gesendetes SYN derselben Verbindung bearbeitet, kann sich zur selben Zeit legitim innerhalb dieser Funktion befinden, in der eine andere CPU die Verbindung abbaut.[1][5]
Zwei Destruktoren, eine Abkürzung, null Gnadenfrist
Zwei Stellen im Code haben den Vertrag gebrochen, auf dem RCU beruht: inet_sock_destruct() in net/ipv4/af_inet.c und tcp_v4_reqsk_destructor() in net/ipv4/tcp_ipv4.c, beide gaben denselben IP-Optionen-Zeiger mit einem einfachen kfree() frei, sofort, statt mit dem RCU-verzögerten kfree_rcu().[5] Ein einfaches kfree() macht den Speicher in dem Moment, in dem es läuft, sofort zur Wiederverwendung verfügbar: keine Gnadenfrist, kein Warten darauf, dass Leser fertig werden. Jede CPU, die sich noch innerhalb von ip_options_build() befindet und den Zeiger liest, den der Destruktor gerade freigegeben hat, liest jetzt Speicher, der unter ihr neu belegt und überschrieben werden kann.
Die Leserseite nutzte RCU: billig, sperrenfrei, tolerant gegenüber gleichzeitigem Freigeben, solange dieses Freigeben verzögert wird. Zwei Schreiber-Stellen haben ihren Teil dieser Abmachung nicht eingehalten. Diese Unstimmigkeit ist genau die Art von Fehler, die eine WAF, eine Authentifizierungsprüfung oder jede andere Kontrolle auf Anwendungsebene niemals sehen wird, weil sie vollständig innerhalb der eigenen Speicherverwaltung des Kernels liegt, zwei einzeilige Funktionsaufrufe tief in einem Destruktor-Pfad.
// Illustrative timeline of the SYN-retransmit race (one of two trigger
// paths), reconstructed from the fixing commit's own description -- not
// a captured trace, and not exploit code.
CPU A (processing the connection) CPU B (retransmitted SYN)
---------------------------------- ----------------------------------
child socket created, inherits the
ireq_opt pointer -- not copied
tcp_v4_reqsk_destructor() runs:
kfree(ireq_opt) <-- freed now,
no grace period
still inside rcu_read_lock(),
ip_options_build() dereferences
the same pointer -- already
freed, possibly reusedDas SYN, das du erneut sendest, oder das Request-Socket, das du migrierst
Der fixende Commit beschreibt genau zwei Wege in dieses Zeitfenster, und keiner davon braucht etwas Ungewöhnliches. Der erste: tcp_v4_syn_recv_sock() übergibt die IP-Optionen eines Request-Sockets an sein neu erzeugtes Child-Socket, ohne sie vorher zu kopieren, sodass eine zweite CPU, die noch ein erneut gesendetes SYN bearbeitet, gewöhnliches TCP-Verhalten, diese Optionen lesen kann, nachdem sie bereits freigegeben wurden.[1][5] Erneut gesendete SYNs passieren in echten Netzwerken ständig, ein Angreifer muss diese Bedingung also nicht erst herstellen. Er muss sie nur richtig timen.
Der zweite Pfad braucht noch eine zusätzliche Bedingung: explizit aktivierte TCP-Request-Socket-Migration, entweder über net.ipv4.tcp_migrate_req=1 oder ein angehängtes BPF-Programm mit SK_REUSEPORT_SELECT_OR_MIGRATE.[5] Das ist nirgendwo die Voreinstellung. Ist es aktiviert, teilt sich ein geklontes Request-Socket denselben Optionen-Zeiger mit dem Original, und derselbe Destruktor gibt ihn frei, unter welchem der beiden ihn auch noch benutzt. Wer einen gemischten IPv4/IPv6-Stack betreibt, sollte ein Detail beachten: Der fixende Commit besagt, dass IPv6 vom Retransmit-Race nicht betroffen ist, weil IPv6 die Optionen seines Request-Sockets dupliziert, statt sie zu teilen. Ein verwandtes IPv6-Migrationsproblem wird auf einen separaten Patch verschoben.[1][5] Dieser Fix betrifft ausschließlich IPv4.
Achtundvierzig Minuten bis zum Zeiger, fünf weitere bis Root
Hier ist der Teil dieser Geschichte, der tatsächlich viral ging, und er verdient es, genau richtig erzählt zu werden. Anthropics eigener Forschungsbeitrag, unter dem Namen des Frontier Red Team, erklärt, dass ein unveröffentlichtes, internes Forschungsmodell Schwachstellen fand und zu einem entfernten, Zero-Click-Exploit gegen Linux-Server mit laufendem Multipath-TCP-Listener verkettete: keine Zugangsdaten, keine Benutzerinteraktion, Root über das Netz.[4][6][7] Der Beitrag nennt CVE-2026-98432 namentlich. In Anthropics eigenen Worten: Es dauerte 48 Minuten, einen Kernel-Zeiger zu leaken, und weitere fünf Minuten danach, um Shell-Befehlsausführung zu erreichen.[4]
Ein Detail, das zusammen mit dieser Behauptung die Runde macht, steht so tatsächlich nicht darin. Der Codename „Project Glasswing“ taucht in Anthropics Beitrag an keiner Stelle auf. Er geht auf eine unbestätigte Sekundärquelle zurück, nicht auf Anthropics eigene Worte, und ich werde ihn hier nicht wiederholen, als hätte Anthropic einen Namen bestätigt, den sie nie benutzt hat. Unabhängig bestätigt ist dagegen: Zwei Sekundärquellen berichten dieselbe CVE-Nummer, denselben CVSS-Wert und dieselbe Zeitangabe, 48 Minuten und 5 Minuten, und beide verweisen auf Anthropics eigenen Beitrag als Quelle.[6][7] Eine davon fügt einen Satz hinzu, der vor dem nächsten Abschnitt eine Pause verdient: „Die öffentliche Aktenlage zu dieser CVE beschreibt einen Fix für IPv4-TCP, keinen für Multipath-TCP, und beide sind nur durch Anthropics Beitrag verbunden.“[7]
Red Hats Bulletin nennt MPTCP an keiner Stelle. Der Patch auch nicht.
Dieser Satz ist die ganze Geschichte, und genau dort geht der meiste Ratschlag aus zweiter Hand fehl. Lies den eigenen fixenden Commit des Kernels, und er beschreibt zwei Auslösepfade in schlichten IPv4-TCP-Begriffen, SYN-Retransmission und Request-Socket-Migration, ohne eine einzige Erwähnung von Multipath TCP.[1][5] Lies Red Hats eigenes Bulletin, RHSB-2026-016, und es ist dasselbe: „Systeme, die eingehende TCP-Verbindungen annehmen“ als betroffene Population, eine allgemeine Beschreibung der Race-Condition, kein MPTCP in der Voraussetzung, im Angriffsvektor oder in den Hinweisen zur Risikominderung.[2] Zwei Primärquellen. Keine davon erwähnt das, was die Hälfte des Internets zu deaktivieren empfiehlt.
Das ist meine eigene Lesart dieser beiden Quellen nebeneinander, kein Satz, den eine von beiden wörtlich so formuliert, deshalb sage ich es offen: Ein MPTCP-Listener ist ein Weg, diesen Fehler zuverlässig zu erreichen. Er ist nicht die bestimmende Voraussetzung des Fehlers. Wenn ein konkret demonstrierter Exploit MPTCP als gewählten Einstiegspunkt nutzte, und laut dem vorigen Abschnitt ist das ein plausibles, aber weiterhin unbestätigtes Detail eines gemeldeten Exploits, sagt das etwas über einen praktischen Weg aus, das Rennen zu gewinnen, nicht darüber, was die Schwachstelle selbst tatsächlich voraussetzt.[4][7] MPTCP zu deaktivieren (net.mptcp.enabled=0) entfernt diesen einen Listener-Typ als Angriffsfläche. Es rührt den zugrunde liegenden Use-after-free nicht an, der über gewöhnliche, nicht MPTCP-bezogene TCP-Verbindungsbehandlung weiterhin vollständig erreichbar bleibt.
// What the vulnerability actually requires (b), versus what one
// reported demonstration used (c). Don't let (c) stand in for (b).
(b) Real preconditions, per the kernel's own commit and Red Hat's
advisory -- neither names MPTCP:
- A listener processing IPv4 TCP SYNs and retransmitted SYNs
(ordinary behavior, any TCP listener), OR
- Request-socket migration explicitly enabled
(net.ipv4.tcp_migrate_req=1, or a BPF
SK_REUSEPORT_SELECT_OR_MIGRATE program) -- not the default.
- Precise timing to win the race window.
- No credentials, no user interaction (PR:N/UI:N).
(c) What one reported demonstration reportedly used to trigger it
reliably:
- A reachable multipath TCP (MPTCP) listener.
Disabling MPTCP removes (c). It leaves (b) exactly where it was.Im Kernel behoben. Noch nicht in dem Kernel, den die meisten tatsächlich laufen lassen
Der Upstream-Fix ist da, und er ist genau datiert: Stable-Zweige sind frei ab 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113 und 6.18.56, mit 7.2.10 und dem ursprünglichen Fix, der für das Mainline-Release 7.3 markiert ist, alles deckungsgleich mit NVDs eigenen Herstellerdaten.[1] Das ist der einfache Teil dieser Geschichte. Ob der Kernel unter deiner tatsächlichen Last einer dieser Nummern entspricht, ist der Teil, der Nachprüfen braucht, kein Annehmen.
Red Hats eigenes Bulletin, zuletzt aktualisiert am 2026-10-30, bewertet dies als „kritische Auswirkung“, nennt aber keinen fertigen Build, kein Errata und überhaupt keinen CVSS-Wert. Es heißt dort lediglich, Red Hat „beschleunige die Veröffentlichung von Fixes“.[2] Ubuntus eigener Tracker listet zum Zeitpunkt dieses Textes jedes unterstützte Release von 16.04 bis 26.10 als Vulnerable oder Vulnerable, work in progress. Nur 14.04, bereits außerhalb des regulären Supports, ist als unbetroffen markiert.[3] Red Hats Übergangslösung, falls man noch auf einen Build wartet: eine nftables-Regel, die eingehende IPv4-TCP-Pakete verwirft, deren IP-Header Optionen trägt, die gewöhnliche TCP-Optionen auf Transportebene unberührt lässt und ausdrücklich kein Ersatz für das Patchen ist.[2]
Eine weitere Zahl zählt hier, weil die Schlagzeilen stark auf Dringlichkeit setzen: Zum Zeitpunkt dieses Textes steht CVE-2026-98432 nicht im KEV-Katalog der CISA, auf zwei unabhängigen Wegen geprüft, und keine hier geprüfte Quelle dokumentiert bestätigte Ausnutzung in freier Wildbahn.[8][9] Das ist nicht dieselbe Aussage wie „kann man zurückstellen“. Ein 9.8 ohne Authentifizierung und ohne Benutzerinteraktion verdient für sich genommen echte Dringlichkeit. Es ist die ehrliche Einordnung: kritisch und in den meisten Distributionen ungepatcht, aber nicht als aktiv angegriffen bestätigt.
Unaffected starting at (NVD vendor data, matches the kernel's own
per-branch fixes exactly):
5.10.272 5.15.223 6.1.190 6.6.159
6.12.113 6.18.56 7.2.10 (original fix tagged for mainline 7.3)
Distro status, read from each vendor's own tracker as of this writing:
Red Hat (RHSB-2026-016): Critical impact. No fixed version or
errata named. "Expediting the release
of fixes." Last updated 2026-10-30.
Ubuntu (security tracker): every supported release, 16.04-26.10,
Vulnerable or Vulnerable, work in
progress. Only 14.04 (out of support)
is clear.Was bestätigt ist, und was online bislang nur eine Behauptung ist
Zwei weitere Dinge kursieren zu dieser CVE, und ich werde keines von beiden klären, weil die Aktenlage das nicht zulässt. Eine Version der Ereignisse besagt, Red Hat habe dies zunächst mit 5.9 bewertet, dann mit 8.1, dann mit 9.8, wobei die Eskalation teilweise auf Anthropics Offenlegung der Exploit-Zeiten zurückgeführt wird. Red Hats aktuelles Bulletin zeigt schlicht keine Bewertung, keinen Vektor und überhaupt keine Bewertungshistorie, sodass diese konkrete Geschichte von 5.9 über 8.1 zu 9.8 durch die einzige verfügbare Primärquelle weder bestätigt noch widerlegt wird.[2]
Die andere Frage ist, ob ein funktionierender Exploit-Proof-of-Concept tatsächlich öffentlich ist. Eine Quelle behauptet, PoCs seien seit dem 2026-10-29 auf GitHub verfügbar; andere Berichte sagen, der Exploit sei nie veröffentlicht worden. Ich habe in keiner Richtung ein funktionierendes PoC-Repository gefunden oder verifiziert. Wenn dir jemand mit Überzeugung sagt, welche der beiden Versionen stimmt, verlange das Repository, nicht die Behauptung.
Was diese Woche wirklich zu prüfen ist
In der Reihenfolge, die tatsächlich zählt, nicht in der, die die beste Schlagzeile ergibt.
Patch and verify, in order:
[ ] Confirm the kernel actually RUNNING, not the changelog: 5.10.272 /
5.15.223 / 6.1.190 / 6.6.159 / 6.12.113 / 6.18.56 / 7.2.10 or later.
[ ] If your distro hasn't shipped a fixed build yet, check its own
tracker directly -- don't trust a blog post's snapshot of it,
this one included. Apply Red Hat's interim nftables rule in the
meantime: drop inbound IPv4 TCP with IP header length > 5.
[ ] Check net.ipv4.tcp_migrate_req. If it's 1, or a BPF
SK_REUSEPORT_SELECT_OR_MIGRATE program is attached, the second
trigger path is open regardless of MPTCP.
[ ] Disable MPTCP if you want to (net.mptcp.enabled=0) -- a
reasonable attack-surface reduction, but record it as exactly
that, not as the fix for this CVE.
[ ] Don't use CISA's KEV list as a signal of how exposed you are
here. As of this writing this CVE isn't on it, and that's a
statement about confirmed in-the-wild use, not about your risk.Das Bulletin sagte „Use-after-free“. Der Diff sagte, wo genau
Jedes Bulletin zu dieser CVE wiederholt dieselben drei Worte: Use-after-free, Kernel, IPv4. Keines davon sagt für sich allein, dass der eigentliche Fehler die Wahl von kfree() statt kfree_rcu() in zwei Destruktoren war, oder dass der kursierende MPTCP-Ratschlag die von einem Exploit gewählte Tür behandelt, als sei sie die einzige Tür im Gebäude. Der Diff hat mir das gesagt. Das Bulletin nicht, und es hat es auch nicht versucht: Das ist nicht die Aufgabe eines Bulletins.
Genau das ist die Lücke, nach der ich bei einer Secure-Code-Review suche: nicht, ob ein Changelog „behoben“ sagt, sondern ob der tatsächliche Diff die eigentliche Ursache adressiert oder nur den einen Pfad, den jemand zufällig als Erstes gefunden hat. Wenn du C- oder C++-Code mit demselben Muster aus geteiltem Besitz und verzögerter Lebensdauer pflegst, über RCU oder anders, und möchtest, dass jemand die Destruktor-Pfade genau mit dieser Frage im Kopf liest, ist das genau die Art von Review, die ich mache. Sag mir, was bei dir läuft, dann grenzen wir den Umfang ein.
Quellen
- [1] NVD: Detailseite zu CVE-2026-98432
- [2] Red Hat: Sicherheitsbulletin RHSB-2026-016
- [3] Canonical (Ubuntu): Sicherheits-Tracker für CVE-2026-98432
- [4] Anthropic (Frontier Red Team): „Discovering vulnerabilities with Claude“
- [5] Linux-Kernel-Stable-Tree: der fixende Commit, gelesen über seinen öffentlichen GitHub-Spiegel
- [6] AI Weekly: Bericht zu Anthropics Behauptung über den verketteten Exploit
- [7] The Hacker News: Bericht zu Anthropics Behauptung über den verketteten Exploit
- [8] CISA: Known Exploited Vulnerabilities Catalog, gefilterte Abfrage
- [9] CISA: Known Exploited Vulnerabilities Catalog, JSON-Feed
Soll das auch in Ihrem Produkt geprüft werden?
Security Code-ReviewMöchten Sie lernen, solche Schwachstellen selbst zu finden?
Secure-Code-Review-Kurs im Einzeltraining