bzip2-Crate stellt von C auf eine 100%ige Rust-Implementierung um
(trifectatech.org)- Das
bzip2-Crate 0.6.0 verwendet standardmäßiglibbz2-rs-sys, eine Rust-Implementierung des bzip2-Algorithmus, entfernt damit die C-Abhängigkeit und verbessert zugleich Geschwindigkeit und Cross-Compilation - bzip2 ist ein älterer Algorithmus, der seltener verwendet wird, aber viele Protokolle und Bibliotheken müssen ihn zur Einhaltung ihrer Spezifikationen weiterhin unterstützen, sodass er tief in Abhängigkeitsbäumen erhalten bleibt
- Die Rust-Implementierung verwendete beim Komprimieren im Vergleich zu C etwa 9,66–14,87 % weniger CPU-Zyklen und verbesserte auch die Dekomprimierung über alle Tests hinweg um 4,48–10,00 %
- Durch den Wegfall von C werden WebAssembly-, Windows- und Android-Builds einfacher, und da standardmäßig keine
libbz2-rs-sys-Symbole exportiert werden, sinkt auch das Risiko von Symbolkonflikten mit anderen Abhängigkeiten - Im Audit wurden ein Off-by-one-Logikfehler und einige Einschränkungen des Fuzzers behoben; außerdem können nun auch übergeordnete Bibliotheken und Anwendungen, die
bzip2verwenden, mit MIRI ausgeführt werden
Änderung der Standardimplementierung in bzip2 0.6.0
- Das
bzip2-Crate 0.6.0 verwendet standardmäßiglibbz2-rs-sys, eine Rust-Implementierung des bzip2-Algorithmus - Durch den Wegfall der bisherigen C-Abhängigkeit wird das
bzip2-Crate schneller und lässt sich leichter cross-kompilieren - Das
libbz2-rs-sys-Crate kann auch als dynamische C-Bibliothek gebaut werden, damit C-Projekte ebenfalls von den Verbesserungen profitieren können - bzip2 wird heute nicht mehr häufig genutzt, doch viele Protokolle und Bibliotheken müssen es zur Einhaltung ihrer Spezifikationen weiterhin unterstützen, sodass es tief in den Abhängigkeitsbäumen vieler Projekte verbleibt
- Details zur Implementierung finden sich im früheren Beitrag Translating bzip2 with c2rust
Ergebnisse der Leistungsverbesserung
- Die Rust-Implementierung ist im Allgemeinen schneller als die C-Implementierung und liegt in einigen Fällen auf ähnlichem Niveau wie deren Leistung
- Im bekannten Bereich gibt es praktisch keine tatsächlich langsameren Fälle
- In den Kompressions-Benchmarks wurden im Vergleich zu C weniger CPU-Zyklen benötigt
sample3.refLevel 1:38.51M→33.53M, -14,87 %silesia-small.tarLevel 1:3.43G→3.00G, -14,30 %silesia-small.tarLevel 9:3.47G→3.17G, -9,66 %- Das
levelvon bzip2 bezeichnet die Nutzung des Arbeitspeichers und hat keinen großen Einfluss auf die Leistung - Bei
sample3.refwird schon mit Level 1 mehr Speicher als die Dateigröße allokiert, daher sind höhere Level wenig relevant
- Auch die Dekomprimierungsleistung verbesserte sich über alle Tests hinweg
sample3.bz2: -4,48 %sample1.bz2: -8,63 %sample2.bz2: -7,67 %dancing-color.ps.bz2: -5,17 %re2-exhaustive.txt.bz2: -7,65 %zip64support.tar.bz2: -10,00 %
- Auf dem macOS-Benchmark-Rechner fallen die Werte für die Dekomprimierungsleistung gelegentlich niedriger aus
- Die Ursache wurde nicht geklärt, und auf macOS war es schwierig, Tools zur Automatisierung von Performance-Tracking wie
perfzum Laufen zu bringen
- Die Ursache wurde nicht geklärt, und auf macOS war es schwierig, Tools zur Automatisierung von Performance-Tracking wie
Builds und Entschärfung von Symbolkonflikten
- Cross-Compilation von Rust-Projekten mit C-Abhängigkeiten funktioniert dank des
cc-Crates oft direkt, aber wenn sie fehlschlägt, kann das Debuggen der Fehler schwierig sein- Auch das Linken von Systembibliotheken kann verwirrende und schwer reproduzierbare Probleme verursachen
- Die WebAssembly-Kompilierung von bzip2 war schon seit Langem problematisch
- Mit dem Wegfall der C-Abhängigkeit und der ausschließlichen Nutzung von Rust-Code werden WebAssembly-, Windows- und Android-Builds einfacher funktionsfähig
libbz2-rs-sysexportiert standardmäßig keine Symbole- Bei Nutzung einer C-Abhängigkeit müssen Symbole exportiert werden, damit Rust-
extern-Blöcke sie finden können - Exportierte Namen können mit anderen Abhängigkeiten kollidieren, wenn diese dieselben Symbole deklarieren
- Wenn ein Rust-Projekt den Symbol-Export benötigt, kann dies per Feature-Flag aktiviert werden
- Bei Nutzung einer C-Abhängigkeit müssen Symbole exportiert werden, damit Rust-
Ergebnisse von Verifizierung und Audit
- Eine performante bzip2-Implementierung benötigt etwas unsafe Code, und die Nachbildung der C-Schnittstelle in Rust erfordert noch mehr unsafe Code
- Dieser Code kann in MIRI ausgeführt werden
- Auch höherstufige Bibliotheken oder Anwendungen, die
bzip2verwenden, können nun mit MIRI ausgeführt werden
- Im Audit wurde ein Off-by-one-Logikfehler entdeckt, außerdem wurden einige Einschränkungen des Fuzzers behoben
- Darüber hinaus gab es keine wichtigen weiteren Erkenntnisse
- Das Audit wurde von Radically Open Security durchgeführt; der vollständige Bericht ist im Audit-Bericht als PDF verfügbar
- An dieser Arbeit beteiligt waren der Maintainer des
bzip2-Crates Alex Crichton, Radically Open Security für Audit und Fachwissen sowie die NLnet Foundation, die über den e-Commons Fund die Finanzierung bereitstellte
Noch keine Kommentare.