Qu'est-ce que Misra et comment le faire cuire

Figure 2

Peut-être que tous les développeurs de logiciels de microcontrôleur ont entendu parler de normes de codage spéciales pour améliorer la sécurité et la portabilité du code. L'une de ces normes est MISRA. Dans cet article, nous allons voir de plus près ce qu'est ce standard, son concept et comment l'utiliser dans vos projets.

Beaucoup de nos lecteurs ont entendu dire que PVS-Studio prend en charge la classification de ses avertissements selon la norme MISRA. À l'heure actuelle, PVS-Studio couvre plus de 100 règles MISRA C: 2012 et MISRA C ++: 2008.

Cet article vise à tuer trois oiseaux avec une pierre:

  1. Dites ce qu'est MISRA pour ceux qui ne sont pas encore familiers avec cette norme;
  2. Rappeler au monde du développement intégré ce que nous pouvons faire;
  3. Aidez les nouveaux employés de notre entreprise, qui développeront également notre analyseur MISRA à l'avenir, à en prendre pleinement connaissance.

J'espère que je pourrai le rendre intéressant. Alors allons-y!

L'histoire de misra


L'histoire de MISRA a commencé il y a longtemps. À l'époque, au début des années 1990, le programme gouvernemental britannique «Safe IT» a financé divers projets liés à la sécurité des systèmes électroniques. Le projet MISRA (Motor Industry Software Reliability Association) lui-même a été fondé pour créer un guide pour le développement de logiciels de microcontrôleurs dans les véhicules terrestres - dans les voitures, principalement.

Ayant reçu un financement de l'État, l'équipe MISRA a repris les travaux et, en novembre 1994, a publié son premier guide: " Lignes directrices pour le développement de logiciels basés sur les véhicules ". Ce guide n'est pas encore lié à un langage spécifique, mais je dois admettre que le travail a été fait de manière impressionnante et qu'il a probablement concerné tous les aspects imaginables du développement de logiciels embarqués. Soit dit en passant, les développeurs de ce guide ont récemment célébré le 25e anniversaire d'une date aussi importante pour eux.

