Quoi, le double-free avec la stack trace et tout, ça ne déclenche pas de crash + core-dump?
Hé bien, j'en ai encore beaucoup à apprendre sur *n*x...
Version imprimable
Quoi, le double-free avec la stack trace et tout, ça ne déclenche pas de crash + core-dump?
Hé bien, j'en ai encore beaucoup à apprendre sur *n*x...
Si si, aussi bien crash qu'exécution de code (vu sous Windows et Linux). Le "double-free" porte le numéro CWE-415:
http://cwe.mitre.org/data/definitions/415.html
L'exécution de code est difficile (voir impossible dans certains cas) mais sous certaines conditions spécifiques la fiabilité d'exécution de code est de 100% pour ce type de vulnérabilité. Cependant, dans certains cas, la vulnérabilité peut être complétement silencieuse (pas de crash et encore moins d'exécution).
En fait le résultat est très dépendant de l'état du tas (heap) pendant et après le double-free et aussi des protections systèmes mise en place (heap chunk cheksumming ou encore heap canary par exemple).
Non, je parlais de ce qui se passait quand un double-free était détecté par la glibc, pas des vulnérabilités qu'ils causent...
On est bien d'accord que ce n'est absolument pas sécure mais pour l'avoir déjà vu plusieurs fois dans des codes (aussi bien sous windows que sous linux), le double free ne fais pas planter l'application.
Là ou j'ai du mal, c'est de savoir si je dois imiter le système lors d'un double free ou si ma solution (qui ne fais rien lors d'un double free) est à conserver.
J'ai un peu peur des performences à vrai dire (déjà qu'en ce moment pour lancer firefox ou gimp il me faut 10min :$)
La norme dit que le comportement dans le cas d'un double free() est non défini et non pas défini par l'implémentation. C'est donc clairement une erreur dont le résultat est imprévisible.
Le programmeur ne devant pas faire de double free(), tu n'as pas d'obligation à préciser ce que ton code fait dans ce cas.
Tu peux choisir ou plus précisément ne pas te préoccuper de ce qui se passe dans cette situation.
C'est un comportement indéfini :
et donc une erreur. A partir de ce moment là tout peut arriver : un plantage pur et simple, un code qui semble marcher jusqu'au jour où ... (et en général, ça arrive au plus mauvais moment), etc.Citation:
or if the space has been deallocated by a call to free or realloc,
the behavior is undefined
Vu de la norme, free() n'a pas l'obligation d'afficher un message dans ce cas là, et d'ailleurs n'en affiche pas dans la plupart des implémentations (au passage, d'ailleurs, la glibc l'affiche systématiquement ou seulement en debug ?).
@sloshy: je viens de tester, un double-free, quand il est détecté par la libc, cause bien un abort du programme (Mandriva Linux, gcc 4.3.2)
Et la sortie:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <stdio.h> #include <stdlib.h> int main(void) { void *toto = malloc(10); void *tata = malloc(10); /*J'en alloue un second pour éviter les considérations de pages*/ puts("Avant"); free(toto); puts("Entre"); free(toto); //double free puts("Après"); free(tata); return EXIT_SUCCESS; }
(au passage, si quelqu'un pouvait me dire comment avoir la stack trace plutôt que juste "Abandon", ce serait sympa).Code:
1
2
3
4
5
6 [medinoc@localhost C]$ gcc -g testDoubleFree.c [medinoc@localhost C]$ ./a.out Avant Entre Abandon [medinoc@localhost C]$
tu peux la récupérer en faisant un debug post mortem avec gdb, pour cela il faut autoriser la génération des fichiers core.
avec <un numero> le numero du fichier core.Code:
1
2
3
4
5
6
7 $ulimit -c unlimited $./a.out ... Abandon (core dump) <-- Ici un fichier core est generé $gdb a.out core.<un numero> bt
lors de mes tests, je n'ai pas eu ce genre de soucis. (dernière version de gcc je tourne sous openBSD).