Traduire du code C en Rust « safe » ? Deux chercheurs l’ont fait
« Une pierre de plus à l’édifice »

rustacean.net
Le langage Rust a largement gagné en visibilité ces dernières années, au point qu’on le retrouve désormais aussi bien dans le noyau de Windows que celui de Linux. Reste une interrogation tenace : est-il possible de convertir l’ancien code C en Rust ? Le sujet occupe jusqu’à la DARPA américaine. Plus récemment, deux chercheurs ont fait une percée et nous avons parlé à l'un d'eux, Aymeric Fromherz.
Le 16 janvier à 16h04
12 min
Logiciel
Logiciel
Pourquoi le langage Rust est-il devenu si désirable ? Essentiellement parce qu’il arrive à marier des performances proches du C (sans toutefois l’égaler) et certaines caractéristiques que l’on rencontre surtout dans les langages managés, comme Java et C#. C’est notamment vrai avec tout ce qui touche à la sécurité en mémoire, dont le typage fort.
Si le sujet a pris tant d’ampleur, c’est notamment parce que certaines grandes entreprises courent après les bugs liés à la mémoire. En 2019, Microsoft avertissait ainsi que 70 % des failles de sécurité détectées dans Windows étaient liées à la sécurité de la mémoire. Ce taux est le même depuis presque 20 ans. L’éditeur évoquait alors pour la première fois son intérêt pour le Rust, que nous avions analysé.
Le score vous parait important ? Il est le même chez Google. « Environ 70 % de nos bugs de sécurité de haute sévérité sont des problèmes d'insécurité de la mémoire (c'est-à-dire des erreurs avec les pointeurs C/C++). La moitié d'entre eux sont des bugs de type "use-after-free" », écrivait ainsi l’éditeur dans un billet de 2020 sur la sécurité de Chromium (projet open source à la base de Chrome et dont la gouvernance vient d’évoluer légèrement). Google indiquait par la même occasion se pencher sur Rust comme possible solution lorsque la solution s’y prêtait, entre autres langages selon le contexte (Java, Kotlin, Swift, etc.).
Du code flambant neuf… et le reste ?
Le Rust s’invite depuis quelques années dans le développement bas niveau et système, permettant l’écriture de nouveaux modules normalement débarrassés de la plupart des problèmes liés à des bugs en mémoire. Par exemple, avec la version 24H2 de Windows 11, le noyau du système embarque pour la première fois du code écrit en Rust. Ce mouvement est nettement accentué par des recommandations officielles. C’est vrai en particulier aux États-Unis, comme à la NSA en 2022 ou à la Maison-Blanche en 2024.
Mais qu’en est-il du reste, de l’immense base de code existante en C ou en C++ ? L’idéal serait de pouvoir traduire automatiquement l’ancien code partout où une telle opération serait pertinente. Le besoin de performances est parfois trop critique pour passer au Rust. La DARPA, avec son projet TRACTOR (TRanslating All C TO Rust), travaille justement sur ce projet. Des travaux parmi d’autres, car le sujet intéresse grandement.
Conserver la vérification formelle
Deux chercheurs ont récemment présenté les résultats de leurs travaux. Le document, en preprint, a été publié sur Arxiv.
On peut y lire qu’Aymeric Fromherz, ingénieur à Inria, et Jonathan Protzenko, ingénieur chez Microsoft (Azure Research), ont travaillé sur la préservation de la preuve formelle lors de la traduction du code C vers Rust. La preuve formelle est une preuve mathématique que le code est rigoureusement exact. La méthode est appliquée généralement sur des projets cruciaux et dont la taille est limitée, car elle réclame des ressources importantes et du temps.
Les deux chercheurs indiquent avoir étudié ce qu’il faudrait faire pour traduire le C en Rust safe, pour automatiser le processus.
« Notre travail présente plusieurs contributions originales : une traduction orientée type de (un sous-ensemble de) C vers Rust safe ; une nouvelle analyse statique basée sur des "arbres divisés" qui permet d'exprimer l'arithmétique des pointeurs de C en utilisant les tranches et les opérations de division de Rust ; une analyse qui déduit exactement quels emprunts doivent être mutables ; et une stratégie de compilation pour les types struct de C, compatible avec la distinction de Rust entre les allocations non possédées et possédées », peut-on lire dans l’article.
Ces travaux ont été appliqués à deux projets existants : HACL, une bibliothèque cryptographique d’environ 80 000 lignes de code, et EverParse, un framework « permettant de générer des analyseurs syntaxiques sécurisés et vérifiés à partir de langages de spécification de format DSL », d’une taille d’environ 10 000 lignes.
Pour mieux cerner ces travaux, nous avons interrogé l’un des deux auteurs, Aymeric Fromherz.
>> Pouvez-vous nous expliquer votre projet dans les grandes lignes ?
Le point de départ a été que nous avions plusieurs bases de codes C, qui étaient du code formellement vérifié. On avait donc des preuves mathématiques de l'absence de problèmes, de la sûreté mémoire, mais également de la correction fonctionnelle par rapport à des spécifications de nos implémentations.
Pour différentes raisons, nous souhaitions transpiler [ndlr : compiler d'un code source à un autre] ce code vers du Rust afin de l'utiliser dans de nouveaux projets. Notre réflexion était de savoir comment on pouvait traduire un sous-ensemble du langage C, suffisant pour nos projets spécifiques, vers du code Rust dit safe, c'est-à-dire avec les garanties du langage, et qui vient avec certaines propriétés de sûreté mémoire fournies par le langage.
Il faut rappeler une nuance importante d’ailleurs. Rust est séparé en deux parties, safe et unsafe. Les garanties sur la sûreté mémoire dont on parle tant depuis plusieurs années sont surtout dans la partie safe du langage. Il était donc important pour nous que l’on puisse traduire du code C vers cette partie safe, et pas seulement de le rendre exécutable sous forme de code unsafe.
>> Pourquoi avoir choisi HACL et EverParse ?
Parce que c'était deux projets déjà déployés dans des milieux industriels. Des projets que nous connaissions bien, vu que soit nous-mêmes, soit des collègues proches en avons développé la majorité. Ils ont été initialement développés de manière vérifiée dans le même langage – qui s'appelle F* – avant d'être traduit vers du code C.
Ce sont donc deux projets pour lesquels nous avions une maîtrise de la chaîne de compilation, de la structure du code, ce qui permettait de se concentrer sur certains challenges du fait de transpiler du code C vers du code Rust, sans devoir gérer du code C dans toute sa généralité. C'était vraiment un moyen pour nous d'avoir un sous-ensemble bien délimité du langage C que nous connaissions, et qui est bien formalisé, sur lequel travailler en tant que projet de recherche.
>> Vous les trouviez représentatifs ?
Certains des challenges sont effectivement représentatifs. Pour certaines des difficultés, dont en particulier la gestion de la mémoire et de l'arithmétique de pointeur, mais également suffisamment restreint pour qu'on puisse étudier ce sous-ensemble du langage de manière formelle, et en définir une traduction vers du code safe.
>> Les résultats ont-ils été concluants ?
Pour les études de cas que nous avons considérées, oui, au sens où on a effectivement réussi à traduire le code C vérifié que nous avions vers du code Rust safe, qui compile bien, qui passe bien tous les tests que nous avons, et qui, selon notre évaluation expérimentale, semble avoir une performance similaire au code C originel.
De cette façon, on considère que l'expérience est concluante, mais on voit vraiment ça comme une étape préliminaire pour un sous-ensemble bien restreint du langage. On ne proclame pas que ce soit quelque chose d'applicable à grande échelle pour tous les projets C existants. Pour nous, c'est un pas peut-être dans cette direction.
>> Allez-vous continuer avec d'autres projets, faire d'autres tests ? Peut-être des projets qui contiennent plus de lignes de code ?
Ça fait partie des possibilités. Pour l'instant, on n'a pas encore de bons exemples que nous aimerions étudier. Nous avons d'autres projets en parallèle qui ne sont pas directement liés à la traduction de C vers Rust.
Mais pour nous, c'est aussi l'intérêt de publier ce preprint pour permettre à d'autres personnes qui travaillent sur ce sujet d'évaluer ces idées, éventuellement de s'en inspirer, et surtout pouvoir construire dessus pour peut-être créer la nouvelle génération d'outils qui traduit du code C vers du code Rust.
>> Pensez-vous que vos travaux intéresseront des entreprises comme Microsoft ou Google ? Avez-vous eu des manifestations d’intérêt ?
On n'a pas eu d'écho ou de retour de contact du monde industriel, industriel au sens large. J'inclus le projet Linux comme le monde industriel. Nous avons eu des contacts d'autres groupes académiques intéressés par les travaux.
À titre personnel, je pense que la question de la traduction de code legacy C vers Rust est une question extrêmement porteuse en ce moment, avec entre autres le projet Tractor de la DARPA qui tente de faire ça en particulier par IA, mais il y a beaucoup d'autres projets qui tentent des approches similaires.
Le projet C2Rust qui traduit vers du code unsafe et qui tente de plus en plus d'essayer de traduire certains fragments vers du code safe.
>> Le projet de la DARPA pourrait-il parvenir aux mêmes résultats ?
Je ne sais pas. J'ai du mal à croire que du code C arbitraire puisse être traduit vers Rust safe dans tous les cas.
Je pense qu'il y a certains motifs, certaines structures de code C qui nécessiteront du code unsafe en Rust. On peut voir nos travaux comme une pierre de plus à l'édifice, d'essayer de considérer en tout cas certains patterns fréquents de code en C, essayer de voir comment on peut les traduire, comment on peut dans certains cas retrouver de la structure expressible en Rust safe…
De cette façon, on espère effectivement que ça intéresse une grande partie du monde industriel. Mais je pense que nous n'avons pas vocation en tout cas actuellement à en créer un outil industriel ou industrialisable, utilisable par le public, parce que c'est quelque chose qui est un travail conséquent et difficilement conciliable avec les métiers de la recherche.
>> Estimez-vous que le Rust va poursuivre son ascension irrésistible ?
« Irrésistible » c'est une bonne question parce qu'il y a quand même de la résistance dans certaines communautés. Il y a encore des débats sur du code très bas niveau qui de toute façon n'est pas expressible en Rust safe, qui soulève donc des questions par rapport aux avantages de Rust par rapport à C.
Je pense en tout cas que, entre autres avec les soutiens gouvernementaux tels qu'on voit aux États-Unis et dans une certaine mesure en Europe, et avec l'énorme effort de la communauté Rust, particulièrement la communauté compilateur, langage et ainsi de suite, il est probable que Rust continue son essor et son évolution.
Après, c'est difficile de spéculer sur ce que seront effectivement les prochaines années, mais que ce soit Rust for Linux ou for Windows, on voit quand même de plus en plus de projets historiquement écrits en C qui s'intéressent de manière très très sérieuse à des réécritures, en tout cas des portages en Rust.
Il y a aussi plusieurs mouvements, que ce soit chez Google ou chez Microsoft pour les pratiques de safe coding, qui visent à écrire du nouveau code dans des langages safe tels que Rust. Donc Rust me paraît en tout cas un excellent candidat pour les prochaines années au minimum.
>> Pensez-vous enfin que le langage Rust est aujourd’hui mature ?
C'est une question difficile. Je pense que ça dépend beaucoup de ce qui va derrière la maturité au sens où on peut se poser le même genre de questions pour un langage comme C ou C++ et sur le fait que même si le langage est considéré suffisamment mature, il y a quand même de nouveaux standards et des évolutions du langage toutes les quelques années.
Donc de cette façon, je pense que Rust n'est pas encore complètement stabilisé, n'est pas encore complètement standardisé non plus. Il y a encore certaines parties du langage qui sont étudiées.
Après, est-ce que le langage Rust est assez mature actuellement pour des applications critiques et industrielles ? À titre personnel, je considère que oui et je pense que le fait que des projets comme Linux ou Windows intègrent des éléments écrits en Rust sont également un argument en cette faveur.
Traduire du code C en Rust « safe » ? Deux chercheurs l’ont fait
-
Du code flambant neuf… et le reste ?
-
Conserver la vérification formelle
Commentaires (5)
Abonnez-vous pour prendre part au débat
Déjà abonné ? Se connecter
Cet article est en accès libre, mais il est le fruit du travail d'une rédaction qui ne travaille que pour ses lecteurs, sur un média sans pub et sans tracker. Soutenez le journalisme tech de qualité en vous abonnant.
Accédez en illimité aux articles
Profitez d’un média expert et unique
Intégrez la communauté et prenez part aux débats
Partagez des articles premium à vos contacts
Abonnez-vousLe 16/01/2025 à 17h33
Le 16/01/2025 à 17h52
Le 17/01/2025 à 22h01
Le 18/01/2025 à 09h56
Mais je suis bien d'accord avec toi que, hors ce genre de cas, ça n'a que peu d'intérêt : le code en C apporte déjà la sécurité attendue.
C'est à mon avis la limite de l'exercice : c'est un cas facile qui ne s'applique qu'à un sous ensemble du C (généré automatiquement depuis un autre langage qui plus est, donc on sait exactement comment les programmes sont structurés).
Le projet de la DARPA est d'une autre ampleur.
Modifié le 20/01/2025 à 08h16
Après je suppose que le compilateur F* => C n'utilise pas tous les façons de coder du C, donc l'exercice est plutôt restreint.
Instinctivement pour ce sujet j'aurais écrit le compilateur F* => Rust mais effectivement on n'en aurait jamais parlé ici :)