Question à propos de la pile d'appel...

Résolu
yoman64 Messages postés 962 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 2 août 2010 - 2 sept. 2008 à 06:05
cs_max12 Messages postés 1491 Date d'inscription dimanche 19 novembre 2000 Statut Modérateur Dernière intervention 7 juillet 2014 - 2 sept. 2008 à 22:56
Bonjour à tous,


N'étant pas expert en C, ma question va peut être sembler stupide, mais
j'aimerais bien trouvé un expert(ou n'importe qui ayant la réponse ) pour y répondre


Alors voilà, je développe présentement un patch pour protéger la pile
d'appel du moteur PHP. Étant administrateur de plusieurs serveurs
FreeBSD/Linux utilisant le php, un appel récursif sans fin provoque
rapidement une faute de segmentation ce qui pourrait facilement mettre
hors service un serveur (attaque DoS).


Enfin bref, après plusieurs expérimentations afin de voir la taille de
la pile dépendait de quoi, j'en suis venu aux résultats suivants:

Linux:

Un programme un C cause une faute de segmentation après 392 952 récursion

PHP plante après 39 354 récursions.

FreeBSD:

C plante après 8 388 133 récursions

PHP après plus de 390 000 récursions

Windows 2003:

Un programme C compilé avec gcc(mingsw) plante après 130 000 récursions

Un programme C compilé avec VS6 ne plante jamais, en redirigeant la sortie vers un fichier le fichier grossis sans arrêt, j'ai stoppé ça à 8Go.

Php plante après environ 50 000 récursions.

Windows Vista:

Un programme compilé avec VS 2008 ne plante jamais.


Tout avais été compilé en mode release.


Les codes utilisés:

Code C: http://pastebin.com/m6ac4c8c9Code C (VS2008): http://pastebin.com/m1728e74d

Script PHP: http://pastebin.com/m491281a0
Bref ma question est:
La pile d'appels (stack call) dépend de quoi ? J'ai toujours cru
que c'était dépendant du système d'exploitation, mais visiblement ce
n'est pas le cas. Pourquoi sous windows avec un compilateur de chez
microsoft ça ne s'arrête jamais ? Passé 10 milliards ça continue...


J'espère voir un expert (brunews ?) passer par là avec des explications concrètes


Merci de votre aide.

-------------------
Vous cherchez un hebergement Php/MySQL Gratuit et sans publicités ??
Et bien c'est la : www.e3b.org  

6 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 sept. 2008 à 11:56
Windows only:
La taille de la pile dépend de l'option de compilation, 1 Mo par défaut. Cette zone mémoire est allouée et réservée par le loader system. La pile est gérée par un pointeur d'adresse, ESP en 32 bits et RSP en x64. Ce pointeur recule d'autant d'octets qu'on empile de params, sur 32 bits sera de 4 minimum hors param pour empiler l'adresse de retour (sera dépilé dans le registre EIP).

Il est donc très clair qu'une fonction récursive présente un danger pour la stack, à bannir en prod.

ciao...
BruNews, MVP VC++
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 sept. 2008 à 21:20
Pas besoin de debug, suffit de régler (clic droit sur le projet > options) "fichiers de sortie" sur "listing asm et source" et de compiler en RELEASE. En mode debug on n'a jamais la garantie d'avoir le meme code produit, d'ailleurs très rarement.

ciao...
BruNews, MVP VC++
3
cs_max12 Messages postés 1491 Date d'inscription dimanche 19 novembre 2000 Statut Modérateur Dernière intervention 7 juillet 2014
2 sept. 2008 à 18:39
Merci pour les explications BruNews (en fait je suis en partie derrière cette question, ayant participé au test). Mais je ne comprend pas pourquoi avec la version VC6 l'explosion attendu ne finit jamais par arriver, le stack ne peux quand même pas avoir une taille infinie ?

http://vbaddons.free.fr
&
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 sept. 2008 à 21:00
Certes non, une stack a par force une taille fixée.
Il est impossible d'émettre le moindre avis sans analyse du code et surtout il faut regarder le listing ASM du compilo pour comprendre ce qui est réellement fait. Il se peut fort bien que le compilo ait remplacé la récursivité par un JMP dans la fonction (un vilain goto) si l'algo est simple.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yoman64 Messages postés 962 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 2 août 2010 2
2 sept. 2008 à 21:09
Hello,

Merci beaucoup pour ces explications très intéressantes. J'allais poser la même question que max12, mais puisque le code est très simple ( http://pastebin.com/m6ac4c8c9 ) il est fort probable que ta deuxième explication soit bonne (je vais laisser à max12 le soin de vérifier, je suis pas trop au courant des débuggeur sous windows).

Merci et a+

-------------------
Vous cherchez un hebergement Php/MySQL Gratuit et sans publicités ??
Et bien c'est la : www.e3b.org  
0
cs_max12 Messages postés 1491 Date d'inscription dimanche 19 novembre 2000 Statut Modérateur Dernière intervention 7 juillet 2014
2 sept. 2008 à 22:56
Encore merci, on n'avait pas pensé à l'assembly (la je me sens con rare).

00AA1000  inc         dword ptr [eax]
    a(i);
00AA1002  jmp         a (0AA1000h)

Une possibilité que je ne croyait pas possible de la part du compilateur

Enfin bref, merci de nous avoir permis de dormir moins idiots ce soir

http://laptopgun.blogspot.com/
&
0
Rejoignez-nous