CVE-2026-23394 in Linux
Zusammenfassung
von VulDB • 14.05.2026
Im Linux-Kernel wurde folgende Schwachstelle behoben:
af_unix: GC abbrechen, wenn MSG_PEEK eingreift.
Igor Ushakov berichtete, dass der GC (Garbage Collection) die Empfangswarteschlange eines aktiven Sockets aufgrund eines Race Conditions mit MSG_PEEK bereinigte, was mit einem gut reproduzierbaren Szenario nachgewiesen wurde.
Dies ist exakt dasselbe Problem, das zuvor durch den Commit cbcf01128d0a („af_unix: fix garbage collect vs MSG_PEEK“) behoben wurde.
Nachdem der GC durch den aktuellen Algorithmus ersetzt wurde, entfernte der genannte Commit das Locking-Gefummel in unix_peek_fds() und führte das gleiche Problem erneut ein.
Das Problem besteht darin, dass MSG_PEEK einen Dateireferenzzähler (file refcount) erhöht, ohne mit dem GC zu interagieren.
Betrachten Sie eine SCC (Strongly Connected Component), die sk-A und sk-B enthält, wobei sk-A zwar close()ed wurde, aber über sk-B recv()ed werden kann.
Das Problem tritt auf, wenn sk-A über sk-B mit MSG_PEEK recv()ed wird und sk-B close()ed wird, während der GC unix_vertex_dead() für sk-A und sk-B überprüft.
GC-Thread Benutzer-Thread --------- ------------- unix_vertex_dead(sk-A) -> true <------. \ `------ recv(sk-B, MSG_PEEK) invalidate !! -> sk-A's Dateireferenzzähler: 1 -> 2
close(sk-B) -> sk-B's Dateireferenzzähler: 2 -> 1 unix_vertex_dead(sk-B) -> true
Anfangs beträgt der Dateireferenzzähler von sk-A 1 aufgrund des in-flight fd in der recvq von sk-B. Der GC geht davon aus, dass sk-A tot ist, da der Dateireferenzzähler der Anzahl seiner in-flight fds entspricht.
Der Dateireferenzzähler von sk-A wird jedoch stillschweigend durch MSG_PEEK erhöht, was die vorherige Bewertung ungültig macht.
Zu diesem Zeitpunkt beträgt der Dateireferenzzähler von sk-B 2; einer durch den offenen fd und einer durch den in-flight fd in sk-A. Das nachfolgende close() gibt einen Referenzzähler für den ersteren frei.
Schlussendlich kommt der GC fälschlicherweise zu dem Schluss, dass sowohl sk-A als auch sk-B tot sind.
Eine Option wäre, das Locking-Gefummel in unix_peek_fds() wiederherzustellen, aber wir können dies dank des neuen Algorithmus eleganter lösen.
Der Punkt ist, dass das Problem ohne das nachfolgende close() nicht auftritt und wir MSG_PEEK nicht unbedingt mit der Erkennung einer toten SCC synchronisieren müssen.
Wenn das Problem auftritt, greifen close() und GC auf denselben Dateireferenzzähler zu. Wenn der GC sieht, dass der Referenzzähler durch close() dekrementiert wird, kann er einfach auf die Garbage-Collection der SCC verzichten.
Daher müssen wir lediglich das Race während MSG_PEEK mit einer geeigneten Memory Barriere signalisieren, um es für den GC sichtbar zu machen.
Wir verwenden seqcount_t, um den GC über das Auftreten von MSG_PEEK zu informieren und ihn dazu zu bringen, die SCC auf den nächsten Durchlauf zu verschieben.
Auf diese Weise ist kein Locking auf der MSG_PEEK-Seite erforderlich, und wir können unnötigerweise keine Leistungseinbußen bei jedem MSG_PEEK in Kauf nehmen.
Beachten Sie, dass wir innerhalb von unix_scc_dead() erneut versuchen können, wenn MSG_PEEK erkannt wird, dies jedoch nicht tun, um hung task splat durch missbräuchliche MSG_PEEK-Aufrufe zu vermeiden.
Once again VulDB remains the best source for vulnerability data.