Veröffentlichung von Rust 1.81. Hindernisse beim Voranbringen von Rust im Linux-Kernel.

Es wurde eine neue Version der Programmiersprache Rust 1.81 veröffentlicht, die ursprünglich von Mozilla entwickelt und nun von der unabhängigen gemeinnützigen Organisation Rust Foundation weiterentwickelt wird. Die Sprache konzentriert sich auf sicheres Arbeiten mit Speicher und bietet Mittel, um hohe Parallelität bei der Ausführung von Aufgaben zu erreichen, ohne einen Garbage Collector und Runtime (Runtime beschränkt sich auf die grundlegende Initialisierung und die Unterstützung der Standardbibliothek) zu verwenden.

Die Methoden zur Speicherverwaltung in Rust befreien den Entwickler von Fehlern beim Umgang mit Zeigern und schützen vor Problemen, die durch niedrige Speicherverwaltung entstehen, wie z. B. den Zugriff auf Speicherbereiche nach deren Freigabe, Dereferenzierung von Nullzeigern, Pufferüberläufen usw. Zur Verbreitung von Bibliotheken, zur Gewährleistung des Builds und zur Verwaltung von Abhängigkeiten wird der Paketmanager Cargo entwickelt. Für das Hosting von Bibliotheken wird das Repository crates.io unterstützt.

Sichere Speicherverwaltung wird in Rust während der Kompilierung durch Überprüfung von Referenzen, Nachverfolgung des Eigentums an Objekten, Berücksichtigung der Lebensdauer von Objekten (Sichtbarkeitsbereiche) und Bewertung der Korrektheit des Zugriffs auf den Speicher während der Ausführung des Codes gewährleistet. Rust bietet ebenfalls Mittel zum Schutz vor Überläufen bei Ganzzahlen, fordert die zwingende Initialisierung von Variablenwerten vor deren Verwendung und behandelt Fehler in der Standardbibliothek besser. Außerdem wird das Konzept der Unveränderlichkeit (immutable) von Referenzen und Variablen standardmäßig angewendet, und es bietet eine starke statische Typisierung zur Minimierung logischer Fehler.

