web-dev-qa-db-fra.com

L'utilisation d'un compilateur C obsolète pose-t-elle un risque pour la sécurité?

Nous avons des systèmes de construction en production dont personne ne se soucie et ces machines utilisent des versions anciennes de GCC comme GCC 3 ou GCC 2.

Et je ne peux pas persuader la direction de le mettre à jour plus récemment: ils disent: "Si ce n'est pas cassé, ne le répare pas". 

Comme nous maintenons une base de code très ancienne (écrite dans les années 80), ce code C89 compile parfaitement sur ces compilateurs. 

Mais je ne suis pas sûr que ce soit une bonne idée d'utiliser ces vieux trucs.

Ma question est:

L'utilisation d'un ancien compilateur C peut-elle compromettre la sécurité du programme compilé? 

METTRE À JOUR:

Le même code est généré par Visual Studio 2008 pour les cibles Windows et MSVC ne prend pas encore en charge C99 ou C11 (je ne sais pas si MSVC le plus récent le permet) et je peux le construire sur mon ordinateur Linux à l'aide du dernier GCC. Donc, si nous déposions simplement un nouveau GCC, il serait probablement construit aussi bien qu'avant.

135
Calmarius

En fait, je dirais le contraire.

Il existe un certain nombre de cas où le comportement n'est pas défini par la norme C mais où il est évident que se passerait-il avec un "compilateur stupide" sur une plate-forme donnée. Des cas tels que permettre à un entier signé de déborder ou d'accéder à la même mémoire via des variables de deux types différents.

Les versions récentes de gcc (et de clang) ont commencé à traiter ces cas comme des opportunités d'optimisation sans se soucier de savoir s'ils modifient le comportement du binaire dans la condition de "comportement non défini". C'est très grave si votre base de code a été écrite par des personnes qui traitaient C comme un "assembleur portable". Au fil du temps, les optimiseurs ont commencé à chercher des morceaux de code de plus en plus gros, augmentant ainsi les chances que le binaire finisse par faire autre chose que "ce qu'un binaire construit par un compilateur idiot" ferait.

Il existe des commutateurs de compilation pour restaurer le comportement "traditionnel" (-fwrapv et -fno-strict-aliasing pour les deux que j'ai mentionnés ci-dessus), mais vous devez d'abord les connaître.

Alors qu'en principe un bogue du compilateur pourrait transformer un code conforme en trou de sécurité, je considérerais que le risque que cela se produise est négligeable dans le grand schéma des choses.

99
plugwash

Il y a des risques dans les deux plans d'action.


Les compilateurs plus anciens ont l'avantage de la maturité, et tout ce qui y était cassé a probablement (sans aucune garantie) été travaillé avec succès.

Dans ce cas, un nouveau compilateur est une source potentielle de nouveaux bogues.


D'autre part, les nouveaux compilateurs sont livrés avec outillage supplémentaire} _:

  • GCC et Clang proposent désormais désinfectants qui peuvent aider le moteur d'exécution à détecter des comportements indéfinis de différentes sortes (Chandler Carruth, de l'équipe Google Compiler, a affirmé l'année dernière qu'il s'attendait à ce qu'ils aient atteint une couverture complète)
  • Clang, au moins, comporte durcissement} _, par exemple Intégrité du flux de contrôle concerne la détection des haut-parleurs de flux de contrôle, il existe également des outils de renforcement pour la protection contre les attaques de type pile (en séparant les flux partie de la pile de la partie de données); les fonctions de renforcement sont généralement peu onéreuses (moins de 1% de temps processeur)
  • Clang/LLVM travaille également sur libFuzzer , un outil permettant de créer des tests unitaires de fuzzing instrumentés qui explorent intelligemment l'espace d'entrée de la fonction testée (en modifiant légèrement l'entrée pour prendre des chemins d'exécution non encore explorés).

