La série Pixel 10 intègre pour la première fois dans des appareils Pixel un composant écrit en Rust, un langage sûr pour la mémoire, au sein du logiciel du modem cellulaire, selon une publication du Google Security Blog. Cette initiative consiste à intégrer au micrologiciel du modem un résolveur du système de noms de domaine (DNS) développé en Rust, afin de réduire les risques de vulnérabilités liées à la sûreté mémoire dans une partie qui traite des données non fiables.
Cette initiative s’inscrit dans les efforts de Google visant à renforcer le modem de communications cellulaires contre les exploitations. L’entreprise avait doté le Pixel 9 de mesures d’atténuation contre plusieurs vulnérabilités de sûreté mémoire, mais elle estime que la complexité du micrologiciel du modem et l’étendue de sa surface d’attaque nécessitent des mesures préventives supplémentaires. Google a indiqué que Project Zero était auparavant parvenu à obtenir l’exécution de code à distance sur des modems Pixel via Internet, tandis que le modem Pixel contient des dizaines de mégaoctets de code exécutable.
Pourquoi Google a-t-elle choisi un résolveur DNS ?
Le DNS ne sert pas uniquement à aider les navigateurs à trouver des sites web. Avec le passage des communications cellulaires modernes aux réseaux de données numériques, des opérations essentielles telles que l’acheminement des appels dépendent également des services DNS. Ce protocole complexe doit analyser des données potentiellement non fiables, ce qui en fait un point sensible lorsqu’il est implémenté dans un langage dépourvu de protection de la mémoire, un type de risque qui, selon la publication, était associé à la vulnérabilité CVE-2024-27227.
Google a évalué plusieurs bibliothèques open source d’implémentation du DNS en Rust et a choisi la bibliothèque hickory-proto en fonction de son niveau de maintenance, d’une couverture de tests supérieure à 75 % et de sa popularité dans la communauté Rust. La bibliothèque ne prenait initialement pas en charge no_std, nécessaire aux environnements aux ressources limitées ou fonctionnant sans système d’exploitation. Google a donc ajouté cette prise en charge à la bibliothèque et à certaines de ses dépendances. Ce travail a également permis d’ajouter la prise en charge de no_std au résolveur d’URL du projet rust-url.
Coût en taille et intégration au logiciel existant
L’étude de taille a montré que le composant intermédiaire écrit en Rust consomme 4 kilo-octets, tandis que les composants core, alloc et compiler_builtins nécessitent 17 kilo-octets, et que la bibliothèque hickory-proto et ses dépendances consomment 350 kilo-octets, pour un total de 371 kilo-octets. Google estime que la taille de la mémoire du modem Pixel n’impose pas de contraintes strictes et a donc privilégié à ce stade le soutien de la communauté et la qualité du code plutôt que l’optimisation de la taille. Elle a toutefois indiqué que cette augmentation pourrait constituer un obstacle pour d’autres systèmes embarqués et qu’elle pourrait être réduite à l’avenir grâce à des options de compilation excluant les fonctionnalités inutiles.
Pour intégrer Rust à la base de code existante écrite en C et en C++, l’équipe a utilisé des tests unitaires afin de vérifier les opérations arithmétiques de base, l’allocation dynamique de mémoire et les interfaces de liaison entre les langages. Elle a également choisi d’intégrer directement les étapes de compilation de Rust au système de build existant plutôt que de créer des bibliothèques statiques séparées via Cargo, car cette approche est plus facile à faire évoluer à mesure que d’autres composants Rust sont ajoutés et réduit le risque de conflits de symboles.
Le système de build principal repose sur Pigweed, tandis que des interfaces FFI ont été utilisées pour relier le système d’allocation mémoire existant du micrologiciel au composant alloc de Rust, ainsi que pour uniformiser la gestion des situations de plantage entre Rust et C/C++. Lors de l’édition de liens, un problème de performances et de consommation d’énergie est apparu après le remplacement des implémentations optimisées par le modem des fonctions memset et memcpy par celles fournies par compiler_builtins. L’équipe a résolu le problème en supprimant les fichiers compiler_builtins de la bibliothèque statique avant l’étape d’édition de liens.
Interface DNS et prochaine étape
Google a défini une interface de programmation en C pour traiter les réponses DNS, puis l’a implémentée en Rust. Après l’analyse de la réponse, le composant appelle les fonctions C existantes afin de mettre à jour les structures de données utilisées par le programme d’origine. L’outil bindgen a été utilisé pour générer le code de liaison nécessaire aux opérations de conversion complexes entre les types de données.
Selon Google, la série Pixel 10 constitue une étape importante, car il s’agit des premiers appareils Pixel à intégrer un langage sûr pour la mémoire dans le modem. L’objectif ne se limite pas au remplacement d’un seul résolveur : l’entreprise estime que le projet jette les bases de l’intégration future d’autres résolveurs et composants écrits dans des langages sûrs pour la mémoire au sein de la base de connectivité cellulaire.