Coccinelle (logiciel)
# Coccinelle (logiciel)

Le logiciel Coccinelle, un outil de correspondance et transformation en langage C, a été réalisé en 2008 par l’actuelle équipe de recherche Whisper (Équipe de projet commune entre l’Inria et la Sorbonne Université) pour faciliter les spécifications et automatisations de l'évolution du noyau Linux. La nouvelle contribution de Coccinelle fut d'autoriser les développeurs à écrire des règles de manipulation de code directement dans la structure syntaxique du code, via la généralisation de syntaxe (en) de patch. Au fil des années, l’outil Coccinelle a été largement utilisé dans le développement du noyau Linux, aboutissant à plus de 6000 commits, et a trouvé sa place dans le processus de développement de Linux.

## Caractéristiques de l'outil Coccinelle

Coccinelle est un programme de correspondance et un outil de transformation pour le code en C. Il est utilisé pour la découverte de bugs dans les évolutions du noyau Linux et développé par Lawall, Muller et coll. depuis 2008. Coccinelle a été à l'origine conçu pour cibler les évolutions collatérales des pilotes de périphériques Linux, où le but était de mettre à jour le code client en réponse à un changement de l'interface d'une bibliothèque. Coccinelle a aussi été largement utilisé pour trouver et fixer des $bugs^,.$ L'outil coccinelle est conçu pour être facile à utiliser par les développeurs de logiciels, sans exiger d’expertise dans l'analyse de programme, la transformation de programme, ou la conception interne de l'outil lui-même. À cette fin, l’outil de transformation Coccinelle et les règles de découverte de bug sont exprimées en utilisant une syntaxe qui est proche de celle d’un patch. Étant donné que Coccinelle tient compte de la sémantique du langage C, notamment sa structure de contrôle, Lawall et coll. font référence à l’outil de transformation Coccinelle ou à la spécification de recherche de bug comme un patch sémantique (semantic patch). En 2014, presque 2000 patchs acceptés dans le noyau Linux ont été créées en utilisant Coccinelle, y compris environ 700 patchs créés par 90 développeurs n’appartenant pas au groupe de recherche de Coccinelle.

Coccinelle est conçu autour d'un langage dédié (en anglais, domain-specific language ou DSL), SmPL (Semantic Patch Language), pour exprimer des changements en termes d'une forme abstraite de patch, mentionné comme un patch sémantique. À la différence d’un patch classique, qui est lié aux lignes et fichiers spécifiques dans le code source, un patch sémantique simple peut mettre à jour tous les emplacements appropriés dans la base de code entière.

La figure 1 montre les étapes principales exécutées par le moteur de Coccinelle. Les points clefs dans sa conception sont les stratégies pour (i) faire face au préprocesseur C (cpp), être capables de préserver le style de code original, (ii) faire l’ abstraction de la syntaxe et des variations de structure de contrôle et (iii) appliquer le code de transformation efficacement. Le résultat de correspondance de la formule CTL avec le CFG est une collection de nœuds où une transformation est requise, le fragment du patch sémantique qui correspond à ces nœuds et les liens de métavariable. Le moteur propage alors les - et + des annotations sur le patch sémantique aux tokens (en) correspondants aux nœuds correspondants du CFG, et ensuite à l’arbre de syntaxe abstraite. Le moteur unparse (en) l’arbre de syntaxe abstraite en supprimant n'importe quel token annoté avec - et en ajoutant les + du patch sémantique, comme approprié. N'importe quel métavariables dans l’ajout supplémentaire des + dans le code sont instanciés selon les liens établis par le processus de correspondance CTL.

* Les méthodes utilisées par l'outil Coccinelle:

### Isomorphisme

    Les isomorphismes assimilent sémantiquement des fragments de code équivalents, pour extraire des variations dans le style de code, et l'utilisation de logique temporelle pour extraire des variations dans les chemins d'exécution spécifiques des périphériques. Le résultat de généricité implique qu’un simple patch sémantique de moins de 50 lignes peut suffire pour mettre à jour plus de 500 fichiers.

### CTL (Logique du temps arborescent (en))

    Le patch sémantique SmPL est compilé dans une formule de logique temporelle (CTL). La correspondance de la formule avec le modèle est alors mise en œuvre utilisant une variante d'un modèle standard vérifiant l'algorithme. Tandis que CTL est probablement peu familier à la plupart des mainteneurs de pilote, il sert seulement comme un langage d’ assembleur, que le mainteneur de pilote ne doit pas lire ou comprendre.