Hauptneuheiten:

  • Der Trait core::error::Error wurde stabilisiert, der die ausgegebenen Fehlermeldungen definiert. Diese Änderung ermöglicht die Verwendung eines einheitlichen Traits Error in verschiedenen Bibliotheken, unabhängig von der Umgebung, einschließlich Bibliotheken, die nicht an die Standardbibliothek gebunden sind und das Attribut "#![no_std]" verwenden.
  • Die stabilen und instabilen Sortierfunktionen in der Standardbibliothek wurden aktualisiert, um neue Algorithmen zu verwenden, die eine höhere Geschwindigkeit und kürzere Kompilierungszeiten zeigen. In der Implementierung der neuen Sortieralgorithmen wird sichergestellt, dass falsch definierte Traits Ord erkannt werden und in solchen Fällen eine Fehlermeldung (panic) ausgegeben wird, anstelle von zufällig gruppierten Daten.
  • Im Linter wurde eine neue Prüfungsstufe 'expect' ("#[expect(lint)]") implementiert, die sicherstellt, dass die Prüfung durchgeführt wird und eine Warnung ausgegeben wird, falls die Prüfung nicht besteht (aufgrund eines Implementierungsfehlers oder einer Deaktivierung der Prüfung). Zum Beispiel kann beim Übertragen des Codebasis zur Verwendung der Prüfung undocumented_unsafe_blocks über Clippy "#[expect(clippy::undocumented_unsafe_blocks)]" angegeben werden, um sicherzustellen, dass alle unsafe-Blöcke während des Übergangs dokumentiert werden. Im Clippy wurden auch die Prüfungen clippy::allow_attributes und clippy::allow_attributes_without_reason implementiert, die den Austausch von Attributen "#[allow]" gegen "#[expect(lint)]" vereinfachen.
  • Es wurde die Möglichkeit eingeführt, den Grund für den Austausch von Prüfungsstufen (lint) zu dokumentieren, was neuen Entwicklern Informationen über die Gründe für die Hinzufügung bestimmter Prüfungen in Form von Compiler-Nachrichten bereitstellt. Zum Beispiel: #![deny(clippy::float_arithmetic, reason = "no hardware float support")]
  • Eine neue Charge von APIs wurde in den stabilen Bereich überführt, darunter wurden Methoden und Implementierungen von Traits stabilisiert:
    • core::error
    • hint::assert_unchecked
    • fs::exists
    • AtomicBool::fetch_not
    • Duration::abs_diff
    • IoSlice::advance
    • IoSlice::advance_slices
    • IoSliceMut::advance
    • IoSliceMut::advance_slices
    • PanicHookInfo
    • PanicInfo::message
    • PanicMessage

    Das Zeichen „const“, das die Verwendung in jedem Kontext anstelle von Konstanten bestimmt, wird in Funktionen angewendet:

    • char::from_u32_unchecked (Funktion)
    • char::from_u32_unchecked (Methode)
    • CStr::count_bytes
    • CStr::from_ptr

    Der Typ std::panic::PanicInfo wurde in std::panic::PanicHookInfo umbenannt (die Verwendung des alten Namens bleibt erhalten, allerdings wird dessen Nutzung ab der nächsten Version eine Warnung auslösen). Der Typ core::panic::PanicInfo bleibt unverändert, wird jedoch als separater Typ weiterentwickelt. Diese Trennung der Typen ermöglicht die Implementierung unterschiedlicher methoden, die spezifisch im Kontext von snd und no_std sind.

  • Der Übergang zu ABI C-unwind (‘extern «C-unwind»‘) wurde abgeschlossen, was sich von ABI ohne den Suffix «-unwind» (‘extern «C»‘) dadurch unterscheidet, dass es sicheres Verhalten (safe) gewährleistet, falls der beim Programmabbruch oder beim Auslösen einer Ausnahme nach C++ initiierte «Unwind»-Prozess die ABI-Grenze überschreitet (zum Beispiel, wenn eine Ausnahme, die im Code einer Programmiersprache auftritt, beim Unwind den Stack berührt, der mit dem Code einer anderen Programmiersprache verbunden ist). Ab der Veröffentlichung von Rust 1.81 wird bei nicht abgefangenen Unwinds in ABI ‘extern «C»‘ ein Abbruch ausgeführt.
  • Ein drittes Unterstützungsniveau für die Plattformen i686-unknown-redox, xtensa-esp32-none-elf, xtensa-esp32s2-none-elf, xtensa-esp32s3-none-elf, xtensa-esp32-espidf, xtensa-esp32s2-espidf und xtensa-esp32s3-espidf wurde implementiert. Das dritte Niveau bietet grundlegende Unterstützung, jedoch ohne automatisierte Tests, Veröffentlichung offizieller Builds und Überprüfung der Buildfähigkeit des Codes.
  • Ein zweites Unterstützungsniveau für die Zielplattformen loongarch64-unknown-linux-musl und arm64ec-pc-windows-msvc wurde umgesetzt. Das zweite Unterstützungsniveau garantiert den Build.
  • Für Linux-Systeme auf der LoongArch-Plattform steht ein vollständiges Toolkit und Profiler zur Verfügung.
  • Eine Sicherheitsanfälligkeit (CVE-2024-43402) in std::process::Command wurde behoben, die nur auf der Windows-Plattform auftritt und einen Exploit-Workaround für die zuvor behobene Schwachstelle BatBadBut beseitigt, die sich auf die Verarbeitung von Sonderzeichen bei der Verwendung von Command::arg und Command::args bezieht, die für die direkte Übergabe von Argumenten an den Prozess ohne deren Verarbeitung durch einen Befehlinterpreter gedacht sind. Tatsächlich wurde beim Starten von bat- und cmd-Skripten der Prozess cmd.exe mit eigener Argumenttrennungslogik gestartet. Der Schutzüberlauf basiert darauf, dass Windows führende Leerzeichen und Punkte in Pfaden entfernt, das heißt, eine Datei mit der Erweiterung «.bat. .» wird als «.bat» behandelt.

Darüber hinaus ist der Rücktritt von Wedson Almeida Filho, dem Projektleiter des Rust for Linux-Projekts, zu vermerken, der sich mit der Integration von Mitteln zur Entwicklung in der Programmiersprache Rust in den Linux-Kernel beschäftigt. Nach seinem Rücktritt bleiben dem Projekt noch zwei weitere Leitungspersonen – Miguel Ojeda, Autor und Hauptentwickler des Rust-for-Linux-Projekts, und Alex Gaynor, ein ehemaliger Direktor der Python Software Foundation, der sich nun auf die Förderung von Rust konzentriert. Der zurückgetretene Leiter, der vor 4 Jahren zum Projekt kam, ist Mitarbeiter von Microsoft und Autor eines experimentellen Treibers mit der Implementierung des EXT2-Dateisystems, der in Rust geschrieben wurde. In letzter Zeit lag Almeida's Fokus auf der Schaffung von Werkzeugen zur Entwicklung von Dateisystemen in Rust. In diesem Jahr hat Almeida 17 Commits ins Rust-for-Linux-Repository eingebracht (zum Vergleich hat Miguel Ojeda 53 Commits hinzugefügt).