Une fois le financement de l'État terminé, les membres de la MISRA ont décidé de continuer à travailler ensemble sur une base informelle, comme cela se poursuit à ce jour. D'une manière générale, MISRA (en tant qu'organisation) est une communauté de parties prenantes de diverses industries automobiles et aéronautiques. Maintenant, ces parties sont:

  • Voitures à moteur Bentley
  • Ford Motor Company
  • Jaguar land rover
  • Systèmes diesel Delphi
  • HORIBA MIRA
  • Protean électrique
  • Services d'ingénierie Visteon
  • L'université de leeds
  • Ricardo uk
  • ZF TRW

Des acteurs du marché très forts, n'est-ce pas? Sans surprise, leur première norme linguistique, MISRA C, est devenue courante chez les développeurs de systèmes embarqués critiques. Un peu plus tard, MISRA C ++ est apparu. Progressivement, les versions des normes ont été mises à jour et affinées pour couvrir les nouvelles fonctionnalités des langues. À ce jour, les versions actuelles sont MISRA C: 2012 et MISRA C ++: 2008.

Concept principal et exemples de règles


Les caractéristiques les plus distinctives de MISRA sont son incroyable attention aux détails et son extrême minutie pour assurer la sécurité et la sûreté. Non seulement les auteurs ont rassemblé toutes les carences en C et C ++ en un seul endroit (comme par exemple les auteurs du CERT) - ils ont également soigneusement élaboré les normes internationales de ces langages et écrit toutes les façons de se tromper. Après, ils ont ajouté des règles sur la lisibilité du code pour assurer le code propre contre une nouvelle erreur.

Pour comprendre l'échelle de gravité, regardons quelques règles tirées de la norme.

D'une part, il existe des règles décentes et utiles qui doivent toujours être suivies, quel que soit le but de votre projet. Pour la plupart, ils sont conçus pour éliminer les comportements indéfinis / non spécifiés / définis par l'implémentation. Par exemple:

  • N'utilisez pas la valeur d'une variable non initialisée
  • N'utilisez pas le pointeur vers FILE après la fermeture du flux
  • Toutes les fonctions non nulles doivent renvoyer une valeur
  • Les compteurs de boucles ne doivent pas être de type virgule flottante
  • et d'autres.

D'autre part, il existe des règles dont les avantages ne sont pas difficiles à mettre en œuvre, mais qui (du point de vue des projets ordinaires) peuvent parfois être violées:

  • N'utilisez pas goto et longjmp
  • Chaque commutateur doit se terminer par une étiquette par défaut
  • N'écrivez pas de code inaccessible
  • N'utilisez pas de fonctions variadic
  • N'utilisez pas l'arithmétique d'adresse (sauf [] et ++ )
  • ...

De telles règles ne sont pas mauvaises non plus, et combinées aux précédentes, elles donnent déjà une augmentation tangible à la sécurité, mais est-ce suffisant pour des systèmes embarqués hautement fiables? Ils sont utilisés non seulement dans l'industrie automobile, mais aussi dans les industries aéronautique, aérospatiale, militaire et médicale.

Nous ne voulons pas qu'une machine à rayons X irradie les patients avec une dose de 20 000 rads à cause d'une erreur logicielle, donc les règles habituelles "quotidiennes" ne suffisent pas. Avec des vies humaines et beaucoup d'argent en jeu, la minutie est indispensable. Voici où le reste des règles MISRA entrent en jeu:

  • Le suffixe «L» dans le littéral doit toujours être en majuscule (la lettre minuscule «l» peut être confondue avec 1)
  • N'utilisez pas l'opérateur "virgule" (cela augmente les chances de faire une erreur)
  • N'utilisez pas la récursivité (une petite pile de microcontrôleurs peut facilement déborder)
  • Les corps des instructions if , else , for , while , do , switch doivent être placés entre crochets (vous pouvez potentiellement faire une erreur lorsque le code n'est pas aligné correctement )
  • N'utilisez pas de mémoire dynamique (car il est possible de ne pas la libérer du tas, en particulier dans les microcontrôleurs)
  • ... et beaucoup, beaucoup de ces règles.

Il arrive souvent que les personnes qui rencontrent MISRA pour la première fois aient l'impression que l'objectif de la norme est de "bannir ceci et de bannir cela". En fait, il en est ainsi, mais seulement dans une certaine mesure.

D'une part, la norme a de nombreuses règles de ce type, mais elle n'est pas destinée à tout interdire, mais d'autre part, elle répertorie l'ensemble des façons de violer la sécurité du code. Pour la plupart des règles, vous choisissez vous-même si vous devez les suivre ou non. Je vais expliquer ce cas plus en détail.

Dans MISRA C, les règles sont divisées en trois catégories principales: obligatoires, obligatoires et consultatives. Les règles obligatoires ne peuvent être enfreintes sous aucun prétexte. Par exemple, cette section inclut la règle: "n'utilisez pas la valeur d'une variable non initiée". Les règles requises sont moins strictes: elles permettent la possibilité d'un rejet, mais seulement si ces écarts sont soigneusement documentés et justifiés par écrit. Les autres règles entrent dans la catégorie des conseils, qui ne sont pas obligatoires.

MISRA C ++ a quelques différences: il n'y a pas de catégorie obligatoire et la plupart des règles appartiennent à la catégorie obligatoire. Par conséquent, en fait, vous avez le droit d'enfreindre n'importe quelle règle - n'oubliez pas de commenter tous les écarts. Il existe également la catégorie Document - ce sont des règles obligatoires (les écarts ne sont pas autorisés) liées aux pratiques générales telles que "Chaque utilisation de l'assembleur doit être documentée" ou "Une bibliothèque incluse doit être conforme à MISRA C ++".

Autres problèmes


En fait, MISRA n'est pas seulement un ensemble de règles. En fait, c'est une directive pour écrire du code sûr pour les microcontrôleurs, et donc c'est plein de goodies. Examinons-les en profondeur.

Tout d'abord, la norme contient une description assez approfondie de la trame de fond: pourquoi la norme a été créée, pourquoi C ou C ++ a été choisi, les avantages et les inconvénients de ces langages.

Nous connaissons tous très bien les mérites de ces langues. Aussi bien que nous sommes également conscients de leurs lacunes :) Haut niveau de complexité, spécification standard incomplète et syntaxe permettant de faire facilement une erreur et de la rechercher pendant des âges - tout cela ne peut être que mentionné. Par exemple, vous pourriez accidentellement écrire ceci:

for (int i = 0; i < n; ++i); { do_something(); } 

Après tout, il est possible qu'une personne ne remarque pas un point - virgule supplémentaire , non? Une autre option consiste à écrire du code comme suit :
 void SpendTime(bool doWantToKillPeople) { if (doWantToKillPeople = true) { StartNuclearWar(); } else { PlayComputerGames(); } } 

Il est bon que le premier et le deuxième cas puissent être facilement détectés par les règles MISRA (1 - MISRA C: 13.4 / MISRA C ++: 6.2.1; 2 - MISRA C: 13.4 / MISRA C ++: 6.2.1).

La norme contient à la fois une description des problèmes et des conseils sur ce qu'il faut savoir avant d'entreprendre une certaine tâche: comment mettre en place le processus de développement selon MISRA; comment utiliser des analyseurs statiques pour vérifier la conformité du code; quels documents doit-on conserver, comment les remplir, etc.

Les annexes à la fin comprennent également: une courte liste et un résumé des règles, une petite liste de vulnérabilités C / C ++, un exemple de documentation sur les écarts de règles et quelques listes de contrôle permettant de trier toute cette bureaucratie.

Comme vous pouvez le voir, MISRA n'est pas seulement un ensemble de règles, mais presque toute une infrastructure pour écrire du code sécurisé pour les systèmes embarqués.

Utilisation dans vos projets


Imaginez la scène: vous allez écrire un programme pour un système embarqué responsable et tellement nécessaire. Ou vous avez déjà un programme, mais vous devez le "porter" sur MISRA. Alors, comment vérifiez-vous la conformité de votre code à la norme? Devez-vous vraiment le faire manuellement?

La vérification manuelle du code est une tâche difficile et même potentiellement impossible. Non seulement chaque réviseur doit examiner attentivement chaque ligne de code, mais il faut aussi connaître la norme presque par cœur. Fou!

Par conséquent, les développeurs MISRA eux-mêmes conseillent d'utiliser l'analyse statique pour tester votre code. Après tout, en fait, l'analyse statique est un processus automatisé de révision de code. Vous exécutez simplement l'analyseur sur votre programme et en quelques minutes, vous obtenez un rapport de violations potentielles de la norme. C'est ce dont vous avez besoin, non? Tout ce que vous avez à faire est de consulter le journal et de corriger les avertissements.

La question suivante est - à quel moment devrions-nous commencer à utiliser MISRA? La réponse est simple: le plus tôt sera le mieux. Idéalement - avant de commencer à écrire du code, car MISRA suppose que vous suivez la norme pour l'ensemble du cycle de vie de votre code.

Eh bien, il n'est pas toujours possible d'écrire selon MISRA dès le début. Par exemple, il arrive souvent que le projet ait déjà été partiellement ou complètement mis en œuvre, mais plus tard, le client voulait que le projet réponde à la norme. Dans ce cas, vous devrez faire une refactorisation approfondie du code existant.

C'est là que l'écueil apparaît. Je dirais même qu'un rocher sous-marin apparaît. Que se passe-t-il si vous prenez un analyseur statique et vérifiez que le projet "ordinaire" est conforme à la norme MISRA? Spoiler: vous pouvez avoir peur.

Figure 5


À droite, l'exemple de l'image est exagéré. Il montre le résultat de la vérification d'un projet assez important qui n'était pas réellement destiné à travailler sur des microcontrôleurs. Cependant, lors de la vérification du code déjà existant, vous pouvez très bien recevoir un, deux, trois ou même dix mille avertissements de l'analyseur. De nouveaux avertissements, émis pour du code nouveau ou modifié, seront simplement perdus dans ce gros tas d'avertissements.

Que pouvez-vous y faire? Devez-vous vraiment reporter toutes les tâches et tout mettre en œuvre pour corriger les anciens avertissements?

En tant que développeurs de l'analyseur statique, nous savons que tant d'avertissements apparaissent après la vérification. Par conséquent, nous avons développé la solution, qui peut aider à utiliser immédiatement l'analyseur sans arrêter le travail. Cette solution est appelée "supprimer la base".

Les bases de suppression représentent le mécanisme PVS-Studio qui vous permet de supprimer massivement les messages de l'analyseur. Si vous vérifiez un projet pour la première fois et obtenez plusieurs milliers d'avertissements - il vous suffit de les ajouter dans une base de suppression et la prochaine exécution ne vous donnera aucun avertissement.

De cette façon, vous pouvez continuer à écrire et à modifier le code comme d'habitude, et ce faisant, vous obtiendrez des messages uniquement sur les bogues qui viennent d'être créés dans le projet. Ainsi, vous tirerez le meilleur parti de l'analyseur ici et maintenant, sans être distrait par le ratissage d'anciens bogues. Quelques clics - et l'analyseur est intégré à votre développement! Vous pouvez lire les instructions détaillées à ce sujet ici .

Vous vous demandez probablement: «Attendez, qu'en est-il des avertissements cachés?» La réponse est assez simple: ne les oubliez pas et corrigez-les par étapes faciles. Par exemple, vous pouvez charger la base de suppression dans le système de contrôle de version et autoriser uniquement les validations qui n'augmentent pas le nombre d'avertissements. Ainsi, petit à petit, votre «rocher sous-marin» se brisera tôt ou tard sans laisser de trace.

D'accord, l'analyseur est maintenant adopté avec succès et nous sommes prêts à continuer. Que faire ensuite? La réponse est évidente - travaillez avec le code! Mais que faut-il pour pouvoir déclarer la conformité à la norme? Comment prouvez-vous que votre projet est conforme à MISRA?

En fait, il n'y a pas de "certificat" spécial que votre code correspond à MISRA. Comme le stipule la norme, le suivi de la conformité doit être effectué par deux parties: le client du logiciel et le fournisseur du logiciel. Le vendeur développe un logiciel conforme à la norme et remplit les documents nécessaires. Le client, à son tour, doit s'assurer que les données de ces documents sont vraies.

Si vous développez un logiciel pour vous-même, la responsabilité de respecter la norme incombera uniquement à vos épaules :)