### CFG (Graphe de flot de contrôle)

    Padioleau et coll. utilisent des chemins dans le graphe de flux de contrôle (CFG), comme une approximation du patron d'opérations exécutées au temps d(exécution par un pilote. Ainsi, une séquence de termes dans un patch sémantique SmPL correspond à une séquence de termes du langage C le long d'un chemin dans le CFG.

### Vérification de modèles

    Pour raisonner en graphes de flux de contrôle, Padioleau et coll. ont basé le moteur Coccinelle sur la technologie vérification de modèles, qui est orienté graphe. Dans cette approche, chaque bloc (en) au plus haut niveau de code source C (par exemple, une fonction (en) ou une macro-définition) est traduit dans un graphique de flux de contrôle.

### Stratégie d'adaptation au préprocesseur C (cpp)

    Un analyseur syntaxique qui est capable d’adapter beaucoup d'utilisations des directives du préprocesseur C. Les commentaires et les espaces blancs (en) sont maintenus où c’est possible dans le code transformé pour préserver la capacité de comprendre et maintenir le pilote. Parce que les évolutions collatérales sont justes un pas dans la maintenance en cours d'un pilote de périphérique Linux, le moteur Coccinelle doit générer un code qui est lisible et dans le style du code source original, y compris l'utilisation de constructions cpp. En outre, une évolution collatérale peut impliquer des constructions cpp. Donc, Coccinelle fait l'analyse syntaxique du code C, sans étendre des directives du préprocesseur cpp, pour qu'elles soient préservés tant dans le processus de transformation que dans le code généré.

## Origines du projet Coccinelle

Dans les systèmes d’exploitation (OS) modernes, les pilotes des périphériques peuvent constituer 70% du code source. Le code du pilote est lui aussi fortement dépendant du reste du code source de l’OS, pour ses fonctions ainsi que la structure de données définie dans le noyau et les bibliothèques de support des pilotes. En conséquence, n’importe quels changements des interfaces du noyau ou des bibliothèques de support des pilotes vont probablement déclencher des modifications dans le code du périphérique pour rétablir son bon fonctionnement. Yoann Padioleau, Julia Lawall et Gilles Muller font référence, en octobre 2006, à ces modifications comme des évolutions collatérales. Elles peuvent entraîner des réorganisations de code substantielles, qui prennent du temps et sont sujettes aux erreurs. Le besoin d'évolutions collatérales peut donc gêner l'évolution de l'OS en pratique. C’est ainsi que Padioleau, Lawall et Muller ont commencé à examiner les problèmes révélés par ces évolutions collatérales dans le contexte de Linux.

En janvier 2007, ils ont proposé un langage de transformation déclaratif, SmPL (Semantic Patch Language), pour exprimer précisément les évolutions collatérales des pilotes de périphériques Linux. La communauté des programmeurs Linux est habitués à l'échange, la lecture et la manipulation de patchs qui fournissent un rapport des changements précédemment exécutés. Padioleau et coll. ont ainsi axé la syntaxe de SmPL sur la notation de fichier de patch. À la différence des patchs habituels, qui enregistrent les changements dans des fichiers spécifiques, SmPL peut décrire les transformations génériques qui s'appliquent aux évolutions collatérales multiples. Ce fut une première étape dans le projet de développer l’outil de transformation Coccinelle, fournissant une assistance automatisée pour exécuter des évolutions collatérales. Cette assistance comprend le langage SmPL pour spécifier les évolutions collatérales et un moteur de transformation pour les appliquer au code des pilotes de périphériques. Le projet de développement de Coccinelle est soutenu par le Conseil de Recherche danois (Danish Research Council for Technology and Production) des universités de Copenhague et Aalborg et l’institut national de recherche en sciences et technologies du numérique (Inria) en France.

## Les évolutions collatérales

### Le problème des évolutions collatérales

