Die Geschichte des Hubris-Bugs: Wer hat den Netzwerk-Switch getötet?
-
Was ist Hubris?
- Hubris ist ein Betriebssystem für tief eingebettete Systeme und wurde für Computer entwickelt, die nicht als Computer wahrgenommen werden, etwa im Inneren einer Tastatur.
- Es wurde entwickelt, um alle Aufgaben zu erledigen, die nötig sind, um die großen Prozessoren in einem Oxide Rack zu starten.
- Hubris ist ziemlich einzigartig; die für diese Geschichte relevanten Aspekte werden weiter unten erklärt.
-
Der Tatort
- Arjen Roodselaar, ein Kollege bei Oxide, der für die Firmware des Netzwerk-Switches zuständig ist, testete Änderungen an der Power-Sequenz und der Taktkonfiguration.
- Nach einer kleinen Änderung ließ sich der Switch plötzlich nicht mehr einschalten.
- Teile der Firmware reagierten noch, aber der kritische Teil, der die Reihenfolge der Stromversorgung steuert, war stehen geblieben.
-
Mehr aus begrenztem RAM herausholen
- Die günstigen Mikrocontroller, auf denen Hubris läuft, verfügen über sehr begrenztes RAM und Flash.
- Hubris besteht aus vielen separat kompilierten Programmen, die Aufgaben genannt werden, und hat daher einen etwas höheren Ressourcenbedarf als andere Betriebssysteme.
- Kollege Matt Keeter hatte das System kürzlich intelligenter gemacht, sodass es mehrere Bereiche in Zweierpotenzgrößen nutzt, um Aufgaben möglichst dicht zu packen.
-
Die rauchende Waffe
- Arjen untersuchte den ausgefallenen Netzwerk-Switch mit Humility, dem Debugger für Hubris.
- Mit dem Befehl
humility tasksließ er sich die Liste der auf dem Prozessor laufenden Aufgaben und ihre Statusinformationen ausgeben. - Dabei stellte er fest, dass die Aufgabe für die Power-Sequenz wegen eines Speicherfehlers bereits 115-mal neu gestartet worden war.
-
Rust-Borrows in Hubris-IPC über Aufgaben hinweg erweitern
- Hubris-Aufgaben können sich über IPC gegenseitig Nachrichten senden.
- Diese Nachrichten sehen Funktionsaufrufen sehr ähnlich und verhalten sich auch so.
- Wenn eine Aufgabe Speicher an eine andere Aufgabe ausleiht, darf sie dabei nicht versuchen, Speicher auszuleihen, den sie tatsächlich nicht besitzt.
-
Wenn Features angreifen
- Zwei Features können zusammen zu einem Bug werden.
- Das Packen von Aufgaben arbeitet im Build-System opportunistisch.
- Wenn sich die Größe von Aufgabe A geringfügig ändert, kann sich dadurch die Lage der MPU-Regionsgrenze einer nicht verwandten Aufgabe B verschieben.
-
Ein Anruf aus dem Inneren!
- Der Algorithmus für den Speicherschutz musste geändert werden.
- Ausgeliehener Speicher muss eine MPU-Region überschreiten dürfen.
-
Mit Hubris scheitern
- Mehrere Dinge, die beim Systemausfall nicht passiert sind.
- Der defekte Netzwerk-Switch konnte in drei Stunden repariert werden.
- Dabei halfen Fehlerisolation, sicheres Fehlschlagen, sicherer Shared Memory, das gemeinsame Design von Kernel und Debugger, die Einfachheit von Entwurf und Implementierung sowie die enge, nicht-hierarchische Zusammenarbeit im Team.
Meinung von GN⁺
- Dieser Artikel zeigt anhand der Suche und Behebung eines Bugs im Betriebssystem Hubris, wie wichtig robustes Softwaredesign selbst in komplexen Systemen ist.
- Der Prozess der Fehlerfindung und -behebung unterstreicht, wie wichtig Teamarbeit und effiziente Debugging-Werkzeuge bei der Lösung komplexer Probleme im Software Engineering sind.
- Er zeigt außerdem, wie entscheidend Isolations- und Fehlermanagement-Funktionen in Systemen wie Hubris sind. Sie können Stabilität und Wartbarkeit eines Systems erheblich verbessern.
- Der Artikel veranschaulicht zudem, wie mit der sicheren Programmiersprache Rust Speichersicherheit gewährleistet und die Zahl von Bugs minimiert werden kann. In Systemen mit Rust treten solche Bug-Typen selten auf, was zeigt, wie wirksam Rusts Garantien zur Speichersicherheit in der Praxis sind.
- Ähnliche Projekte oder Produkte mit vergleichbaren Funktionen sind seL4, FreeRTOS und Zephyr; dabei handelt es sich jeweils um Betriebssysteme für eingebettete Systeme mit unterschiedlichen Zielen und Eigenschaften.
- Wer Systeme wie Hubris einführt, sollte Faktoren wie Speicherbeschränkungen, Aufgabenverwaltung und das Design des IPC-Mechanismus berücksichtigen. Zu den Vorteilen solcher Systeme zählen robustes Systemdesign und sichere Speicherverwaltung, während die Komplexität des Systems und die Lernkurve zu den Nachteilen gehören können.
1 Kommentare
Hacker-News-Kommentare
Review des Hubris-Kernel-Codes
Lob für die Stellenanzeige
Code-Review und Vorschlag
TaskDesc::regionshinzuzufügen.Einschätzung des Debugging-Prozesses
Interesse an der Kultur des Oxide-Teams
Link zu weiterführenden Informationen
Mitgefühl für Probleme beim Debugging
Vorschlag zum Umgang mit der Hardware
Lob für die Arbeit von Oxide
Reaktion auf den Namen des Betriebssystems