Détecter les failles du code C avec Valgrind et les corriger avec Snyk Code
24 septembre 2024
0 minutes de lectureLe C et le C++ restent des langages fondamentaux pour le développement de logiciels critiques. Ils sont utilisés dans un vaste éventail de systèmes, des appareils embarqués aux applications hautes performances dans les secteurs de la fabrication, des technologies opérationnelles (OT) et de l’industrie. Leur efficacité, leur capacité à contrôler les ressources système et leurs performances les rendent indispensables aux développeurs qui travaillent sur des projets stratégiques.
Le C et le C++ sont particulièrement répandus au Japon, où les secteurs de la fabrication et de l’industrie sont des moteurs économiques essentiels. Les développeurs japonais s’appuient sur ces langages pour créer des logiciels robustes et efficaces, qui sont au cœur de nombreux systèmes, de l’automobile à l’automatisation des usines. La précision et la fiabilité du C et du C++ sont indispensables pour répondre aux exigences élevées de ces secteurs.
L’importance de la sécurité du code en C et C++
Si le C et le C++ offrent un contrôle et des performances inégalés, ils présentent aussi d’importants défis en matière de sécurité. L’absence de mécanismes de sécurité intégrés, comme la gestion automatique de la mémoire, rend ces langages vulnérables à des problèmes tels que les dépassements de tampon, les utilisations après libération et les fuites de mémoire. Même si elles peuvent sembler élémentaires, ces vulnérabilités peuvent avoir de graves conséquences, en particulier dans les logiciels critiques, où la fiabilité et la sécurité sont primordiales.
Le code C vulnérable provoque une fuite de mémoire
Examinons un exemple de code C vulnérable qu’un développeur pourrait écrire et qui introduirait une faille de sécurité liée aux fuites de mémoire.
Voici le code de notre programme C. Saurez-vous y repérer la faille de sécurité ?
Ce fichier program1.c contient un exemple de vulnérabilité liée à l’allocation dynamique de mémoire (MISRA Dir 4.12, MISRA Rule 21.3). La faille de sécurité de la fonction allocateMemory() est qu’elle utilise malloc() pour allouer de la mémoire, sans la libérer, ce qui entraîne une fuite de mémoire. Il est possible d’éviter ce problème en suivant les recommandations MISRA, qui limitent l’allocation dynamique de mémoire.
Il s’agit d’une erreur courante en programmation C, qui peut entraîner une augmentation progressive de la mémoire utilisée par votre programme. À terme, celui-ci peut manquer de mémoire et planter, ou provoquer le manque de mémoire d’autres programmes sur votre système.
Pourquoi ne pas simplement utiliser l’allocation statique de mémoire, par exemple int arr[10] ? Dans certaines situations, il est impossible d’allouer de la mémoire sur la pile. Imaginons que vous écriviez une fonction qui lit un fichier en mémoire. Vous ne connaissez pas sa taille avant l’exécution : impossible, donc, d’utiliser un tableau de taille fixe. À la place, vous pouvez utiliser malloc pour allouer exactement la quantité de mémoire nécessaire une fois la taille du fichier connue.
Pour exécuter le programme, commencez par le compiler, puis lancez-le :
Le programme contient-il une fuite de mémoire ? Comment la corriger ?
Détecter les failles de sécurité du code C avec Valgrind
Valgrind est un outil puissant pour détecter les fuites de mémoire dans votre programme. Nous pouvons l’exécuter avec le programme pour vérifier s’il y en a.
Installez Valgrind sur votre système. Si vous utilisez un système Linux, vous pouvez passer par son gestionnaire de paquets. Voici un exemple pour Debian :
Remarque : Valgrind n’est pas disponible sur macOS avec les puces ARM. Nous allons donc ignorer cette étape et exécuter Valgrind dans un conteneur Docker :
Lancez ensuite le conteneur et associez le répertoire courant au répertoire /tmp du conteneur :
Compilez ensuite le programme program1.c dans le conteneur :
Vous pouvez ensuite exécuter le programme avec Valgrind pour rechercher des fuites de mémoire :
Valgrind devrait alors afficher un résultat indiquant la fuite de mémoire :
Valgrind est un excellent outil, mais pour un développeur C au quotidien, ce flux de travail n’est pas évolutif et nécessite de compiler et de construire un programme complet avant de pouvoir l’analyser.
Snyk Code vous aide à détecter cette vulnérabilité dans votre base de code, sans même passer par la compilation. Il vous suffit d’installer l’extension et d’ouvrir le fichier pour que la vulnérabilité s’affiche. En effet, Snyk Code est un outil d’analyse statique du code qui utilise des techniques de machine learning pour repérer les problèmes sans avoir besoin d’une étape de compilation ou de build. Cette approche permet à Snyk d’analyser votre code à la recherche de vulnérabilités de sécurité et de vous fournir rapidement des résultats fiables, avec peu de faux positifs.

Détecter les traversées de répertoires, les dépassements de tampon et d’autres vulnérabilités en C
Le moteur SAST qui alimente Snyk Code détecte bien plus de types de vulnérabilités que les seules fuites de mémoire dues à malloc.
Examinons un exemple plus complexe qui combine plusieurs pratiques de codage non sécurisées en C et introduit des failles de sécurité :
Le programme C ci-dessus regorge de vulnérabilités. Il s’agit toutefois d’un exemple très concis et simplifié de code non sécurisé, choisi par souci de brièveté. Certaines pratiques de codage plus subtiles peuvent néanmoins facilement se retrouver dans des bases de code réelles.
Une fois le programme compilé, vous pouvez l’exécuter :
Si un fichier nommé text.txt se trouve dans le même répertoire et n’est pas vide, le programme lira le fichier et en affichera le contenu.
Par exemple :
Tout semble correct. Que se passe-t-il si vous indiquez un fichier dont le chemin remonte dans l’arborescence des répertoires ?
Le programme présente une vulnérabilité de traversée de répertoires qui permet à un attaquant de lire des fichiers sensibles sur le système.
Pour tester d’autres vulnérabilités, essayez de :
Indiquer un fichier qui n’existe pas
Indiquer un fichier vide
Indiquer un nom de fichier ou un chemin complet trop long (plus de 50 caractères)
Certains de ces problèmes de sécurité dépassent largement les compétences d’un développeur en programmation C. La traversée de répertoires, par exemple, nécessite de connaître la sécurité des applications, et pas seulement la gestion sécurisée de la mémoire et les bonnes pratiques de développement en C.
Heureusement, lorsque vous collez le code du programme dans l’IDE, l’extension Snyk analyse le code C pour détecter les pratiques de codage non sécurisées et les problèmes courants de sécurité des applications. Elle les signale rapidement, avec le contexte directement dans le code :

Sécurisez votre code C et C++ avec Snyk
Une faille de sécurité dans les secteurs de la fabrication et de l’industrie peut avoir des conséquences catastrophiques : interruption des opérations, risques pour la sécurité et pertes financières. Sécuriser le code C et C++ n’est pas seulement une bonne pratique, c’est une nécessité. Snyk donne aux développeurs les moyens de détecter et de corriger les vulnérabilités dès les premières étapes du développement.
Sécurisez votre code grâce à des informations de pointe
Découvrez toutes les fonctionnalités SAST de Snyk Code en seulement 30 minutes.
