Le débordement qui ne plante pas
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 8 — Mémoire, fichiers et entrées-sorties
Énoncé
Comparer le sort de ces deux programmes.
/* (A) */ int* p = NULL;
*p = 1;
/* (B) */ int voisine = 1000;
int t[5] = {0, 0, 0, 0, 0};
for (int i = 0; i < 8; i = i + 1) { t[i] = i; }
printf("voisine = %d\n", voisine);Corrigé
(A) est tué par le système : code de sortie , soit le signal , SIGSEGV. L'adresse n'appartient à aucune plage du processus, le matériel intercepte, le système tue. Rien n'a été corrompu.
(B) compilé avec -fno-stack-protector affiche :
voisine = 6
t = 0 1 2 3 4
et se termine avec le code . Les tours ont écrit hors du tableau, dans une mémoire qui appartient bel et bien au processus : celle de voisine. La variable a changé de valeur sans qu'aucune ligne du programme ne la nomme. Le tableau, lui, est intact — le programme peut donc être faux ailleurs qu'à l'endroit de la faute.
Le classement est contre-intuitif, et c'est le point de l'exercice :
| Ce qui arrive | Gravité | |
|---|---|---|
| (A) hors du processus | mort immédiate, signal 11 | le bon cas |
| (B) hors tableau, dans le processus | une autre variable change | le mauvais |
Une nuance mesurée. Compilé sans -fno-stack-protector, c'est-à-dire par défaut sur la plupart des systèmes actuels, le même programme (B) se termine par le code , SIGABRT : le compilateur avait glissé une valeur témoin — un canari — entre les variables locales et l'adresse de retour, et il a constaté à la sortie de la fonction qu'elle avait changé. Cette protection ne couvre que le débordement vers le haut d'un tableau local ; elle n'a rien vu, et ne peut rien voir, du même débordement sur un bloc du tas. Elle réduit la surface d'attaque, elle ne rend pas le programme correct.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.