L’équipe Whisper a évalué les divers aspects du besoin d'évolutions collatérales dans les pilotes de périphériques Linux, utilisant des outils d'extraction de données ad hoc qu’ils ont développé. Ces résultats montrent que les bibliothèques de support des pilotes et les fichiers spécifiques des périphériques qui en dépendent sont nombreux et leurs relations complexes. Yoann Padioleau, René R. Hansen, Julia Lawall et Gilles Muller ont ainsi identifié en 2006, dans la version 2.6.13 du noyau Linux, 150 bibliothèques de support de pilotes et presque 2000 fichiers spécifiques des périphériques. Un fichier spécifique de périphérique peut utiliser jusqu'à 59 fonctions de bibliothèque différentes. Plutôt que de devenir plus stable, cette base de code se développe de plus en plus rapidement.

Ils ont constaté que le nombre d'évolutions dans les éléments d'interface croient fortement, avec 300 évolutions probables dans le code de Linux 2.2 et plus de 1200 dans Linux 2.6 jusqu'à Linux 2.6.13. Certaines de ces évolutions déclenchent des évolutions collatérales dans presque 400 fichiers. Entre Linux 2.6.9 et Linux 2.6.10, plus de 10 000 lignes de code périphériques spécifique, affectées par des évolutions collatérales, ont été trouvées.

### Les divers aspects du processus des évolutions collatérales

Avant l’arrivée de l’outil Coccinelle, ces évolutions suivaient ce procédé typique : Quand un développeur fait un changement dans une bibliothèque Linux interne qui a un impact sur une API, il met manuellement à jour tout le code spécifique du périphérique dans l'arborescence source Linux, basé sur sa compréhension de l'évolution et son approche des pilotes concernés. Ensuite, les mainteneurs des nombreux pilotes extérieurs à l'arborescence source de Linux exécutent l'évolution collatérale dans leurs propres codes. Ces mainteneurs de pilotes n'ont pas la connaissance immédiate de cette évolution et doivent ainsi déduire comment elle s'applique à leurs codes depuis n'importe quels commentaires de code disponibles, de mails informels et de patchs souvent volumineuses. Finalement, des utilisateurs motivés appliquent les évolutions collatérales pour coder ce qui a été omis par le développeur de bibliothèque ou le mainteneur de pilotes. Et ce cas pose problème au mainteneur de pilotes car ces utilisateurs ne peuvent avoir aucune expérience avec l'évolution collatérale ou le code des pilotes.

Comme Linux est un OS open source, beaucoup de programmeurs différents contribuent à son développement. En effet, les mainteneurs de pilote ne sont souvent pas des experts du noyau, mais plutôt des experts d’un périphérique donné ou même des utilisateurs ordinaires qui constatent que leur matériel n'est pas correctement supporté. Parce que les développeurs qui mettent à jour le noyau et les bibliothèques de support des pilotes ne partagent pas souvent de langage commun et une expertise avec le mainteneur de périphérique, la documentation d'évolutions collatérales complexes est souvent incomplète.

### Les précédentes tentatives de résolution

La réutilisation de pilotes de périphériques a été tentée par la restructuration des systèmes d'exploitation utilisant une approche de micro-noyau. Goel et Duchamp ont émulé des pilotes de périphériques de Linux sur un micro-noyau Mach 4.0, avec des résultats de performance décevants . L’architecture Chorus/MiX a aussi essayé de démultiplier des pilotes de périphériques existants en les exécutants comme des entités indépendantes. Cependant, cette solution a fourni une migration moins transparente qu'attendue, et quelques adaptations étaient toujours requises. Une approche semblable avait été entreprise dans le système Minix, bien qu’elle soit plus centrée sur la conception de systèmes minimaux pour des objectifs de fiabilité qu'en réutilisant du logiciel hérité.

## Semantic patches (SmPL)

SmPL est l’acronyme pour “Semantic Patch Language”, il se prononce “simple” en Français.

### Les buts de ce nouveau langage

La communauté Linux utilise divers outils pour mieux analyser le langage C. Sparse est une bibliothèque qui, comme un compilateur front end, fournit l’accès à l'arbre de syntaxe abstraite et l'information de saisie d'un programme en C. Cette bibliothèque a été utilisée pour implémenter quelques analyses statiques ciblant la détection de bug, construite sur des annotations supplémentaires aux déclarations de variables, dans l'esprit de static et constant. Smatch est un projet semblable qui permet à un développeur d'écrire des scripts en Perl pour analyser du code en C. Ces deux projets ont été inspirés par le travail d'Engler et coll. sur l’automatisation de la recherche de bug dans les codes de systèmes d’exploitation. Ces exemples montrent que la communauté Linux est ouverte à l'utilisation d'outils automatisés pour améliorer la qualité du code, particulièrement quand ces outils sont construits sur les secteurs traditionnels d'expertise des développeurs Linux.

