
Tout d'abord, pourquoi un autre langage après plus de 30 ans en C et en assembleur ? Et pourquoi Rust ?
Les principaux mainteneurs du noyau Linux ont un âge qui commence par le chiffre 5. Certains se rapprochent même de la soixantaine. Aussi, la communauté du célèbre noyau open source commence à penser au changement de générations. Une nouvelle dont la tranche d’âge se situe dans la trentaine gravit les échelons, mais comme Linus lui-même le souligne : « Il s'avère qu'il est vraiment difficile de trouver des personnes qui sont des mainteneurs » ; un fait lié à ceci que le développement du kernel Linux continue de se faire en C et assembleur. Des langages auxquels la vieille génération est plus accoutumée ? C’est une possibilité et elle est susceptible d’expliquer pourquoi 2022 est devenue l’année du langage Rust au sein du noyau Linux.
C'est ainsi qu'est né le projet Rust-for-Linux : initié en 2020 par Miguel Ojeda, un ingénieur logiciel chez CERN, il a reçu le soutien de Linus Torvalds, le créateur du noyau Linux. Le projet a été fusionné dans la branche principale du noyau Linux en version 6.1, en tant qu’expérience visant à déterminer si Rust est adapté pour le noyau, c’est-à-dire s’il vaut les compromis. Le projet fournit une infrastructure et des outils pour compiler, charger et déboguer du code Rust dans le noyau, ainsi qu’une bibliothèque standard minimale (core) et une bibliothèque d’abstraction du noyau (kernel).
Rust a une propriété clé qui le rend très intéressant à considérer comme un autre langage du noyau : il garantit qu'aucun comportement indéfini n'a lieu (tant que le code non sécurisé est sain). Cela inclut l'absence d'erreurs de type use after-free (Use-After-Free (UAF) est une vulnérabilité liée à une utilisation incorrecte de la mémoire dynamique lors du fonctionnement du programme. Si après avoir libéré un emplacement mémoire, un programme n'efface pas le pointeur vers cette mémoire, un attaquant peut utiliser l'erreur pour pirater le programme), double free (des erreurs qui surviennent lorsque free() est utilisé plus d’une fois avec la même adresse mémoire comme entrée. Appeler free() deux fois sur la même variable peut entraîner une fuite de mémoire), data race (une data race survient quand une donnée partagée est accédée par au moins deux threads dont au moins un en écriture et ce, sans synchronisation), etc.
Le projet Rust for Linux n’a pas pour objectif de réécrire le noyau entier en Rust, mais plutôt d’ajouter du nouveau code, écrit en Rust, qui s’interface proprement avec l’infrastructure existante du noyau. Le projet vise également à encourager les développeurs à utiliser Rust pour les parties du noyau qui sont particulièrement sensibles ou complexes, telles que les pilotes de périphériques, les sous-systèmes de sécurité ou les protocoles réseau. Rust pourrait ainsi apporter des bénéfices en termes de qualité, de performance et de sécurité du code du noyau, tout en réduisant les coûts de développement et de maintenance.
Rust-for-Linux, ses apports et ses défis
Le projet Rust-for-Linux a recruté un ingénieur à temps plein l’année dernière, a déclaré Ojeda, ainsi qu’un étudiant développeur. Plusieurs entreprises ont rejoint le projet pour soutenir ce travail. Il y a aussi un travail en cours pour faire fonctionner l’outil Coccinelle avec le code Rust. Une priorité actuelle est de trouver plus de relecteurs pour le code qui est soumis.
Sur le plan de la chaîne d’outils, le travail sur gccrs, le compilateur Rust basé sur GCC, a considérablement ralenti. Le générateur de code GCC pour rustc progresse mieux ; il peut compiler du code noyau maintenant et a été fusionné dans le compilateur. Ce backend basé sur GCC permettra d’étendre le support de Rust à des architectures qui ne sont pas supportées par rustc basé sur LLVM. Pendant ce temps, le projet Rust lui-même s’implique davantage dans ce travail ; c’est une bonne chose, car le noyau a des besoins spécifiques et aura besoin de garanties que les changements de langage ne casseront pas le code du noyau à l’avenir.
Au sein du noyau, le travail se poursuit dans un certain nombre de sous-systèmes. L’implémentation Rust du binder d’Android fonctionne bien et ses performances sont équivalentes à celles de l’implémentation C. La quantité de code non sécurisé qui a été nécessaire pour y parvenir était agréablement faible. Les liaisons avec les systèmes de fichiers font l’objet d’un travail de Wedson Almeida Filho, qui vise pour l’instant un support en lecture seule. L’objectif est de rendre possible l’implémentation d’un système de fichiers en Rust 100% sécurisé.
En général, il constate un nombre croissant de mainteneurs qui sont ouverts à l’idée d’utiliser Rust. Cela conduit à un problème auquel les développeurs Rust se sont heurtés, cependant. Il serait bon d’avoir quelques pilotes de référence dans le noyau comme exemple de la façon dont les pilotes peuvent être écrits et de permettre de comparer les pilotes Rust et C. La meilleure façon de le faire semble souvent être de fusionner un pilote Rust qui duplique la fonctionnalité d’un pilote C existant - mais ce genre de fonctionnalité dupliquée n’est pas apprécié par les mainteneurs. Peut-être, a-t-il dit, serait-il bon de permettre quelques pilotes dupliqués qui ne sont pas destinés à être utilisés, mais seulement comme exemples pour les autres développeurs.
Il y a aussi d’autres défis ; l’intégration des abstractions de la couche bloc a rencontré une certaine résistance. Le mainteneur de la couche virtuelle de systèmes de fichiers Christian Brauner a dit qu’il n’était pas opposé à fusionner ces abstractions, mais qu’il préférerait ne pas le faire et voir des systèmes de fichiers construits dessus tout de suite. Il préférerait voir une implémentation de quelque chose de relativement simple, dans le style du pilote binder, pour montrer que les choses fonctionnent comme prévu. Un pilote bientôt ?
Bientôt une branche Rust ?
Dave Airlie, le mainteneur du sous-système DRM (graphique), a dit que, s’il en avait le pouvoir, il y aurait un pilote DRM Rust fusionné dans les prochaines versions. Christoph Hellwig a répliqué qu’Airlie était prêt à « rendre la vie de tout le monde infernale » pour qu’il puisse jouer avec son jouet préféré. Fusionner Rust, a dit Hellwig, obligerait les autres à gérer un second langage, de nouvelles chaînes d’outils, et « des wrappers avec des sémantiques bizarres ». Dan Williams a estimé que la situation actuelle « est ce à quoi ressemble le succès », et que la communauté du noyau s’était déjà engagée en faveur de Rust.
Airlie a poursuivi en disant qu’une grande partie du travail sur Rust est actuellement bloquée dans une sorte de problème de l’œuf et de la poule. Les abstractions ne peuvent pas être fusionnées tant qu’il n’y a pas d’utilisateur pour elles, mais le code qui a besoin de ces abstractions est bloqué en attendant que le code soit intégré dans plusieurs sous-systèmes. En conséquence, les développeurs travaillant sur Rust se traînent de grandes piles de correctifs dont ils ont besoin pour travailler sur leur code. Il a suggéré qu’il serait peut-être bon de créer une branche spéciale pour le code Rust, où les abstractions pourraient être fusionnées plus facilement, en attendant qu’elles soient prêtes pour la branche principale.
À partir de là, la conversation a pris plusieurs directions.
Rust : oui, mais...
Greg Kroah-Hartman, le mainteneur du noyau stable, a dit qu’il n’était pas opposé à l’idée d’une branche Rust, mais qu’il faudrait qu’elle soit maintenue par quelqu’un d’autre que lui. Il a aussi demandé comment le code Rust serait testé, et s’il y aurait des outils pour vérifier la qualité du code et la conformité aux normes de codage du noyau. Ojeda a répondu qu’il y avait déjà des outils pour le formatage du code Rust, et qu’il travaillait sur un outil pour vérifier les règles spécifiques au noyau. Il a aussi dit qu’il y avait des tests unitaires pour le code Rust, et qu’il espérait que le code Rust serait intégré dans les systèmes de test existants du noyau.
Dave Chinner s'inquiète du fait que les responsables manquent d'expertise pour examiner correctement les abstractions en cours de fusion. Airlie a répondu que les responsables fusionnent désormais de nombreuses API C sans vraiment comprendre comment elles fonctionnent. De nombreuses erreurs ont été commises au cours du processus, mais « nous sommes toujours là ». Lorsque des choses s’avèrent être cassées, elles peuvent être réparées, et cela se produira plus rapidement si le code remonte en amont.
Ted Ts'o s'est dit préoccupé par le fardeau que l'ajout du code Rust imposerait aux responsables. Les développeurs de Rust établissent des normes plus élevées que celles fixées par le passé, a-t-il déclaré. Fusionner de bonnes abstractions est une chose, mais qui est responsable de la révision des pilotes et comment les modifications à l'échelle de l'arborescence seront-elles gérées ? L’effort de Rust, a-t-il dit, arrive à un point où il touche une partie croissante de la communauté.
Williams a souligné que durant la session précédente, la difficulté de faire migrer les sous-systèmes du noyau vers de nouvelles API avait été évoquée ; maintenant, dit-il, on parle de passer à un tout nouveau langage. Hellwig a déclaré que le vrai problème est que les liaisons Rust ont tendance à fonctionner différemment des API C pour lesquelles elles fournissent des abstractions ; les nouvelles API sont peut-être meilleures, mais ce sont toujours des API complètement nouvelles. Ce qu’il faudrait faire, dit-il, c’est d’abord corriger les API C afin qu’elles soient directement utilisables par le code Rust. Il a proposé que, pour chaque sous-système envisageant d'introduire du code Rust, un an ou deux soient d'abord consacrés au nettoyage de ses API dans ce sens. Ojeda a déclaré que ce type d'amélioration de l'API s'était déjà produit dans certains sous-systèmes.
Linus Torvalds a déclaré qu'il voyait un fossé entre le système de fichiers et les responsables des pilotes. Les développeurs du côté des systèmes de...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.