En général, pour prouver la conformité de votre projet, vous aurez besoin de pièces justificatives. La liste des documents que les développeurs de projets doivent préparer peut varier, mais MISRA propose un ensemble comme référence. Examinons de plus près cet ensemble.

Vous aurez besoin de ces éléments pour appliquer la conformité standard:

  • Le projet lui-même, dont le code est conforme aux règles obligatoires et obligatoires
  • Guider le plan d'application
  • Documentation sur tous les avertissements du compilateur et de l'analyseur statique
  • Documentation pour tous les écarts par rapport aux règles requises
  • Résumé de la conformité aux lignes directrices

Le premier est un plan d'application du guide. Il s'agit de votre tableau le plus important et il contient des références à tous les autres documents. Dans sa première colonne est une liste des règles MISRA, dans le reste, il est noté s'il y a eu des écarts par rapport à ces règles. Ce tableau ressemble à ceci:

Image 1

La norme recommande de construire votre projet avec plusieurs compilateurs, ainsi que d'utiliser deux analyseurs statiques ou plus pour tester la conformité de votre code. Si le compilateur ou l'analyseur émet un avertissement lié à une règle, vous devez le noter dans le tableau et documenter les points suivants: pourquoi l'avertissement ne peut pas être corrigé, qu'il soit faux ou non, etc.

