Je suppose qu'il y a une histoire, mais pourquoi la pile se développe-t-elle vers le bas?
Il me semble que les dépassements de tampon seraient beaucoup plus difficiles à exploiter si la pile augmentait ...
Je suppose qu'il y a une histoire, mais pourquoi la pile se développe-t-elle vers le bas?
Il me semble que les dépassements de tampon seraient beaucoup plus difficiles à exploiter si la pile augmentait ...
Réponses:
Je crois cela vient des tout premiers jours de l'informatique, lorsque la mémoire était très limitée, et il n'était pas judicieux de pré-allouer un gros morceau de mémoire à l'usage exclusif de la pile. Ainsi, en allouant de la mémoire de tas à partir de l'adresse zéro vers le haut et en empilant de la mémoire de la fin de la mémoire vers le bas, vous pouvez avoir le tas et la pile partager la même zone de mémoire.
Si vous aviez besoin d'un peu plus de tas, vous pourriez être prudent avec l'utilisation de votre pile; si vous aviez besoin de plus de pile, vous pouvez essayer de libérer de la mémoire. Le résultat a été, bien sûr, surtout, des plantages spectaculaires, car la pile écrasait parfois le tas et vice versa.
À l'époque, il n'y avait pas d'interwebz, il n'y avait donc pas de problème d'exploitation de dépassement de tampon. (Ou du moins dans la mesure où les interwebz existaient, ils se trouvaient tous dans des installations de haute sécurité du département de la défense des États-Unis, de sorte que la possibilité de données malveillantes n'avait pas besoin d'être beaucoup réfléchie.)
Après cela, avec la plupart des architectures, il s'agissait de maintenir la compatibilité avec les versions précédentes de la même architecture. C'est pourquoi des piles à l'envers sont toujours avec nous aujourd'hui.
la mémoire du programme est traditionnellement
code
constants
heap (growing up)
...
stack (growing down)
le tas et la pile peuvent être échangés
mais les dépassements de tampon peuvent toujours être exploités si la pile va dans l'autre sens
prendre le classique strcpy
comme exemple
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
avec la mémoire de pile comme
ret foo
arg in
buff array
ret strcpy
buf pointer
in
cela signifierait que lorsque la copie est effectuée, l'adresse de retour de se strcpy
trouve après le tampon (au lieu de foo
l'adresse de retour de) et peut être remplacée par ce qui se trouve dansin
Certains matériels ont le tas commençant à une mémoire élevée, augmentant vers le bas, tandis que la pile commence à une mémoire faible augmentant.
Le matériel PA-RISC de HP, entre autres, le fait: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
Le vénérable système d'exploitation Multics fonctionnait sur du matériel qui avait (peut-être plusieurs) des piles grandissant: voir http://www.acsac.org/2002/papers/classic-multics.pdf , fin de la section 2.3.2:
Troisièmement, les piles sur les processeurs Multics ont augmenté dans le sens positif plutôt que dans le sens négatif. Cela signifiait que si vous accomplissiez réellement un débordement de tampon, vous écraseriez les trames de pile inutilisées, plutôt que votre propre pointeur de retour, ce qui rend l'exploitation beaucoup plus difficile.
C'est une déclaration assez intéressante. Les débordements de mémoire tampon sont-ils devenus un problème si énorme uniquement en raison de l'arrangement "habituel" procédure-appel-pile-cadre? De plus, dans quelle mesure la réputation de Multics comme totalement invulnérable n'était-elle qu'un coup de chance dans la conception matérielle?