Pour être capable de décrire génériquement des évolutions collatérales, en restant cohérent avec le modèle de développement de code du noyau Linux, Padioleau et coll. ont étendu la notation de patch pour inclure les aspects de la sémantique du langage C, et non juste sa syntaxe. Ils font ainsi référence à des patchs sémantiques (semantic patches) pour leurs spécifications. En utilisant ces patchs sémantiques, ils affinent le modèle de patch décrit ci-dessus. Ainsi seul le développeur de bibliothèque applique manuellement l'évolution collatérale à quelques fichiers de pilotes, pour obtenir un sens aux changements qui sont exigés et écrit ensuite des patchs sémantiques qui peuvent être appliquées aux fichiers restants et distribuées à d'autres mainteneurs de pilotes. Le but des patchs sémantiques est de s'appliquer indépendamment du style de code, mais ce n'est pas possible en pratique de prévoir toutes les variations possibles. Ainsi, l'outil devrait non seulement appliquer des patchs sémantiques, mais devrait être aussi capable d'aider le développeur ou le mainteneur de pilote quand une correspondance exacte de la règle avec le code source n'est pas possible.

### Syntaxe de SmPL

En général, le patch sémantique a la forme d'un patch traditionnel, consistant en une séquence de règles dont chacune commence par une information de contexte délimitée par une paire de @@ et spécifie ensuite une transformation appliqué dans ce contexte.

Exemple d'un patch sémantique pour mettre à jour des fonctions SCSI proc_info avec l'outil diff :

Dans le cas d’un patch sémantique, l'information de contexte ne déclare pas des numéros de ligne, mais un groupe de métas variables. Un méta variable peut correspondre à n'importe quel terme indiqué dans sa déclaration (identificateur, expression, etc), de telle sorte que toutes les références à un méta variable donné correspondent au même terme. La règle de transformation est spécifiée comme dans un fichier de patch traditionnel, avec un terme ayant la forme du code à être transformé. Ce terme est annoté avec les modificateurs - et + pour indiquer le code qui doit être respectivement supprimé et ajouté. Les lignes 1-5 du patch sémantique du code ci-dessus déclarent une collection de métas variables. La plupart de ces métas variables sont utilisées dans la fonction d’ en-tête aux lignes 6-9 pour spécifier le nom de la fonction qui sert à transformer et les noms de ses paramètres. L’action de spécifier la fonction d'en-tête en termes de métas variables identifie efficacement la fonction qui sert à transformer en des termes de son prototype. Ce qui est défini par la bibliothèque SCSI et est ainsi commun à toutes les fonctions proc_info. A noter que quand une définition de fonction est transformée, le prototype correspondant est aussi transformé automatiquement de la même manière ; il n'est donc pas nécessaire de spécifier explicitement la transformation d'un prototype de patch sémantique. Le reste du code spécifie le déplacement des fragments de code divers décrits au-dessus du corps de la fonction. Comme le code à supprimer n'est pas nécessairement contigu, ces fragments sont séparés par l'opérateur SmPL "...", qui correspond à n'importe quel ordre d'instructions. La pièce sémantique spécifie aussi qu'une ligne devrait être ajoutée : la déclaration indiquée à la ligne 11 pour être enlevé du corps de fonction est spécifiée pour être ajouté à la liste de paramètre à la ligne 7 par une référence répétée au méta variable hostptr. En général, la règle s'applique indépendamment des espacements, des sauts de ligne et des commentaires. De plus, le moteur de transformation est paramétré par une collection d'isomorphismes spécifiant les ensembles des équivalences qui sont prises compte en appliquant la règle de transformation.

L’équipe Whisper commençait à concevoir les prémices d’une structure, Coccinelle, qui inclut un langage, SmPL dans lequel s’expriment les patchs sémantiques qui décrivent des évolutions collatérales et un outil de transformation pour appliquer ces patchs sémantiques au code spécifique des périphériques. Pour s’adapter aux habitudes des développeurs Linux et fournir une syntaxe lisible, SmPL est basé sur le format de patch standard.

### Exemple d’autres structures de transformation de programmes

