3 points par GN⁺ 2025-06-19 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Le crate bzip2 0.6.0 adopte par défaut libbz2-rs-sys, une implémentation Rust de l’algorithme bzip2, supprimant la dépendance au C tout en améliorant la vitesse et la facilité de compilation croisée
  • bzip2 est un ancien algorithme de moins en moins utilisé, mais de nombreux protocoles et bibliothèques doivent encore le prendre en charge pour respecter leurs spécifications, si bien qu’il reste présent au fond des arbres de dépendances
  • L’implémentation Rust utilise environ 9,66 à 14,87 % de cycles CPU en moins que le C pour la compression, et améliore aussi la décompression sur l’ensemble des tests de 4,48 à 10,00 %
  • La suppression du C simplifie les builds WebAssembly, Windows et Android, et comme les symboles libbz2-rs-sys ne sont pas exportés par défaut, le risque de conflits de symboles avec d’autres dépendances diminue également
  • L’audit a permis de corriger un bug logique off-by-one et certaines limites du fuzzer ; les bibliothèques et applications de plus haut niveau utilisant bzip2 peuvent désormais aussi être exécutées avec MIRI

Changement d’implémentation par défaut dans bzip2 0.6.0

  • Le crate bzip2 0.6.0 utilise par défaut libbz2-rs-sys, une implémentation Rust de l’algorithme bzip2
  • En supprimant l’ancienne dépendance au C, le crate bzip2 devient plus rapide et plus facile à compiler en cross-compilation
  • Le crate libbz2-rs-sys peut être compilé comme bibliothèque dynamique C, afin que les projets C puissent eux aussi profiter de ces améliorations
  • bzip2 est aujourd’hui peu utilisé, mais de nombreux protocoles et bibliothèques doivent encore le prendre en charge pour respecter leurs spécifications, et il reste profondément enfoui dans les arbres de dépendances de nombreux projets
  • Les détails d’implémentation sont disponibles dans l’article précédent Translating bzip2 with c2rust

Résultats des améliorations de performances

  • L’implémentation Rust est généralement plus rapide que l’implémentation C, et dans certains cas atteint un niveau de performance comparable au C
    • Dans les plages connues, il n’existe aucun cas significativement plus lent
  • Les benchmarks de compression montrent une baisse des cycles CPU par rapport au C
    • sample3.ref level 1 : 38.51M33.53M, -14,87 %
    • silesia-small.tar level 1 : 3.43G3.00G, -14,30 %
    • silesia-small.tar level 9 : 3.47G3.17G, -9,66 %
    • Dans bzip2, le level désigne la quantité de mémoire de travail utilisée et n’a pas d’impact majeur sur les performances
    • sample3.ref alloue déjà plus de mémoire que la taille du fichier avec le level 1, les levels plus élevés sont donc peu pertinents
  • Les performances de décompression s’améliorent également sur l’ensemble des tests
    • 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 %
  • Sur la machine de benchmark macOS, les chiffres de performance en décompression ressortent parfois plus faibles
    • La cause n’a pas été identifiée, et il a été difficile de faire fonctionner sous macOS des outils capables d’automatiser le suivi des performances comme perf

Builds et réduction des conflits de symboles

  • La compilation croisée de projets Rust ayant des dépendances C fonctionne souvent directement grâce au crate cc, mais lorsqu’elle échoue, le débogage des erreurs peut être difficile
    • L’édition de liens avec des bibliothèques système peut aussi créer des problèmes confus et difficiles à reproduire
    • La compilation WebAssembly de bzip2 posait problème depuis longtemps
    • En supprimant la dépendance C et en n’utilisant que du code Rust, les builds WebAssembly, Windows et Android deviennent plus faciles à faire fonctionner
  • libbz2-rs-sys n’exporte pas de symboles par défaut
    • Avec une dépendance C, il faut exporter les symboles pour que les blocs Rust extern puissent les trouver
    • Les noms exportés peuvent entrer en conflit lorsqu’une autre dépendance déclare les mêmes symboles
    • Si un projet Rust a besoin d’exporter des symboles, il peut l’activer via un feature flag

Validation et résultats de l’audit

  • Une implémentation performante de bzip2 nécessite une partie de code unsafe, et reproduire l’interface C en Rust demande encore davantage de code unsafe
    • Ce code peut être exécuté avec MIRI
    • Les bibliothèques de plus haut niveau ou les applications utilisant bzip2 peuvent désormais aussi être exécutées avec MIRI
  • L’audit a découvert un bug logique off-by-one et corrigé certaines limites du fuzzer
  • Ce travail a bénéficié de l’aide d’Alex Crichton, mainteneur du crate bzip2, de Radically Open Security pour l’audit et son expertise, ainsi que de la NLnet Foundation, qui a financé le projet via l’e-Commons Fund

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.