Zakładam, że jest to historia, ale dlaczego stos rośnie w dół?
Wydaje mi się, że przepełnienie bufora byłoby znacznie trudniejsze do wykorzystania, gdyby stos wzrósł w górę ...
Zakładam, że jest to historia, ale dlaczego stos rośnie w dół?
Wydaje mi się, że przepełnienie bufora byłoby znacznie trudniejsze do wykorzystania, gdyby stos wzrósł w górę ...
Odpowiedzi:
Wydaje mi się , że pochodzi on z bardzo wczesnych dni obliczeniowych, kiedy pamięć była bardzo ograniczona i nie było rozsądnie wstępnie przydzielać dużej części pamięci do wyłącznego użytku przez stos. Tak więc, przydzielając pamięć sterty od adresu zero w górę i stos pamięci od końca pamięci w dół, możesz mieć, że sterty i stos będą mieć ten sam obszar pamięci.
Jeśli potrzebujesz nieco więcej stosu, możesz być ostrożny z wykorzystaniem stosu; jeśli potrzebujesz więcej stosu, możesz spróbować zwolnić trochę pamięci sterty. Rezultatem były oczywiście głównie spektakularne awarie, ponieważ stos od czasu do czasu nadpisywał stos i odwrotnie.
W tamtych czasach nie było interwebzów, więc nie było problemu z wykorzystaniem przepełnienia bufora. (Lub przynajmniej w takim stopniu, w jakim istniał ten interwebz, wszystko znajdowało się w obiektach o wysokim bezpieczeństwie Departamentu Obrony Stanów Zjednoczonych, więc możliwość złośliwych danych nie musiała być zbytnio rozważana).
Następnie w przypadku większości architektur wszystko było kwestią utrzymania zgodności z poprzednimi wersjami tej samej architektury. Właśnie dlatego stosy do góry nogami są dziś z nami.
pamięć programu jest tradycyjnie konfigurowana jako
code
constants
heap (growing up)
...
stack (growing down)
stos i stos można wymieniać
ale przepełnienia bufora można nadal wykorzystać, jeśli stos pójdzie w drugą stronę
biorąc strcpy
za przykład klasykę
foo(char* in){
char[100] buff;
strcpy(buff,in);
}
z pamięcią stosu jako
ret foo
arg in
buff array
ret strcpy
buf pointer
in
oznaczałoby to, że po zakończeniu kopiowania adres zwrotny strcpy
znajduje się za buforem (zamiast foo
adresu zwrotnego) i może zostać zastąpiony przez to, co jest win
Niektóre urządzenia mają stertę zaczynającą się od dużej pamięci, która rośnie, podczas gdy stos zaczyna się od małej pamięci, która rośnie.
Sprzęt HP PA-RISC między innymi robi to: http://www.embeddedrelated.com/usenet/embedded/show/68749-1.php
Czcigodny system operacyjny Multics działał na sprzęcie, który dorastał (jeden z prawdopodobnie wielu): patrz http://www.acsac.org/2002/papers/classic-multics.pdf , koniec sekcji 2.3.2:
Po trzecie, stosy procesorów Multics rosły w kierunku dodatnim, a nie ujemnym. Oznaczało to, że jeśli rzeczywiście dokonałeś przepełnienia bufora, zastąpiłbyś nieużywane ramki stosu, a nie własny wskaźnik powrotu, co znacznie utrudnia wykorzystanie.
To dość interesujące stwierdzenie. Czy przepełnienie bufora stało się tak wielkim problemem tylko z powodu „zwyczajowego” ustawienia procedury-wywołania-stosu-ramki? A także, ile reputacji Multics jako Totally Invulnerable było tylko fartem projektowania sprzętu?