D’autres structures de transformation de programme ont été proposées, s’appuyant sur des langages comme C et Java. CIL (en) et XTC sont essentiellement des analyseurs syntaxiques qui fournissent un support pour mettre en œuvre des parcours d'arbres de syntaxes abstraites. CIL gère aussi le code source du langage C en termes de représentation intermédiaire plus simple. Réécrire des règles doit être exprimé en termes de cette représentation plutôt qu'en termes de code trouvé dans le pilote approprié. Stratego (en) est un langage dédié qui sert à écrire des transformations de programme. Un filtrage par motif correct et des stratégies de gestion de règle y sont intégrés et impliquent que le développeur peut spécifier les transformations devant arriver sans encombrer le code avec la mise en œuvre de mécanismes de transformation. Néanmoins, seulement quelques analyses de programme sont fournies. Les autres analyses qui sont exigées, comme l'analyse de flux de contrôle, doivent être mises en œuvre dans le langage Stratego. D’après Padioleau et coll., cela mène à des règles qui sont très complexes pour exprimer des évolutions collatérales même simples.

## Évolutions de l'outil Coccinelle

### Introduction des langages de script

L'interface de langage de script a été initialement motivée dans le but d'utiliser Coccinelle pour trouver des bugs. Les bugs qui dépendent principalement de la structure du code, comme la vulnérabilité use-after-free(oubli par un développeur de réinitialiser un pointeur après une libération de la mémoire), pourraient être trouvés; alors que le filtrage par motif des fonctionnalités de Coccinelle n'était pas suffisant pour détecter des bugs comme le dépassement de tampon qui exige le raisonnement des variables d’environnement. Pour permettre le raisonnement de l'information arbitraire, un support a été ajouté en 2008 pour les règles de langage de script. Le premier langage supporté était Python, qui était attendu comme familier aux développeurs Linux. Coccinelle est implémenté dans OCaml, et le script OCaml a été ajouté en 2010, pour la commodité des développeurs Coccinelle. Les scripts ont été à l'origine conçus pour filtrer les ensembles de métas variables établies selon les règles précédentes.

Le code ci-dessous montre un exemple de suppression d’un point-virgule après un en-tête « if » si l’ expression de sous-suite est désignée, suggérant que la dernière expression soit indentée pour être dans le branchement « if ». Une règle de script compare l' indentation des deux expressions (ligne 11) et annule le méta variable des environnements de liaisons (ligne 12) dans lequel l’ instruction conditionnelle est alignée avec ou à droite de l’expression de sous-suite.

Finalement, la motivation première pour le script, c'est-à-dire trouver des bugs comme le dépassement de tampon, n'était pas couronné de succès. En effet, les modèles de code étaient petits et génériques et les scénarios implémentant les analyses exigées étaient complexes. Cependant, le script a été un bond en avant pour l'expressivité de Coccinelle et des nouvelles fonctionnalités de script ont été ajoutées comme de nouveaux besoins ont émergé. Dès le début, les bibliothèques ont été ajoutées pour produire des messages d'erreur formatés. En 2009, les scripts initialize et finalize (en) ont été introduits pour permettre de définir l'état global du traitement de tous les fichiers, faciliter la collection de statistiques. En 2010, les scripts sont devenus capables de créer des nouveaux fragments de code pouvant être stockés dans des métas variables et hérités selon des règles de sous-suite. En 2016, pour améliorer la performance et réduire la taille du patch sémantique, il est devenu possible d'ajouter du code de script aux déclarations de méta variable, pour définir les prédicats qui annulent les liaisons de métas variable au début du processus de comparaison. Finalement, le script autorise l'itération, qui permet à un patch sémantique de soumettre de nouveaux jobs au moteur de Coccinelle, pour exécuter l'analyse à travers de multiples fichiers.

### Sécurité et détection de vulnérabilités par Coccinelle

**OpenSSL**

