Fuzzer Python

Suite à ma conférence sur l'assurance qualité et fuzzing aux RMLL, je me suis remis à jouer avec mon fuzzer Fusil. Dans le TGV retour, 8h quand même pour rentrer à Strasbourg, j'ai écrit un fuzzer pour le langage Python. L'idée est de récupérer la liste des fonctions, classes et méthodes d'une module, et les appeler/instancier avec un nombre d'arguments aléatoires de type aléatoire. Comme je m'y attendais, une fois le fuzzer python écrit, CPython 2.5 a rapidement planté : erreur de segmentation dans le module imageop.

Rapports de bugs Python 2.6

Pour écrire un rapport de bug correct, j'ai reproduit les bugs avec la version trunk (futur CPython 2.6) compilée avec l'option pydebug et... mince, ça plante plus : le bug imageop est déjà corrigé. J'ai donc amélioré le fuzzer pour qu'il ne teste non plus uniquement un seul module, mais toute une liste de modules (j'ai noté ceux écrits en langage C), et j'ai rajouté d'autres types d'argument (nombre flottant, objet, unicode, etc.). Voilà CPython qui plante, ouf, l'honneur du fuzzing est sauf :-) J'ai alors rapporté une quinzaine de bugs (cherchez les bugs rapportés entre le 6 et le 9 juillet), à chaque fois accompagné d'un patch et d'un exemple pour reproduire le crash. Deux patchs sont déjà appliqués.

Publication de Fusil 0.9

Pour fêter ce succès, j'ai publié la version 0.9 de Fusil. Cette nouvelle version contient le nouveau fuzzer pour Python, peut s'exécuter dans l'interprète Python PyPy, gère mieux le logging (sortie plus concise mais contient le nombre de crash et un fichier project.log est conservé dans le dossier du projet), et l'outil IncrMangle est plus rapide et précis.

Fuzzing de PyPy

Enfin, j'ai fuzzé un peu PyPy, mais le seul vrai bug que j'ai trouvé est dans un module que j'ai écrit (module pwd écrit avec ctypes) ! Par contre, Carl (cfbolz sur le salon IRC #pypy du serveur Freenode) a trouvé d'autres bugs dans PyPy en utilisant Fusil.

Classement des interprètes Python

Pour résumer, vu les résultats face aux tests de fuzzing, on peut classer la qualité des interprètes Python comme ceci : CPython 2.5 < CPython trunk << PyPy où << veut dire très supérieur. Effectivement, je n'ai trouvé qu'un seul bug PyPy après une nuit de fuzzing contre une quinzaine dans CPython rapidement détectés.