Suite de mon initiation au fuzzing. J'ai continué des tests pour trouver toujours plus de bug. J'avais lu par-ci par-là que les programmes ont de très nombreux points d'entrée, pas uniquement le clavier et la souris. J'avais testé les fichiers, j'ai alors testé les variables d'environnement. J'ai d'abord écrit un script bash utilisant strace (puis ltrace) pour traquer les appels à getenv() (entre autres). À partir de la liste des variables, j'en tenté de faire planter les programmes en passant des valeurs invalides (grand nombre, très longue chaîne, etc.). Le premier programme à planter était dpkg avec « COLUMNS=10000000 dpkg -l ».

J'ai mis une bonne grosse semaine à isoler le bug. J'ai compris que le bug venait de vfprintf() mais je n'ai pas compris dans quel cas on pouvait le reproduire. J'ai isolé la chaîne de formatage : on peut alors reproduire le bug avec la fonction printf de bash ou /usr/bin/printf : « printf "%-1.25000000s" "Hello" ». En creusant encore plus, jusqu'à l'assembleur (on peut pas creuser plus profond :-)), j'ai isolé la ligne C qui posait problème. C'était un appel à mbstowcs() utilisant un tampon local de la forme « wchar_t ignore[prec]; », or prec vaut 25000000. En clair : la glibc tente d'allouer 25 Mo dans la pile alors qu'elle fait que 8 Mo et que Linux ne sait pas la faire grossir automatiquement (honte à lui). Je pensais justement que c'était un appel à alloca() mais je faisais fausse route. Conclusion : utilisez la pile avec parcimonie. Évitez absoluement la fonction alloca() et la notation C « type var[taille]; » où taille est supérieur de 4096 ou une variable contrôlable directement ou indirectement par l'utilisateur.

J'ai rapporté le bug et il a été corrigé en 48h par Ulrich Drepper (mainteneur de la libc). Encore une belle preuve de la réactivité des développeurs de logiciel libre.