Dans ce projet, Lawall et coll. ont utilisé Coccinelle sur un type de bug qui a été précédemment mis en évidence dans le code d'OpenSSL selon le rapport CVE-2008-5077 de vulnérabilité de sécurité à la suggestion de Ben Laurie, qui est un expert OpenSSL. Cette vulnérabilité est basée sur l'observation que beaucoup de fonctions dans OpenSSL retournent des entiers faux-positifs pour indiquer les divers types d'erreurs. Néanmoins, le code callsite (en) errorchecking considère souvent seulement le 0 comme une erreur et toute autre valeur comme réussie. Ce modèle n'existe pas dans Linux et la connaissance spécifique de OpenSSL est nécessaire. Lawall et coll. ont détecté environ 30 bugs dans un snapshot d'OpenSSL (openssl-1.0.0-stable-snap-20090911). Dans des nombreux cas, ils étaient capables d'utiliser les capacités de transformation de programme du moteur Coccinelle pour corriger automatiquement ces bugs. La plupart des patchs de correction de ces bugs ont été soumis aux développeurs OpenSSL et tous ces patchs correctifs ont été acceptés. Le tableau 1 présente les rapports donnés par les règles du patch sémantique qui détecte des tests directs et le tableau 2 présente les rapports donnés par les règles du patch sémantique qui détecte des tests sur des valeurs stockées. Acc. (Accepté) indique le nombre de bugs pour lesquels les patchs ont été soumis et acceptées par les développeurs OpenSSL. FP indique le nombre de faux positif. Unk. (Inconnu) indique des rapports dont Lawall et coll. n’étaient pas capables de classifier comme des bugs ou des faux positifs. En général, le taux de faux positif est aux alentours de 50 %. Ce taux est haut, mais le nombre complet de rapports est peu élevé. Ils s’attendent à ce que cela puisse être fait plus rapidement par un expert de OpenSSL.

Tableau 1 :

| | Bugs | Acc. | FP | Unk. | Files |
| - | - | - | - | - | - |
| ASN1_item _ex _d2i | 0 | 0 | 1 | 0 | 1 |
| BIO_ctrl | 1 | 0 | 0 | 0 | 1 |
| BIO_write | 6 | 6 | 0 | 0 | 3 |
| BN_exp | 1 | 1 | 0 | 0 | 1 |
| CMS_get1_ReceiptRequest | 2 | 2 | 0 | 0 | 1 |
| ENGINE_ctrl | 4 | 4 | 1 | 0 | 2 |
| EVP_PKEY_cmp_parameters | 0 | 0 | 1 | 0 | 1 |
| EVP_PKEY_sign | 1 | 1 | 0 | 0 | 1 |
| OPENSSL_isservice | 1 | 1 | 2 | 0 | 3 |
| RAND_bytes | 4 | 3 | 0 | 0 | 4 |
| RAND_pseudo_bytes | 2 | 0 | 0 | 0 | 1 |
| UI_ctrl | 0 | 0 | 2 | 0 | 2 |
| X509_STORE_get_by_subject | 0 | 0 | 0 | 2 | 1 |
| X509_check_purpose | 0 | 0 | 0 | 1 | 1 |
| asn1_cb | 0 | 0 | 10 | 0 | 3 |
| asn1_check_tlen | 0 | 0 | 2 | 0 | 1 |
| i2a_ASN1_INTEGER | 1 | 1 | 0 | 0 | 1 |
| i2a_ASN1_OBJECT | 1 | 1 | 0 | 0 | 1 |
| sk_num | 0 | 0 | 3 | 0 | 1 |
| TOTAL | 26 | 20 | 20 | 3 | 30 |

Tableau 2 :

| | Bugs | Acc. | FP | Unk. | Files |
| - | - | - | - | - | - |
| ASN1_INTEGER_get | 0 | 0 | 2 | 0 | 2 |
| BIO_ctrl | 1 | 1 | 0 | 0 | 1 |
| EVP_DigestVerifyFinal | 1 | 1 | 0 | 0 | 1 |
| EVP_SealInit | 1 | 1 | 0 | 0 | 1 |
| RAND_bytes | 1 | 1 | 0 | 0 | 1 |
| SSLStateMachine_read_extract | 0 | 0 | 1 | 0 | 1 |
| UI_UTIL_read_pw | 0 | 0 | 1 | 0 | 1 |
| X509_check_purpose | 0 | 0 | 1 | 1 | 2 |
| asn1_cb | 0 | 0 | 4 | 0 | 2 |
| asn1_check_tlen | 0 | 0 | 2 | 0 | 1 |
| asn1_template_noexp_d2i | 0 | 0 | 1 | 0 | 1 |
| dtls1_retrieve_buffered_fragment | 0 | 0 | 0 | 1 | 1 |
| get_cert_chain | 0 | 0 | 1 | 0 | 1 |
| i2b_PVK_bio | 2 | 2 | 0 | 0 | 2 |
| ocsp_check_issuer | 0 | 0 | 1 | 0 | 1 |
| TOTAL | 6 | 6 | 14 | 2 | 19 |

