flawopen.com/Teardowns/cve-2024-26585-linux-tls-tx-work-close-race
CVE-2024-26585: TLS-Schließrace im Linux-Kernel
Bei Linux-kTLS konnte der Abschluss sendmsg/recvmsg wecken, bevor TX-Arbeit eingereiht war. Der Fix reiht die Arbeit zuerst ein.
Ein Mitarbeiter sagt einem wartenden Kollegen „fertig“, bevor er seine letzte Aufgabe in die gemeinsame Warteschlange legt. In der Lücke kann der Kollege den Betrieb schließen und vorhandene Aufgaben abbrechen; danach stellt der Mitarbeiter noch eine Aufgabe ein. Der Kernel-Fix reiht TLS-Sendearbeit ein, bevor er den Abschluss signalisiert.
Kernkonzepte & Begriffe
kTLS- TLS im Linux-Kernel, das TLS-Datensätze im Netzwerkpfad des Kernels verarbeitet.
Asynchroner Kryptoabschluss- Callback, der nach Abschluss einer asynchronen TLS-Verschlüsselung ausgeführt wird.
`complete()`- Linux-Completion-Primitive, die einen auf das Ende eines Vorgangs wartenden Thread weckt.
Verzögerte TX-Arbeit- Eingereihte Kernel-Arbeit, die die TLS-Datenübertragung nach der Verschlüsselung fortsetzt.
Framework-Zuordnungen
- CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-362
Ursachenanalyse
In net/tls/tls_sw.c konnte tls_encrypt_done() complete() für den auf sendmsg()/recvmsg() wartenden Thread aufrufen, bevor die verzögerte TX-Arbeit für den ersten Datensatz geplant wurde. Der geweckte Thread kann zurückkehren und den Socket schließen, während der Callback die Arbeit noch einreiht. Dadurch konkurrieren Socket-Schließung und TX-Arbeitsplanung. Der Upstream-Commit e01e3934a1b2 kehrt die Reihenfolge um: Liegt der Datensatz am Anfang von ctx->tx_list, wird ctx->tx_work vor dem Aufruf von complete() geplant. Die CVE-Mitteilung beschreibt eine Race Condition; die zitierten Quellen belegen nicht die früheren Aussagen zu MSG_ZEROCOPY, freigegebenen Netzwerkseiten, Überschreiben oder einem Fix mit refcount_inc_not_zero().
Schritt-für-Schritt Angriffsablauf
1. TLS-Übertragung beginnt
Ein Prozess nutzt den kTLS-Sendepfad, auf dem Datensatzverschlüsselung asynchron enden kann.
2. Callback prüft die Reihenfolge
tls_encrypt_done() prüft, ob der abgeschlossene Datensatz am Anfang von ctx->tx_list steht.
3. Wecken konkurriert mit dem Schließen
Vor dem Patch konnte der Callback den Thread mit complete() wecken und TX-Arbeit erst danach einreihen; dazwischen konnte der Thread den Socket schließen.
4. Patch ordnet die Übergabe
Der Fix reiht zuerst verzögerte TX-Arbeit ein und signalisiert erst danach den Abschluss; so kann der Thread nicht vor der Planung fortfahren.
Quellcode: Verwundbar vs. Sicher
// Relevante Reihenfolge in net/tls/tls_sw.c vor e01e3934a1b2
bool ready = false;
if (rec == first_rec)
ready = true;
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
if (!ready)
return;
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
// Relevante Reihenfolge in net/tls/tls_sw.c nach e01e3934a1b2
if (rec == first_rec) {
// Stellen Sie die Sendeaufgabe ein, bevor Sie den übermittelnden Thread aufwecken.
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
}
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
Checkliste für Engineering & Systemsicherheit
- ✓Aktualisieren Sie auf einen unterstützten Distributionskernel mit dem
CVE-2024-26585-Backport; beachten Sie den Herstellerhinweis, da stabile Kernel Fixes zurückportieren. - ✓Reihen Sie in asynchronen Callbacks Folgearbeit vor dem Abschlusssignal ein, wenn der geweckte Thread das gemeinsame Objekt schließen kann.
- ✓Synchronisieren Sie beim Schließen das Abbrechen oder Leeren der Arbeit so, dass Callbacks nach dem Abbruchzeitpunkt keine neue Arbeit einreihen.
- ✓Ergänzen Sie einen kontrollierten Nebenläufigkeitstest für asynchronen TLS-Abschluss gegen Socket-Schließung und prüfen Sie die Reihenfolge der Arbeit.
- ✓Setzen Sie
MSG_ZEROCOPYoder Hardwareverschlüsselung nicht als Voraussetzung voraus; die Upstream-Beschreibung nennt asynchronen Kryptoabschluss und TX-Planung.