Der Integer-Überlauf steckt in der Attach-Funktion von shmat(4) und wurde mit Errata 018 behoben, ausgeliefert am 14. September – eingestuft nicht als Sicherheits-, sondern als Zuverlässigkeitskorrektur, obwohl er den Einstiegspunkt der gesamten Kette bildet. Das Use-after-free durch fehlerhafte Referenzzählung, das die Kette vervollständigt, wurde separat mit Errata 026 am 30. September als Sicherheitskorrektur geschlossen. Beide Korrekturen stehen über syspatch für alle Architekturen bereit; OpenBSD 7.8 erhielt zusätzlich den Fix für den Integer-Überlauf.
Ursache ist der Zähler shm_nattch für Shared-Memory-Anbindungen, der in den originalen BSD-Quellen von 1988 als vorzeichenbehafteter 16-Bit-Short mit einem Maximalwert von 32.767 definiert ist. OpenBSD übernahm den Typ und verbreiterte ihn nie. Der Exploit bindet 127 Shared-Memory-Segmente ein und erzeugt 259 Prozesse, womit der Zähler überläuft und auf −32.643 umschlägt. Eine Race Condition löst anschließend das Use-after-free aus: Wegen des beschädigten Referenzzählers gibt der Kernel Speicher frei, den andere Prozesse noch verwenden.
Ein zusätzlicher Out-of-bounds-Write überschreibt Zähler für Multicast-Mitgliedschaften im Kernel. Beim Schließen des betroffenen Sockets verändern die daraus folgenden Dekrementierungen Page-Table-Einträge und schalten eine Benutzerspeicher-Abbildung auf Supervisor-Zugriff um – damit sind SMAP und SMEP ausgehebelt. Danach überschreibt der Exploit einen Funktionszeiger an einer vorhersagbaren Kernel-Adresse und führt eigenen Code aus.
„Während OpenBSDs KARL das Kernel-Binary neu linkt, um Funktions- und Datenadressen zu randomisieren, bleiben die Speicherallokatoren des Kernels deterministisch“, schreibt der Forscher Andrew Griffiths. Weder der Boot-Time- noch der Best-Fit-Allokator randomisiert seine Basisadresse, sodass früh beim Systemstart angelegte Strukturen – darunter Funktionszeiger in den Handlern der Netzwerkschnittstellen lo0 und enc0 – auf derselben Hardware über Neustarts hinweg an identischen Adressen liegen. Der Exploit kommt deshalb ohne eine Lücke zur Informationsoffenlegung aus.
Über die beiden Errata hinaus schlägt Calif vier Härtungsmaßnahmen vor:
- Safe Unlinking für verkettete Listen im Kernel, wie es FreeBSD und NetBSD bereits einsetzen
- Randomisierung der selbstreferenziellen Page-Table-Abbildung
- Randomisierung des Kernel-Allokators
- compilergestützte Bounds-Prüfungen
Für beide Fehler ist bislang keine CVE-Nummer vergeben. Hinweise auf eine Ausnutzung in Angriffen gibt es nicht. Nach eigenen Angaben meldete Calif die Schwachstellen „Anfang dieses Jahres“ an OpenBSD; der Proof-of-Concept-Code liegt auf GitHub.