Dans un autre projet, Lawall et coll. ont développé un outil, Herodotos, qui suit à la trace l'histoire des fragments de code qui correspondent à un patch sémantique donné sur les versions multiples d'un projet de logiciel. Ils ont appliqué Herodotos aux versions OpenSSL 0.9.8a par 0.9.8j, sortis entre 2005 et 2008, et aux semantic pachs définis dans les tableaux 1 et 2, pour obtenir un historique d'erreurs traitant des bugs. Ils ont constaté que presque tous les bugs trouvés ont été présents depuis au moins la version 0.9.8a, avec une poignée introduit à une date ultérieure, en raison d'un certain changement du code ou l'introduction d'un nouveau fichier.

Jana et coll. ont aussi cherché des contrôles d'erreur dans OpenSSL avec leur outil EPEx, en s’assurant en plus que l'erreur soit correctement traitée. Cela leur a permis de trouver une classe significativement plus grande de traitements des erreurs. Aussi, avec leur approche, ils ont un taux peu élevé de faux positif.

**CERT C Secure Coding Standard**

Olesen et coll. ont adapté l’outil Coccinelle dans un outil, Clang, pour analyser et certifier des programmes en C, en accord avec le CERT C Secure Coding Standard et le standard MISRA (the Motor Industry Software Reliability Association) C. Ils soutiennent qu'un tel outil doit être fortement adaptable et customisable à chaque projet de logiciel aussi bien qu'aux règles de certification exigées par une norme donnée.

**Recherche de vulnérabilités sur Android**

Lu et coll. ont expérimenté le langage SmPL de Coccinelle pour évaluer les différentes éditions d'Android. Ils ciblent principalement trois types d’utilisations défectueuses des pointeurs.

**Recherche de vulnérabilités sur Android**

**Memory not released (Mémoire (en) non libérée)**


    Si la mémoire dynamique pointée par le pointeur n'est pas libérée après utilisation, alors il y a une fuite de mémoire.

**Recherche de vulnérabilités sur Android**

**Null pointer reference (Référence de pointeur nul (en))**


    Si un pointeur ne se déclare pas avant qu'il soit utilisé ou un pointeur nul est utilisé comme un objet, il y aura quelques fautes d’utilisations des pointeurs qui peuvent être des vulnérabilités.

**Recherche de vulnérabilités sur Android**

**Usage of float pointer (Utilisation de pointeur avec virgule flottante)**


    Lorsque la mémoire ciblée par le pointeur est utilisée et libérée, la mémoire ciblée par le pointeur retourne au système d'exploitation. L'indicateur devient une virgule flottante à 1. S'il n'est pas traité correctement, il y aura une faute (en) de référence du pointeur.

Pour leurs expérimentations, Lu et coll. ont utilisé trois éditions différentes d'Android, 2.1, 3.0 et 4.0 pour trouver les possibilités de fautes dans les codes. Ils ont obtenu 48 fautes avec Android 2.1, dont il y a 9 vulnérabilités confirmées. La raison des faux positifs est que Coccinelle n'a pas la capacité de faire l’analyse de flux de données (en) et ne peut pas couper les branchements qui ne sont pas accessibles.

Resultat Android 2.1 :

| Type de Faute | Faute | Erreur | Total |
| - | - | - | - |
| Type de Faute | NUM | NUM | NUM |
| Mémoire non libérée | 5 | 22 | 25 |
| Référence de pointeur nul | 3 | 11 | 24 |
| Utilisation de pointeur avec virgule flottante | 1 | 8 | 9 |

Resultat Android 3.0 :

| Type de Faute | Faute | Erreur | Total |
| - | - | - | - |
| Type de Faute | NUM | NUM | NUM |
| Mémoire non libérée | 9 | 49 | 51 |
| Référence de pointeur nul | 2 | 11 | 13 |
| Utilisation de pointeur avec virgule flottante | 2 | 12 | 14 |

Resultat Android 4.0 :

