Adloun

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 arriveGravité
(A) hors du processusmort immédiate, signal 11le bon cas
(B) hors tableau, dans le processusune autre variable changele 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.