Instrumenter votre binaire avec les désinfectants (Address Sanitizer, Memory Sanitizer ou Undefined Behavior Sanitizer), puis le fuzzer (à l'aide de American Fuzzy Lop par exemple) a permis de découvrir des vulnérabilités dans un certain nombre de logiciels de haut profil, voir par exemple ceci Article LWN.net .

Ces nouveaux outils, ainsi que tous les futurs outils, vous sont inaccessibles à moins que vous ne mettiez à jour votre compilateur.

En restant sur un compilateur peu puissant, vous vous mettez la tête dans le sable et vous vous croisez les doigts pour qu'aucune vulnérabilité ne soit trouvée. Si votre produit est une cible de grande valeur, je vous exhorte à reconsidérer votre décision.


Remarque: même si vous ne mettez PAS à niveau le compilateur de production, vous voudrez peut-être utiliser un nouveau compilateur pour vérifier la vulnérabilité de toute façon; sachez que, puisqu'il s'agit de compilateurs différents, les garanties sont toutefois réduites.

50
Matthieu M.

Votre code compilé contient des bugs qui pourraient être exploités. Les bogues proviennent de trois sources: des bogues dans votre code source, des bogues dans le compilateur et les bibliothèques, et un comportement non défini dans votre code source que le compilateur transforme en bogue. (Le comportement non défini est un bogue, mais pas encore dans le code compilé. Par exemple, i = i ++; en C ou C++, il s'agit d'un bogue, mais dans votre code compilé, il peut augmenter de 1 et être ok, ou défini je suis un peu indésirable et être un bug). 

Le taux de bogues dans votre code compilé est probablement faible en raison des tests et de la correction des bogues dus aux rapports de bogues clients. Donc, il y a peut-être eu un grand nombre de bugs au début, mais le nombre a baissé. 

Si vous effectuez une mise à niveau vers un compilateur plus récent, vous risquez de perdre les bogues introduits par ceux du compilateur. Mais ces insectes seraient tous des insectes que personne, à votre connaissance, n’a trouvé ni exploité. Mais le nouveau compilateur peut avoir lui-même des bogues, et il est important de noter que les nouveaux compilateurs ont davantage tendance à transformer un comportement non défini en bogues dans le code compilé. 

Donc, vous aurez beaucoup de nouveaux bogues dans votre code compilé; tous les bugs que les pirates pourraient trouver et exploiter. Et à moins que vous ne fassiez beaucoup de tests et que vous laissiez votre code aux clients pour rechercher les bogues pendant longtemps, la sécurité sera moins grande. 

46
gnasher729

L'utilisation d'un ancien compilateur C peut-elle compromettre la sécurité du programme compilé? 

Bien sûr, cela peut l'être si l'ancien compilateur contient des bogues connus susceptibles d'affecter votre programme. 

La question est, est-ce? Pour en être sûr, vous devez lire le journal de modification complet de votre version à la date du jour et vérifier chaque bogue corrigé au fil des ans.

Si vous ne trouvez aucune preuve de bogues de compilation qui pourraient affecter votre programme, la mise à jour de GCC juste pour le plaisir de le lire semble un peu paranoïaque. N'oubliez pas que les versions plus récentes peuvent contenir de nouveaux bogues, qui n'ont pas encore été découverts. Beaucoup de changements ont été apportés récemment avec le support de GCC 5 et C11.

Cela étant dit, le code écrit dans les années 80 est probablement déjà rempli de failles de sécurité et repose sur un comportement mal défini, quel que soit le compilateur. Nous parlons de C pré-standard ici.

9
Lundin

Il existe un risque de sécurité lorsqu'un développeur malveillant peut se faufiler par un bogue du compilateur. Selon la quantité de bogues connus dans le compilateur utilisé, la porte dérobée peut sembler plus ou moins discrète (dans tous les cas, le code est correct, même s’il est compliqué, au niveau de la source. Révisions du code source et tests utilisant un compilateur non bogué ne trouvera pas la porte dérobée, car celle-ci n'existe pas dans ces conditions). Pour des points de déniabilité supplémentaires, le développeur malveillant peut également rechercher seul des bogues de compilateur inconnus auparavant. Encore une fois, la qualité du camouflage dépendra du choix des bogues du compilateur trouvés.