| Type de Faute | Faute | Erreur | Total |
| - | - | - | - |
| Type de Faute | NUM | NUM | NUM |
| Mémoire non libérée | 7 | 36 | 40 |
| Référence de pointeur nul | 2 | 21 | 23 |
| Utilisation de pointeur avec virgule flottante | 1 | 9 | 10 |

### Évolutions des performances

Une des premières observations de Lawall et coll. était que la performance pourrait être améliorée en ne faisant pas l'analyse syntaxique des fichiers qui ne correspondent pas à un patch sémantique. En effet, beaucoup de patchs sémantiques contiennent des mots-clés comme les noms des fonctions d'API qui doivent les assister pour correspondre et cela arrive peu souvent dans le noyau Linux. Coccinelle a initialement utilisé la commande Unix grep pour trouver les fichiers contenant ces mots-clés, mais avec des lenteurs, étant donné la grande taille de code.

Le moteur Coccinelle utilise alors grep, ou l'indexation de texte intégral et d'outil de recherche glimpse si cette option a été activée par l'utilisateur, pour identifier les fichiers qui contiennent au moins un de ces mots clefs.

Cette deuxième approche d'utiliser glimpse pour préparer un index d'avance et ensuite seulement traiter les fichiers indiqués par l'index. Comme l'index est plus petit que le code source du noyau et est organisé efficacement, l'utilisation de glimpse améliore considérablement la performance, particulièrement pour les patchs sémantiques qui impliquent des fonctions d'API du noyau. Néanmoins, glimpse était à l'origine seulement disponible librement aux utilisateurs universitaires, il a dû être manuellement installé et la création d'un index sur chaque mise à jour de noyau est chronophage. En 2010, Coccinelle a été complété par le support de id-utils, qui fait partie de nombreuses distributions Linux et pour lequel la création d'index est beaucoup plus rapide. En 2013, le support pour les utilisateurs qui n'ont pas d'index disponible a été réécrit pour essentiellement ré implémenter la commande grep dans OCaml, réduisant les appels de système et de mieux tenir compte des besoins spécifiques de Coccinelle.

## Impact sur Linux

### Augmentation des commits Coccinelle

Le sous-système le plus affecté est celui des drivers (pilotes), avec 57 882 lignes supprimées et 77 306 lignes rajoutées, suivies par les sous-systèmes arch, fs, net, sound, et include, qui sont tous affectés par des milliers de lignes supprimées ou rajoutées. La prédominance de drivers n'est pas surprenante, étant donné qu’ils composent 67 % du code source du noyau Linux 4.15. Le sous-système drivers a aussi été expérimenté par d'autres outils de découverte de bugs et de fiabilité de $code^,^,^,^,.$ Le taux de lignes changées par Coccinelle pour le sous-système drivers reste élevé, mais les résultats montrent l'applicabilité de Coccinelle à travers le noyau.

### Catégories d'utilisateurs

Différents types de développeurs contribuent au noyau Linux, en soumettant des patchs. Parmi ceux qui mentionnent Coccinelle dans leur historiques de commit, Lawall et coll. distinguent six catégories d'utilisateurs Coccinelle :

**Les développeurs Coccinelle**


    Ce sont les membres de l'équipe de développement Coccinelle et des personnes employées par l'équipe pour disséminer Coccinelle.

**Les stagiaires Outreachy**


    Le noyau Linux participe au programme de stage de Outreachy et les stagiaires peuvent utiliser Coccinelle dans le processus d'application ou le programme de stage.

**Utilisateur dédié**


    C'est un développeur qui utilise Coccinelle dans le noyau pour une petite collection de simples changements largement appropriés.

**0-day**


    C'est un service de test automatisé Intel qui construit et démarre le noyau Linux pour de multiples configurations de noyau, sur chaque commit pour les centaines d’arbres de git. Ce service de test dirige aussi un certain nombre d'outils d'analyse statiques, y compris Coccinelle, sur le résultat de chaque commit.

**Les mainteneurs de noyau**


    Ce sont les développeurs de noyau qui reçoivent et commit les patchs, et sont généralement responsables de quelques sous-systèmes. Lawall et coll. ont identifié les mainteneurs comme les développeurs qui sont nommés dans le fichier MAINTENERS de Linux 4.15 (1170 développeurs).

**Les autres contributeurs**


    Ces contributeurs peuvent être fréquents ou occasionnels.
