Die Version 1.93 der Programmiersprache Rust wurde veröffentlicht. Rust wurde ursprünglich von Mozilla entwickelt und wird nun von der unabhängigen gemeinnützigen Organisation Rust Foundation weiterentwickelt. Die Sprache konzentriert sich auf sichere Speicherverwaltung und bietet Mittel zur Erreichung hoher Parallelität bei der Ausführung von Aufgaben, ohne dabei auf einen Garbage Collector oder ein Runtime-Environment zurückgreifen zu müssen (das Runtime beschränkt sich auf die grundlegende Initialisierung und Unterstützung der Standardbibliothek).
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:
- Die in Rust integrierte Standard-C-Bibliothek Musl, die bei der statischen Verknüpfung für Zielplattformen "*-linux-musl" (aarch64-unknown-linux-musl, x86_64-unknown-linux-musl, powerpc64le-unknown-linux-musl usw.) auf Systemen ohne Musl verwendet wird, wurde auf Version 1.2.5 aktualisiert. Die minimal unterstützte Musl-Version bei dynamischer Verknüpfung wurde ebenfalls auf Version 1.2.5 angehoben. Zuvor wurde in Rust die Musl-Version 1.2.3 verwendet, die Probleme mit der Implementierung des DNS-Resolvers hatte. In Version 1.2.4 des Musl-Resolvers wurde die Möglichkeit hinzugefügt, Anfragen über TCP zu senden, falls die UDP-Anfrage fehlschlägt. Dies löste das Problem mit großen DNS-Einträgen und stellte die Kompatibilität mit rekursiven DNS-Servern her, die keine abgeschnittenen UDP-Antworten unterstützen. In Version 1.2.5 des Musl-Resolvers wurde die Verarbeitung von Antworten mit langen CNAME-Abfolgen implementiert und ein Problem behoben, bei dem einige große Antworten, die über TCP übertragen wurden, verworfen wurden.
- Die Standardbibliothek wurde überarbeitet, um Probleme mit der Wiederenterbarkeit bei der Verwendung in globalen Speicheralokatoren, die in Rust geschrieben sind, dem Makro std::thread_local! und der Funktion std::thread::current zu lösen, die zu endloser Rekursion führten. Um zu vermeiden, dass std::thread_local! und std::thread::current beim Versuch, Speicher zuzuweisen, denselben Alokator aufrufen, der bereits verwendet wird, wird jetzt direkt das systemeigene Speichervergabe-Mechanismus angewendet.
- Innerhalb der Blöcke "asm!" mit Assembler-Code ist die Verwendung von Attributen "cfg" erlaubt. Dies ermöglicht beispielsweise die Steuerung der Aktivierung erweiterten CPU-Befehlsätze im Kontext einzelner Ausdrücke innerhalb des asm-Blocks (früher konnten die Attribute "cfg" nur für den gesamten asm-Block festgelegt werden). asm!( // oder global_asm! oder naked_asm! "nop", #[cfg(target_feature = "sse2")] "nop", // … #[cfg(target_feature = "sse2")] a = const 123, // nur verwendet bei sse2 );
- Eine neue Charge von APIs wurde in den stabilen Bereich überführt, darunter wurden Methoden und Implementierungen von Traits stabilisiert:
- <[MaybeUninit]>::assume_init_drop
- <[MaybeUninit]>::assume_init_ref
- <[MaybeUninit]>::assume_init_mut
- <[MaybeUninit]>::write_copy_of_slice
- <[MaybeUninit]>::write_clone_of_slice
- String::into_raw_parts
- Vec::into_raw_parts
- ::unchecked_neg
- ::unchecked_shl
- ::unchecked_shr
- ::unchecked_shl
- ::unchecked_shr
- ::as_array
- ::as_array_mut
- ::as_array
- ::as_mut_array
- VecDeque::pop_front_if
- VecDeque::pop_back_if
- Duration::from_nanos_u128
- char::MAX_LEN_UTF8
- char::MAX_LEN_UTF16
- Die Zielplattform "riscv64a23-unknown-linux-gnu" wurde auf die zweite Unterstützungsstufe übertragen, die eine Garantie für die Erstellung, jedoch keine Garantie für das Bestehen des Testsets impliziert.
- Zusätzlich sind mehrere damit verbundene Projekte in Rust zu erwähnen:
- Für den Linux-Kernel wird das Framework Rex entwickelt, das es ermöglicht, Plugins für den Linux-Kernel in Rust zu erstellen, die zur Erweiterung der Kernel-Funktionalität anstelle von eBPF verwendet werden können. Rex bietet die gleichen Sicherheitsgarantien wie eBPF, nutzt jedoch die Möglichkeiten der Programmiersprache Rust und eine leichtgewichtige Runtime zur Isolation und Sicherheitsgewährleistung. Für solche Programme wird kein Verifier verwendet, und die Programme werden vom Rust-Compiler in nativen Code kompiliert.
In Rex-Programmen ist die Verwendung einer Teilmenge der Rust-Sprache erlaubt, die Sicherheitsgarantien bietet. Derzeit werden 5 Typen von eBPF-Programmen unterstützt: kprobe, perf_event, tracepoint, xdp und tc. Es ist möglich, Hilfsfunktionen von eBPF aufzurufen, mit eBPF-Map-Strukturen zu interagieren, Kernel-Ressourcen zu verwalten, Ausnahmen zu behandeln und Wrapper und Abstraktionen über Kernelstrukturen zu nutzen.
- Es ist eine Veröffentlichung von Fjall 3 verfügbar, einem in Rust geschriebenen eingebetteten Speicher, der mit Daten im Schlüssel-Wert-Format arbeitet. Die Datenspeicherung erfolgt in Form eines Logs unter Verwendung eines LSM-Baumes (Log-Structured-Merge), ähnlich wie bei RocksDB, bei dem Änderungen durch Hinzufügen von Daten ans Ende der Datei protokolliert werden. Für den Zugriff auf die Datenbank wird eine API im Stil von BTreeMap angeboten. Unterstützt werden Funktionen wie Namensräume, direkte und umgekehrte Bereichssuche, integrierte Kompression, serialisierbare Transaktionen, separate Speicherung von Schlüsseln und damit verbundenen sehr großen Werten sowie automatisierte Hintergrundwartung der Datenbank. Der Code ist unter der Lizenz Apache 2.0 offen.
In Rex-Programmen ist die Verwendung einer Teilmenge der Programmiersprache Rust zulässig, die Sicherheitsgarantien bietet. Aktuell werden 5 Typen von eBPF-Programmen unterstützt: kprobe, perf_event, tracepoint, xdp und tc. Es besteht die Möglichkeit, Hilfsfunktionen von eBPF aufzurufen, mit eBPF-Map-Strukturen zu interagieren, Kernressourcen zu verwalten, Ausnahmen zu behandeln und Wrapper sowie Abstraktionen über Kernstrukturen zu verwenden.
- Die Version Fjall 3, ein auf Rust basierendes eingebettetes Speichersystem, das mit Daten im Schlüssel-Wert-Format arbeitet, steht zur Verfügung. Die Daten werden in Form eines Logs mit einem LSM-Baum (Log-Structured-Merge) gespeichert, ähnlich wie bei RocksDB, wobei Änderungen durch Hinzufügen von Daten ans Ende der Datei aufgezeichnet werden. Ein API im Stil von BTreeMap wird für den Zugriff auf die Datenbank angeboten. Funktionen wie Namensräume, Vorwärts- und Rückwärtssuche über Bereiche, integrierte Komprimierung, serialisierbare Transaktionen, getrennte Speicherung von Schlüsseln und sehr großen zugehörigen Werten sowie automatisierte Hintergrundwartung der Datenbank werden unterstützt. Der Code ist unter der Lizenz Apache 2.0 geöffnet.
- Das Tor-Projekt hat die Version Arti 1.9.0 veröffentlicht, eine Implementierung des Tor-Tools, die in Rust geschrieben wurde. Wenn der Arti-Code ein Niveau erreicht, das eine vollständige Ablösung der C-Variante ermöglicht, beabsichtigen die Tor-Entwickler, Arti den Status der Hauptimplementierung von Tor zu verleihen und die Unterstützung für die C-Implementierung schrittweise einzustellen. In der neuen Version wurde die Funktionalität für Relays und Server Verzeichnisse (Directory Authority) weiterentwickelt, die Unterstützung für dynamisch zugewiesene Ports (proxy.socks_listen = «auto») verbessert und eine experimentelle API zur Schlüsselverwaltung für Onion-Dienste hinzugefügt.
Quelle: opennet.ru