Si l'une des règles ne peut pas être vérifiée par un analyseur statique, vous devez effectuer une révision manuelle du code. Cette procédure doit également être documentée, après quoi un lien vers cette documentation doit être ajouté au plan de conformité.

Si le compilateur ou l'analyseur statique s'avère correct, ou s'il existe des violations de règles valides pendant le processus de révision du code, vous devez soit les corriger, soit les documenter. Encore une fois, en attachant le lien vers la documentation dans le tableau.

Ainsi, un plan de conformité est un document qui fournira de la documentation pour tout écart identifié dans votre code.

Abordons brièvement la documentation directe des écarts par rapport aux règles. Comme je l'ai mentionné, une telle documentation n'est nécessaire que pour les règles requises, car les règles obligatoires ne peuvent pas être violées et les règles consultatives peuvent être violées sans aucune documentation.

Si vous choisissez de déroger à la règle, la documentation doit inclure:

  • Le numéro de la règle violée
  • L'emplacement exact de l'écart
  • La validité de l'écart
  • Preuve que l'écart ne compromet pas la sécurité
  • Conséquences potentielles pour l'utilisateur

Comme vous pouvez le voir, une telle approche de la documentation vous fait sérieusement vous demander si la violation en vaut la peine. Cela a été fait spécifiquement pour ne ressentir aucune envie de violer les règles requises :)

Maintenant sur le résumé de la conformité aux règles. Ce document sera peut-être le plus facile à remplir:

Image 3

La colonne centrale est remplie avant de commencer à travailler avec le code, et la bonne - une fois votre projet prêt.

