Rust wird Linux vor KI retten, sagt Greg Kroah-Hartman
Das bedeutet jedoch nicht, dass Greg Kroah-Hartman, der Maintainer des stabilen Linux-Kernels, glaubt, dass Rust Magie ist.
Wichtigste Erkenntnisse
- Rust wird Linux vor den inhärenten Sicherheitsschwächen von C bewahren.
- Linux könnte angesichts einer Flut an von KI entdeckten Sicherheitsproblemen Hilfe gebrauchen.
- In Zukunft wird immer mehr Linux-Code in Rust geschrieben werden.
Auf der Rust Week, der größten Rust-Konferenz der Welt, in Utrecht, Niederlande, eröffnete Greg Kroah-Hartman, der Maintainer des stabilen Linux-Kernels, mit den Worten: „Ich bin hier, um über unvertrauenswürdige Daten und Linux zu sprechen - sowie darüber, wie Rust uns retten wird.“ Nach „einem langen Monat oder zwei in der Kernel-Sicherheitsliste“ trieb er diesen Gedanken noch weiter: „Ich werde nun eine noch kühnere Aussage machen: ‚Ihr werdet Linux retten.‘ Entschuldigung, es liegt ganz bei euch.“
Rettung? Linux muss gerettet werden?
Er sprach von dem plötzlichen Auftreten zahlreicher schwerwiegender Sicherheitslücken in Linux - wie Dirty Frag, Copy Fail und Fragnesia -, die dank der neuesten KI-Programme zur Fehlererkennung entdeckt wurden.
Infolgedessen sagte Kroah-Hartman, der seit 2005 „jeden einzelnen Kernel-Sicherheitsfehler je gesehen hat“, dass das Kernel-Team mittlerweile „13 CVEs [Common Vulnerabilities and Exposures] pro Tag herausgibt - oder so etwas Verrücktes“. Er ist der Ansicht, dass Rust eine der wenigen realistischen Möglichkeiten ist, die Anzahl jener Fehler zu reduzieren, die durch die traditionellen Fehlerbehandlungs- und Ressourcenmanagement-Probleme in C entstehen.
Kroah-Hartman veranschaulichte diese Fallstricke anhand echter C-Fehler im Kernel - darunter ein 15 Jahre alter Bluetooth-Fehler, bei dem ein Zeiger ohne Prüfung dereferenziert wurde, sowie ein Xen-Fehler, bei dem „wir vergessen haben, einen Lock zu entfernen“ in einer Fehlerbehandlungsroutine. „Die meisten Fehler im Kernel sind solch kleine, unbedeutende Probleme“, erklärte er. „Fehlerbedingungen werden nicht überprüft, Locks werden vergessen, Speicher wird nicht freigegeben - und mit der Zeit häufen sich die Sicherheitslücken. Dadurch stürzt der Kernel ab. Das ist es, womit wir in C zu kämpfen haben. Deswegen mögen wir C nicht.“
Kroah-Hartman argumentierte, dass der „größte Vorzug von Rust“ darin bestehe, solche Fehler bereits zur Kompilierzeit zu erkennen - anstatt erst bei der Code-Überprüfung. Bezüglich des Lockings wies er beispielsweise auf Rusts Locking-Abstraktionen im Kernel hin: „Die einzige Möglichkeit, auf interne Zeiger von Strukturen zuzugreifen, besteht darin, das Lock zu erlangen und es anschließend automatisch wieder freizugeben. Der Compiler übernimmt das; alles ist gesichert, das Locking funktioniert einwandfrei - und alle sind zufrieden. Man kann einfach keinen Code schreiben, der auf diese Werte zugreift … ohne zuvor das Lock zu erlangen. Der Compiler erlaubt das schlichtweg nicht.“
Diese Eigenschaften, so argumentierte er, beseitigen direkt einen großen Teil der Fehler, die er feststellt: „Das wird uns zwei Dinge ersparen. Erstens: 60 Prozent der Fehler im Kernel verschwinden sofort. Danke.“ Der Nutzen besteht darin, dass die Überprüfungen früher und automatischer erfolgen: „Wenn das bereits zur Kompilierzeit passiert - und nicht erst bei der Code-Review - dann machen Sie mich nicht zum Maintainer, der Ihren Code lesen und sagen muss: ‚Aha, Sie überprüfen den Fehlerwert ordnungsgemäß. Und Sie setzen die Locks an der richtigen Stelle ein?‘ Rust bietet uns das kostenlos an. Das ist das Beste überhaupt.“
Selbst wenn Rust morgen verschwinden würde, so argumentierte Kroah-Hartman, hätte es den Kernel bereits dazu gebracht, den C-Code sowie die Schnittstellen zu bereinigen. Er erkannte den Einfluss von Rust uneingeschränkt an: „Wir haben uns das von Rust abgeschaut. Danke. Es ist eine gute Idee - selbst wenn Rust morgen verschwinden würde, hätten wir den C-Code im Kernel bereits stark bereinigt und die entsprechenden Konzepte übernommen. Wir danken Ihnen: Allein durch seine Existenz haben Sie Linux verbessert.“
Er beschrieb neue „Guards“ sowie „scoped locks“ in C, die von Rust inspiriert sind: „Jetzt haben wir das - wir verfügen über scoped locks und Allokatoren in C. Zudem haben wir neuen Code hinzugefügt, der es uns schwerer macht, Fehler zu machen - aber vor allem vereinfacht er das Programmieren.“ Mit mehr als 5.000 Entwicklern und nur etwa 700 Maintainern sei die Überprüfungszeit die knappste Ressource, so er. Deshalb seien Muster, die die Korrektheit des Codes offensichtlich machen, von entscheidender Bedeutung: „Wir optimieren darauf, den Code leicht überprüfbar zu machen… Wenn ich Ihren Code leichter überprüfen kann, reicht ein Blick darauf aus, um zu sagen: ‚Hey, Sie haben es offensichtlich richtig gemacht - weil Sie dieses Muster verwenden. Alles in Ordnung, weniger Fehler.‘“
Die Rust-Bindings erfordern auch auf der C-Seite tiefgreifendere Änderungen. Er erinnerte an eine frühe Konferenz zu Rust-for-Linux und sagte, dass er, als er „hunderte Zeilen Rust-Code sah, die dazu dienten, lediglich zwei Zeilen C-Code zu verarbeiten“, erkannte: „Ich kann den C-Code ändern. Wir können den C-Code so verändern, dass der Rust-Code einfacher wird. Wir haben kein Problem damit, beide Seiten dieser ‚Barriere‘ zu verändern. Lasst uns das tun.“ Heute schreibt er dem Rust-for-Linux-Team zu, die Schnittstellen der Treiber neu gestaltet zu haben: „Die dabei geltenden Regeln sowie die Funktionsweise der Traits und Schnittstellen im Zusammenspiel mit dem C-Code im Kernel werden es einfacher machen, Treiber zu schreiben - und es wird schwieriger, Fehler zu machen… Sie haben großartige Arbeit geleistet.“
Abgesehen von den Sprachfunktionen verknüpfte Kroah-Hartman Rust direkt mit einer breiteren Initiative im Zusammenhang mit unvertrauenswürdigen Daten sowie der Idee, dass „alle Eingaben gefährlich sind“. In Anlehnung an einen Satz aus der Microsoft-Sicherheitsstrategie sagte er zu den Zuhörern: „Falls Sie sich sonst nichts aus meinem Vortrag merken, dann bitte nur diese vier Wörter. Sie stammen aus der Microsoft-Sicherheitsstrategie - vor vielen, vielen Jahren. Man erkannte damals, dass alle Eingaben potenziell gefährlich sind. Man muss daher alle Eingaben überprüfen.“
Er beschrieb die laufenden Arbeiten an einem „untrusted“-Typ-Wrapper sowie einer Validierungsmethode in Rust, die eine explizite Validierung an der Stelle erzwingt, an der Daten von einem untrusted- in einen trusted-Zustand übergehen. „Wir haben etwas, das als ‚untrusted‘-Typ bezeichnet wird und dem Daten hinzugefügt werden kann. Jedes Mal, wenn man tatsächlich auf diese Daten zugreifen möchte - es handelt sich dabei lediglich um einen Typ, also keinen eigentlichen Code - gibt dies dem Compiler einen Hinweis: Man muss zuerst eine Validierung durchführen, bevor man darauf zugreifen darf.“ Der wichtigste Vorteil für Code-Reviewer, so sagte er, sei, dass „sich alles auf die Übergabepunkte konzentriert“: „In einem einzigen Abschnitt des Codes kann man sämtlichen Code sehen, der die Validierung des Übergangs von untrusted-Daten aus dem Benutzerbereich zu trusted-Daten vornimmt.“
Dieses Modell lässt sich auch auf zunehmend feindselige Hardware anwenden: „Beim Modell sowie bei den Kerneln vertrauen wir der Hardware nicht einmal. Hardware ist voller Fehler - mittlerweile gibt es sogar bösartige Hardware, und wir sehen immer mehr davon.“ Sein Ziel ist es, solche Daten als „nicht vertrauenswürdig“ zu kennzeichnen und sie über das Typensystem zu verfolgen; anschließend will er seine Überprüfungsbemühungen gezielt darauf konzentrieren. „Das wird uns wirklich retten - schließlich vertrauen wir den Daten nicht. Ich glaube, das wird Linux retten: die Kombination aus all den anderen Maßnahmen sowie den als „nicht vertrauenswürdig“ gekennzeichneten Daten. Ich denke, dadurch lassen sich 80 Prozent aller bekannten Sicherheitslücken beseitigen - und das ist eine enorme Zahl.“
Rust ist keine Magie
Das bedeutet nun nicht, dass er denkt, Rust sei Magie - ist es nicht. Er nannte ein der ersten Rust-Komponenten, die in den Kernel integriert wurden: Die Logik zur Anzeige von QR-Codes, die verwendet wird, wenn der Kernel abstürzt. „Diese Logik wurde in Rust geschrieben. Bekanntlich enthielt sie einen Speicherfehler: Es wurde ein Puffer sowie dessen Größe übergeben - der restliche Code überprüfte die Puffergröße jedoch nie. Dadurch konnte der Speicher willkürlich überschrieben werden; schließlich kann Rust genauso schlimm abstürzen wie C.“ Somit ist Rust „keine Wunderwaffe“.
Er ermutigt auch niemanden, den Linux-Kernel in Rust neu zu schreiben. Ein Teilnehmer fragte: „Ermutigen Sie tatsächlich dazu, bereits vorhandenen Code im Kernel mit [Rust] neu zu schreiben?“ Greg antwortete: „Nein, wir wollen keine Neuschreibungen. Also: Sofern Sie nicht der Maintainer und Eigentümer der jeweiligen Datei sind, nutzen Sie Rust nur für neue Code-Teile. Lassen Sie den bestehenden C-Code in Ruhe - danach können wir weiterentwickeln.“ Als Beispiel nannte er Binder, die zentrale Interprozesskommunikationsschicht von Android: Dort existieren vorübergehend sowohl eine C- als auch eine Rust-Implementierung, bis beide auf dem gleichen Stand sind. Danach „werden sie den C-Code löschen - denn ich vertraue ihnen, und sie sind die Eigentümer und Maintainer beider Implementierungen.“
Im Laufe der Zeit erwartet er, dass die Unterstützung neuer Hardware zunehmend auf Rust ausgerichtet wird: „Rust wird im Kernel im Laufe der Zeit weiterentwickelt werden. Einige Subsysteme haben bereits gesagt: ‚Hey, nur neue Grafikkartentreiber sollten in Rust geschrieben werden.‘ … Mittlerweile haben wir einen entscheidenden Punkt erreicht: Man kann nun wirklich gute Treiber für alle möglichen Subsysteme in Rust und Linux schreiben. Ich denke, im kommenden Jahr oder zwei wird man das beobachten können.“ Typisch für Kroah-Hartman fasste er dieses Modell als evolutionär zusammen: „Linux entwickelt sich weiter - es handelt sich dabei nicht um eine ‚intelligente Konstruktion‘. Im Laufe der Zeit kommen neue Treiber für neue Hardware hinzu. Man beginnt anschließend, diese neue Hardware zu nutzen; die alten Treiber werden nicht mehr verwendet. Irgendwann werden wir sie löschen - so wie wir es nach etwa 20 Jahren immer tun.“
In der Zwischenzeit sagte Kroah-Hartman zum Publikum: „Heute bestehen 36 Millionen Zeilen des Linux-Kernels aus C-Code, dazu kommen 113.000 Zeilen Rust-Code. Vor allem ist dieser Rust-Code als Bindings erforderlich.“ Da Treiber den Großteil des Kernels ausmachen, „mussten Alice Ryhl, eine führende Rust-Entwicklerin für Android, sowie die Entwickler von Rust-for-Linux Bindings für alles schreiben, um überhaupt einen kleinen Treiber in Rust programmieren zu können.“ Dadurch war die Community gezwungen, ihre übliche Regel gegen ungenutzten Code etwas zu lockern: „Wir mögen es auch nicht, Code zum Kernel hinzuzufügen, der nicht verwendet wird; daher ist es schwierig, Bindings hinzuzufügen - es sei denn, es gibt bereits Nutzer dafür. Es handelt sich also um ein klassisches Henne-Ei-Problem. Wir mussten diese Regel etwas beugen.“
Er wies auch auf kommende Implementierungen im echten Welteinsatz hin: „Android-Telefone werden, hoffentlich bald, erscheinen und den gesamten [Rust]-Code in Binder ausführen. Damit können bald Milliarden von Geräten Rust unter Linux nutzen.“
Was schließlich zahlreiche Hauptentwickler, einschließlich ihn selbst, von Rust überzeugte, war die Tatsache, dass es „das Code-Review vereinfacht“. Durch CI-[Continuous Integration]-Bots, die für die Erstellung von Builds sorgen, sowie Rusts Typensystem, das wichtige Invarianten gewährleistet, können die Entwickler „sich auf die Logik konzentrieren“ anstatt sich um Ressourcenverwaltung kümmern: „Ich kann mich auf diese eine Funktion konzentrieren. Ich muss mir um den Rest keine Sorgen machen - schließlich gehe ich davon aus, dass er korrekt funktioniert, weil er ordnungsgemäß erstellt wurde.“
Intern, so sagte er, hätten die leitenden Maintainer bereits eine Entscheidung bezüglich des Status von Rust getroffen: „Die Maintainer des Linux-Kernels treffen sich jedes Jahr, um zu besprechen, welche Fortschritte gemacht werden. Letztes Jahr sagten wir, dass das Rust-Experiment beendet sei - es ist kein Experiment mehr, sondern Realität.“ Die Begründung dafür: „Die Menschen, die dahinterstehen, sind vertrauenswürdig. Wir vertrauen ihnen. Wir wissen, was sie tun. Sie haben bewiesen, dass sie die nötige Arbeit leisten, um Rust zu einer tauglichen Programmiersprache für den Kernel zu machen - und wir werden dafür sorgen, dass dies gelingt. Also: Volles Tempo voraus! Und wie immer“, fügte er ironisch hinzu, „geht die Weltherrschaft weiter.“
