Sécuriser le code C et C++ pour l’automobile et les véhicules définis par le logiciel (SDV)
23 octobre 2024
0 minutes de lectureL’avènement des véhicules définis par le logiciel (SDV) marque un tournant pour l’industrie automobile. Lors du congrès international de la Society of Automotive Engineers (SAE) qui s’est tenu à Detroit du 16 au 18 avril 2024, divers intervenants ont affirmé que ce marché, estimé à plus de 500 milliards de dollars, allait faire l’objet d’investissements en R&D et donner lieu à de grandes avancés technologiques. Le basculement vers les SDV donnera naissance à de nouveaux flux de revenus par le biais d’abonnement à des fonctionnalités et services inimaginables avec le modèle d’achat ponctuel qui caractérisait jusque-là l’industrie automobile.
Les constructeurs et leurs sous-traitants cherchent à devenir des entreprises technologiques en se rapprochant d’une architecture électrique/électronique qui place les semi-conducteurs au centre de ces innovations. Les microservices, les architectures avec conteneurs et la disponibilité d’une puissance de calcul dans le cloud importante sont aussi des composants essentiels des SDV.
Le secteur utilise presque uniquement du C et du C++ pour développer ses logiciels, des langages considérés comme fiables, efficaces et puissants. Ils ne sont pourtant pas dénués de risques de sécurité, comme des dépassements de mémoire tampon ou des problèmes sécurité de la mémoire, des faiblesses qui sont connues depuis des décennies. Le marché des SDV a ainsi grand besoin de sécuriser ses logiciels, ce qui est justement la mission que s’est fixée Snyk. Les constructeurs automobiles peuvent notamment tirer parti des solutions de Snyk pour la sécurisation de l’infrastructure en tant que code et des conteneurs, ainsi que de ses intégrations fluides à de nombreux fournisseurs cloud.
Mercedes a par exemple pris une longueur d’avance sur ses concurrents avec son système d’exploitation MB.
Nous avons intégré rapidement le meilleur matériel disponible avec le processeur Qualcomm Gen4 8295, qui a été commercialisé auprès du grand public seulement 6 mois auparavant. Il s’agissait d’un projet ambitieux et je suis très fier que mon équipe aie su relever ce défi, générer 20 Go de code compilé et obtenir cette première approche de MB.OS sur la Classe E, car les leçons tirées de ce projet seront essentielles pour le lancement de notre système complet, MB.OS 1.0.
Conformité à la norme MISRA pour le code en C et C++
La norme MISRA C:2023 se concentre principalement sur la sécurité et la fiabilité des systèmes critiques, et notamment sur différents points pour lesquels la présence de vulnérabilités dans une application pourrait générer des risques pour la sécurité humaine. Si cette norme aborde de nombreux sujets, certaines règles et directives concernent tout particulièrement le renforcement de la sécurité des applications par l’adoption de pratiques évitant les comportements non définis, la corruption de la mémoire, les accès non autorisés et diverses autres vulnérabilités courantes.
La structure et le contenu de la norme MISRA C++:2023 sont similaires à la version C, avec des règles et directives liées à la sécurité des applications, accompagnés d’exemples de code conforme et non conforme.
Certaines parties des normes MISRA pour le développement en C et C++ édictent des directives et règles relatives à la sécurité des applications et la création de logiciels C et C++ sécurisés, notamment :
Directive MISRA 4.12 - Ne pas utiliser l’allocation dynamique de la mémoire : éviter d’allouer dynamiquement la mémoire évite des vulnérabilités liées à des erreurs de gestion de la mémoire.
Règle MISRA 1.3 - Ne pas laisser de comportement indéfini ou de comportement non spécifié critique : un comportement indéfini peut générer des failles de sécurité. Cette règle est essentielle pour assurer la sécurité du code.
Règle MISRA 18.1 - Un pointeur obtenu par une opération arithmétique sur l’opérande d’un pointeur doit désigner un élément du même tableau que l’opérande d’origine : cette règle vise à éviter les accès hors limites, une vulnérabilité que l’on retrouve fréquemment dans les programmes en C.
Règle MISRA 21.3 - Les fonctions d’allocation et de désallocation de mémoire de <stdlib.h> ne doivent pas être utilisées : comme pour la directive 4.12, éviter l’allocation dynamique de la mémoire limite les risques liés aux vulnérabilités liées à la gestion de la mémoire.
Règles MISRA 22.1 à 22.20 (ressources) : une gestion appropriée des ressources, notamment des erreurs et de la libération des ressources, est essentielle pour éviter les fuites et les épuisements de la mémoire, qui peuvent être exploités pour lancer des attaques par déni de service ou aboutir à des comportements indéfinis eux-mêmes exploitables par des attaquants.
Si la norme MISRA pour le C ne parle jamais explicitement de « mesures de sécurité », le respect de ses règles et directives complètes renforce la posture de sécurité des logiciels en éliminant de nombreuses sources courantes de failles de sécurité des codes écrits en C et C++. Elle permet de développer des systèmes sûrs, fiables et sécurisés en encourageant un comportement robuste et correctement défini.
Mission de Snyk
Snyk a pour mission d’aider les développeurs à sécuriser leur code, notamment s’il est écrit en C ou C++. En intégrant la sécurité dans le cycle de vie comme dans le cadre du DevSecOps, Snyk permet aux développeurs de repérer les vulnérabilités avant qu’elles ne se transforment en problèmes critiques. Snyk aide aussi les développeurs à repérer les patterns de code vulnérables lorsqu’ils enregistrent leur code dans l’IDE. Ils n’ont pas à attendre les contrôles des pipelines d’intégration continue et de build, voire que leur code soit compilé.
Avec des outils comme Snyk Code, vous pouvez analyser vos bases de code C et C++ pour y détecter des vulnérabilités et obtenir des informations concrètes permettant de les corriger.
Prenons l’exemple d’une vulnérabilité que l’on retrouve fréquemment en C++ : le dépassement de la mémoire tampon. Voici un extrait de code permettant d’illustrer ce problème :
#include <iostream>
#include <cstring>
void vulnerableFunction(char* input) {
char buffer[10];
// ❌ Potential buffer overflow
strcpy(buffer, input);
}
int main() {
char input[20] = "This is a long string";
vulnerableFunction(input);
return 0;
}
Dans ce code en C++, la fonction strcpy
peut générer un dépassement de la mémoire tampon si la chaîne en entrée dépasse la taille de la mémoire. Snyk peut identifier ce type de vulnérabilité et fournir des recommandations plus sûres. Dans notre cas, la solution pourrait être d’utiliser strncpy
:
void secureFunction(char* input) {
char buffer[10];
strncpy(buffer, input, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null-termination
}
Avec Snyk installé dans votre IDE, vous avez deux atouts dans votre manche :
Snyk détectera le code vulnérable, comme ce dépassement de la mémoire tampon, sans nécessiter sa compilation.
Snyk vous proposera une correction via Snyk Agent Fix.
Vous souhaitez voir notre solution à l’œuvre ? C’est par ici :

En adoptant des pratiques de codage sécurisées et en utilisant des outils comme Snyk, les développeurs peuvent fortement réduire le risque de vulnérabilités dans leurs bases de code en C et C++. Créez un compte Snyk dès aujourd’hui pour sécuriser vos projets logiciels stratégiques.
Exemples de code sécurisé et conforme, et de code vulnérable
Pour montrer le lien entre les normes MISRA et le code et les vulnérabilités que l’on retrouve concrètement dans le monde réel, nous allons prendre l’exemple d’un programme en C, program2.c
. Ce programme présente un exemple de comportement indésirable (règle MISRA 1.3 de la liste ci-dessus).
Voici le code de ce programme :
#include <stdio.h>
void undefinedBehavior() {
int x = 5 / 0;
printf("Value of x: %d\n", x);
}
int main() {
undefinedBehavior();
return 0;
}
La division par zéro est un comportement indéfini en C qui peut générer des résultats imprévisibles. La norme MISRA, à raison, interdit ce type d’opération pour assurer la sécurité du code des logiciels critiques.
Compilez le programme, puis exécutez-le.
$ gcc program2.c -o program2
$ ./program2
Vous remarquerez que GCC génère un avertissement concernant la division par zéro :
program2.c:5:15: warning: division by zero is undefined [-Wdivision-by-zero]
int x = 5 / 0;
^ ~
1 warning generated.
Ici, notre code est simple et peu étendu. Dans le monde réel, ces problèmes peuvent être difficiles à localiser lorsque la base de code est étendue, et les compilateurs peuvent générer de nombreux avertissements.
Localisez la vulnérabilité avec Snyk Code
Il n’est pas toujours évident de voir les erreurs générées par le compilateur, qu’il soit lié au comportement indéfini induit par une _division par zéro_ ou à d’autres erreurs. Parfois, ces erreurs ne sont repérées que tard dans le cycle de développement. Snyk Code peut vous aider à les détecter dès le début du développement en analysant votre base de code avant la compilation.
Le moteur d’analyse statique de la sécurité des applications de Snyk s’appuie sur le machine learning pour comprendre les flux d'appels du programme et remonter les chemins du code allant des points de consommation des données à leurs sources. Il peut ainsi détecter du code non sécurisé et des vulnérabilités potentielles dans votre base de code, sans avoir besoin de la compiler. »

Outils pour la sécurité et la conformité du code C et C++
Il existe plusieurs outils open source permettant de vérifier la conformité de code en C et C++ avec la norme MISRA :
OpenMRC : OpenMRC est un outil de vérification des règles MISRA-C open source se présentant sous la forme d’un plug-in Eclipse CDT. Il est conçu pour analyser le code des véhicules définis par le logiciel par rapport à la norme MISRA-C:2004 et génère des messages sur les violations pour aider les développeurs à assurer la conformité de leur code.
Clang-misracpp2008 : ce projet, désormais archivé, avait pour ambition de devenir un outil de vérification open source des règles MISRA C++:2008 sur la base de l’infrastructure LLVM/Clang. S’il n’est plus actif aujourd’hui, ses développeurs recommandent de se tourner vers
clang-tidy-misra
.clang-misracpp2008
prenait la forme d’un plugin LLVM/Clang et cherchait à vérifier les règles MISRA C++ par le biais d’une logique personnalisée et d’indicateurs fournis par le compilateur.
Qu’elles respectent ou non vos critères de qualité et soient suffisamment à jour ou non, n’hésitez pas à comparer ces options à Snyk.
La plateforme de sécurité de Snyk inclut Snyk Code, un outil SAST en temps réel qui optimise la sécurité du code en proposant une expérience adaptée aux développeurs. Les résultats de Snyk incluent des informations, des exemples de correction pour vous guide, voire une correction automatique générée par Snyk Agent Fix.
Snyk est gratuit et peut être utilisé de différentes manières pour analyser du code C et C++, par exemple via l’installation de son extension pour les IDE, l’importation de dépôts Git depuis Bitbucket ou GitHub ou en utilisant la CLI.
Dans le cas des programmes C et C++, il existe un autre vecteur de failles de sécurité, autre que le code écrit par les développeurs : le code importé depuis des bibliothèques open source.
Enfin, je vous recommande vivement de parcourir les leçons sur les vulnérabilités du C de Snyk Learn. Concises, elles vous permettront d’apprendre de manière interactive. Ces leçons abordent différentes vulnérabilités C et C++, comme null dereference et double free, les pratiques de codage déconseillées, etc.
Sécurisez votre code avec une intelligence de pointe
Découvrez l’ensemble des fonctionnalités de Snyk Code SAST en seulement 30 minutes.