Voici une question raisonnable: pourquoi les catégories de règles devraient-elles être spécifiées, si elles sont déjà spécifiées dans la norme elle-même? Le fait est que la norme permet de "promouvoir" une règle dans une catégorie plus stricte. Par exemple, un client peut vous demander de classer une règle de conseil. Une telle "promotion" doit être faite avant de travailler avec le code, et le résumé de la conformité aux règles vous permet de le noter explicitement.

Quant à la dernière colonne, c'est assez simple: il suffit de noter si la règle est utilisée, et si oui, s'il y a des écarts par rapport à elle.

Cette table entière est nécessaire pour que vous puissiez voir rapidement quelles sont les règles de priorité et si le code les respecte. Si vous êtes soudain intéressé à connaître la cause exacte de l'écart, vous pouvez toujours vous tourner vers le plan de conformité et trouver la documentation dont vous avez besoin.

Figure 6

Vous avez donc soigneusement écrit le code en suivant les règles MISRA. Vous avez élaboré un plan de conformité et documenté tout ce qui pourrait être documenté, et vous avez rempli votre curriculum vitae de conformité. Si c'est effectivement le cas, alors vous avez un code très propre, très lisible et très fiable que vous détestez maintenant :)

Où vivra votre programme maintenant? Dans un appareil d'IRM? Dans un capteur de vitesse ordinaire ou dans le système de contrôle d'un satellite spatial? Oui, vous avez parcouru un chemin bureaucratique sérieux, mais ce n'est pas grave. Quand il s'agit de vraies vies humaines, vous devez toujours être scrupuleux.

Si vous avez réussi et réussi à atteindre la fin victorieuse, je vous félicite sincèrement: vous écrivez du code sécurisé de haute qualité. Je vous remercie!

L'avenir des normes


Pour la finale, j'aimerais m'attarder sur l'avenir des standards.

Maintenant, Misra vit et évolue. Par exemple, "The MISRA C: 2012 Third Edition (First Revision)" est une édition révisée et agrandie avec de nouvelles règles annoncée au début de 2019. Dans le même temps, la prochaine version de "MISRA C: 2012 Amendment 2 - C11 Core », qui est une norme révisée de l'année 2012, a été annoncé. Ce document comprendra des règles qui couvrent pour la première fois les versions en langage C des années 2011 et 2018.

MISRA C ++ continue également d'évoluer. Comme vous le savez, la dernière norme de MISRA C ++ est datée de 2008, donc la version la plus ancienne du langage qu'elle couvre est C ++ 03. Pour cette raison, il existe une autre norme similaire à MISRA, et elle s'appelle AUTOSAR C ++. Il était à l'origine destiné à être une continuation de MISRA C ++ et devait couvrir les versions ultérieures du langage. Contrairement à son cerveau, AUTOSAR C ++ est mis à jour deux fois par an et prend actuellement en charge C ++ 14. De nouvelles mises à jour C ++ 17 puis C ++ 20 sont à venir.

Pourquoi ai-je commencé à parler d'une autre norme? Le fait est qu'il y a un peu moins d'un an, les deux organisations ont annoncé qu'elles fusionneraient leurs normes en une seule. MISRA C ++ et AUTOSAR C ++ deviendront un standard unique et évolueront désormais ensemble. Je pense que c'est une excellente nouvelle pour les développeurs qui écrivent pour les microcontrôleurs en C ++, et pas moins une excellente nouvelle pour les développeurs d'analyseurs statiques. Il y a encore beaucoup à faire! :)

Conclusion


Aujourd'hui, nous espérons que vous avez beaucoup appris sur MISRA: lisez l'histoire de son origine, étudié les exemples de règles et de concept de la norme, examiné tout ce dont vous aurez besoin pour utiliser MISRA dans vos projets et même aperçu de l'avenir. J'espère maintenant que vous comprenez mieux ce qu'est MISRA et comment le cuisiner!

Dans la vieille tradition, je vais laisser ici un lien vers notre analyseur statique PVS-Studio. Il est capable de trouver non seulement des écarts par rapport à la norme MISRA, mais également une vaste gamme d'erreurs et de vulnérabilités. Si vous êtes intéressé à essayer PVS-Studio vous-même, téléchargez la version de démonstration et vérifiez votre projet.

C'est là que mon article se termine. Je souhaite à tous les lecteurs un joyeux Noël et de joyeuses fêtes de fin d'année!

Source: https://habr.com/ru/post/fr482486/


All Articles