Suppongo che ci sia una storia, ma perché lo stack cresce verso il basso?
Mi sembra che gli overflow del buffer sarebbero molto più difficili da sfruttare se lo stack aumentasse ...
Suppongo che ci sia una storia, ma perché lo stack cresce verso il basso?
Mi sembra che gli overflow del buffer sarebbero molto più difficili da sfruttare se lo stack aumentasse ...
Risposte:
Io credo che proviene dai primissimi giorni di calcolo, quando la memoria era molto limitata, e non è stato saggio pre-allocare un grande pezzo di memoria per l'uso esclusivo dallo stack. Quindi, allocando la memoria heap dall'indirizzo zero verso l'alto e impilando la memoria dalla fine della memoria verso il basso, è possibile che sia l'heap sia lo stack condividano la stessa area di memoria.
Se avessi bisogno di un po 'più di heap, potresti stare attento all'utilizzo dello stack; se hai bisogno di più stack, puoi provare a liberare un po 'di memoria heap. Il risultato fu, ovviamente, soprattutto crash spettacolari, dato che lo stack occasionalmente sovrascriveva il mucchio e viceversa.
A quei tempi non c'erano interwebz, quindi non c'erano problemi di sfruttamento del buffer sovraccarico. (O almeno nella misura in cui esistesse l'interwebz, era tutto all'interno di strutture ad alta sicurezza del dipartimento della difesa degli Stati Uniti, quindi non è stato necessario riflettere molto sulla possibilità di dati dannosi.)
Dopodiché, con la maggior parte delle architetture si trattava solo di mantenere la compatibilità con le versioni precedenti della stessa architettura. Ecco perché le pile rovesciate sono ancora con noi oggi.
la memoria del programma è tradizionalmente impostata come
code
constants
heap (growing up)
...
stack (growing down)
heap e stack possono essere scambiati
ma gli overflow del buffer possono ancora essere sfruttati se lo stack è andato dall'altra parte
prendendo il classico strcpy
come esempio
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
con memoria stack come
ret foo
arg in
buff array
ret strcpy
buf pointer
in
ciò significherebbe che al termine della copia l'indirizzo di ritorno strcpy
è dopo il buffer (anziché l' foo
indirizzo di ritorno) e può essere sovrascritto da qualsiasi cosa si trovi inin
Alcuni hardware hanno l'heap che inizia a memoria alta, che cresce, mentre lo stack inizia a memoria bassa che cresce.
L'hardware HP PA-RISC, tra gli altri, lo fa: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
Il venerabile sistema operativo Multics funzionava su hardware che aveva (uno dei forse molti) stack in crescita: vedi http://www.acsac.org/2002/papers/classic-multics.pdf , fine della sezione 2.3.2:
In terzo luogo, le pile sui processori Multics sono cresciute nella direzione positiva, piuttosto che in quella negativa. Ciò significa che se si realizzasse effettivamente un overflow del buffer, si sovrascriverebbero i frame stack non utilizzati, anziché il proprio puntatore di ritorno, rendendo lo sfruttamento molto più difficile.
È un'affermazione piuttosto interessante. Gli overflow del buffer sono diventati un problema così grande solo a causa della disposizione "consueta" di procedure-call-stack-frame? Inoltre, quanta parte della reputazione di Multics come Totally Invulnerable era solo un colpo di fortuna nella progettazione hardware?