Als Grund für seinen Rücktritt wird ein Mangel an Energie und Enthusiasmus genannt, die früher zur Reaktion auf einige nichttechnische Nebensächlichkeiten (nontechnical nonsense) dienten. Almeida ist der Meinung, dass Entwickler viel Energie in Streitigkeiten über unwichtige Fragen aufwenden müssen, die das wichtigere globale Ziel in den Hintergrund drängen. Almeida bleibt überzeugt, dass die Zukunft der Kernel in der Verwendung von Programmiersprachen liegt, die einen sicheren Umgang mit Speicher bieten, und wenn die Linux-Entwicklergemeinschaft dies nicht versteht, wird Linux durch einen anderen Kernel ersetzt, wie es einst mit Unix geschah.

Die Unterstützer des Rust-for-Linux-Projekts sehen sich dem Widerstand erfahrener alter Kernel-Entwickler gegenüber, die keinen Bedarf sehen, eine neue Sprache zu lernen. In seinem Rücktrittsschreiben verweist Almeida als Beispiel auf eine Diskussion, die während der Präsentation von Almeida und Kent Overstreet auf der Konferenz „Linux Storage, Filesystem, Memory-Management, and BPF Summit“ stattfand und sich mit der Nutzung von Rust zur Entwicklung von Dateisystemen beschäftigte. Ted Ts’o, Autor der Dateisysteme ext2/ext3/ext4, kritisierte die Bemühungen um die Implementierung von Rust und verglich die Initiative Rust-for-Linux mit dem Versuch, alle zu einer Religion von Rust zu bekehren.

Als Antwort auf Almeidas Absicht, eine Bindung über die in C geschriebenen Schnittstellen für Dateisysteme zu schaffen, um sie im Code in Rust zu verwenden, wies Ted Ts'o darauf hin, dass eine solche Bindung unvermeidlich zu Problemen führen wird, da jede Änderung der C-Schnittstellen und das Durchführen von Refactoring eine Anpassung der Bindung für Rust erfordern wird. Er möchte keine zusätzliche Verantwortung für die Behebung von Problemen im Rust-Code und die Überwachung des Zustands der Rust-Bindung übernehmen. Der Code in C entwickelt sich ständig weiter, und wenn eine Änderung die Funktionalität der Bindung für Rust beeinträchtigt, wirkt sich das auch auf alle davon abhängigen Dateisysteme aus.

Ted ist ebenfalls der Meinung, dass die Bindung für Rust in absehbarer Zukunft von untergeordneter Rolle bleiben wird und Probleme in den Bindungen nur eine Sorge für die Entwickler von Rust-for-Linux sein werden und nicht für die Gemeinschaft der Entwickelnden von Dateisystemen im Kernel. Es wurde festgehalten, dass nicht alle Entwickler bereit sind, Rust zu lernen, und deshalb werden sie nach Änderungen, die den anderen Code beeinflussen, nur den abhängigen C-Code aktualisieren können, aber nicht in der Lage sein werden, die Rust-Bindungen zu korrigieren, da sie Rust nicht beherrschen. Zur Diskussion gesellte sich auch James Bottomley, der das SCSI-Subsystem betreut, der sagte, dass je mehr Semantik in den Bindungen kodiert ist, desto spröder werden sie in Bezug auf die Gewährleistung der Synchronisierung.

In der Zwischenzeit hat das Unternehmen Google im letzten Jahr die Firmware pvmfm, die in verwendet wird, in Rust neu geschrieben. virtuellen Maschinen, die auf der Android-Plattform gestartet werden, teilte Erfahrungen über die schrittweise Integration von Rust-Code in bestehende Firmware, die ursprünglich in C oder C++ geschrieben wurde. Es wurde gezeigt, wie die Sicherheit der Firmware erheblich erhöht werden kann, indem funktional identische Ersatzkomponenten in Rust erstellt werden. Bei der Einführung von Rust wird empfohlen, den Fokus auf die Verwendung von Rust für neuen Code und für code zu legen, der sicherheitsrelevante Funktionen ausführt (z. B. Code zur Verarbeitung von externen Daten, die aus unsicheren Quellen stammen). Für die Integration von Rust- und C-Code wird empfohlen, Schichten (shim) zu verwenden, die Aufrufe zwischen den Rust- und C-APIs übersetzen (C-API wird für die Verwendung im Rust-Code und umgekehrt exportiert), die es ermöglichen, API-Elemente schrittweise in Rust umzuschreiben.

Quelle: opennet.ru

60GB SSD 8Gb DDR4