Cette attaque est illustrée sur le programme Sudo dans cet article . bcrypt a écrit un excellent suivi pour les minifiers Javascript .

Indépendamment de cette préoccupation, l'évolution des compilateurs C a consisté à exploiter un comportement indéfini plus et plus et plus de manière agressive, de sorte que l'ancien code C écrit de bonne foi serait réellement plus sûr compilé avec un compilateur C de l’époque, ou compilé à -O0 (mais certaines nouvelles optimisations exploitant UB sont révolutionnaires et sont introduites dans les nouvelles versions des compilateurs, même à -O0 ).

9
Pascal Cuoq

Les compilateurs plus anciens peuvent ne pas être protégés contre les attaques de piratage connues. La protection anti-écrasement, par exemple, n’a pas été introduite jusqu’à GCC 4.1 . Alors oui, le code compilé avec des compilateurs plus anciens peut être vulnérable de la même manière que les nouveaux compilateurs.

7
DrMcCleod

Un autre aspect à prendre en compte est le développement du nouveau code .

Les compilateurs plus anciens peuvent avoir un comportement différent de celui standardisé et attendu par le programmeur pour certaines fonctionnalités de langage. Cette inadéquation peut ralentir le développement et introduire des bugs subtils pouvant être exploités.

Les anciens compilateurs offrent moins de fonctionnalités (y compris des fonctionnalités de langage!) Et n'optimisent pas aussi bien. Les programmeurs corrigent ces lacunes - par exemple, en réimplémentant les fonctionnalités manquantes ou en écrivant un code intelligent qui est obscur mais qui tourne plus vite - créant de nouvelles opportunités pour la création de bugs subtils.

6
Hurkyl

Nan

La raison est simple, un ancien compilateur peut avoir d'anciens bugs et exploits, mais le nouveau compilateur aura de nouveaux bugs et exploits. 

Vous ne "corrigez" aucun bogue en effectuant une mise à niveau vers un nouveau compilateur. Votre commutation d'anciens bugs et exploits pour de nouveaux bugs et exploits. 

5
coteyr

Il existe une probabilité plus élevée que tous les bogues de l'ancien compilateur soient bien connus et documentés, par opposition à l'utilisation d'un nouveau compilateur, de sorte que des actions puissent être entreprises pour éviter ces bogues en codant autour d'eux. Donc, d'une manière qui ne suffit pas comme argument pour la mise à niveau. Nous avons les mêmes discussions où nous travaillons, nous utilisons GCC 4.6.1 sur une base de code pour logiciels embarqués et il y a une grande réticence (parmi la direction) à mettre à niveau le dernier compilateur par peur des nouveaux bogues non documentés. 

2
Anders

Votre question se divise en deux parties:

  • Explicite: “L’ancien compilateur présente-t-il un plus grand risque?” (Plus ou moins, comme dans votre titre)
  • Implicite: «Comment puis-je persuader la direction de mettre à niveau»

Vous pouvez peut-être répondre à la fois en trouvant une faille exploitable dans votre base de code existante et en montrant qu'un compilateur plus récent l'aurait détectée. Bien sûr, votre direction peut dire «vous avez trouvé cela avec l'ancien compilateur», mais vous pouvez souligner que cela coûte un effort considérable. Ou vous le passez par le nouveau compilateur pour trouver la vulnérabilité, puis l'exploitez, si vous êtes capable/autorisé à compiler le code avec le nouveau compilateur. Vous voudrez peut-être l’aide d’un pirate informatique amical, mais cela dépend de leur confiance et de leur permettre/leur permet de leur montrer le code (et d’utiliser le nouveau compilateur).

Mais si votre système n'est pas exposé à des pirates informatiques, vous devriez peut-être être plus intéressé par la question de savoir si une mise à jour du compilateur augmenterait votre efficacité: MSVS 2013 Code Analysis trouve assez souvent les bogues potentielles beaucoup plus tôt que MSVS 2010, et supporte plus ou moins C99/C11 - Vous ne savez pas s'il le fait officiellement, mais les déclarations peuvent suivre des instructions et vous pouvez déclarer des variables dans for- boucles.

0
PJTraill