Czy sprzęt lub oprogramowanie wykrywa przepełnienie stosu?


26

Czy zadaniem oprogramowania (systemu operacyjnego) jest wykrywanie przepełnienia stosu, czy też przepełnienie stosu jest wykrywane sprzętowo, powodując wyjątek w procesorze?


Powiedziałbym, że sprzęt, przez awarie MMU na większości procesorów. x86 w trybie 32-bitowym oprócz stronicowania miał segmentację, a „segment segmentu” jest powiązany, podobnie jak segmenty kodu, danych, rozszerzenia ... zarówno z adresem podstawowym, jak i rozmiarem. Każdy dostęp poza tym zakresem spowodowałby błąd.
TEMLIB

Odpowiedzi:


25

Może to być oprogramowanie, sprzęt lub oba, albo żaden.

Istnieją dwa rodzaje przepełnień: przepełnienie podczas powiększania stosu (podczas wchodzenia do funkcji) i przepełnienie podczas uzyskiwania dostępu do tablicy na stosie. Przepełnienia podczas powiększania stosu można wykryć, sprawdzając ograniczenia wejścia funkcji, aby sprawdzić, czy jest wystarczająco dużo miejsca (i albo zasygnalizować błąd, albo zwiększyć stos, jeśli nie ma). Przepełnienia podczas uzyskiwania dostępu do tablicy na stosie stanowią problem tylko w językach niskiego poziomu, które nie weryfikują granic tablic; rozwiązaniem jest sprawdzenie granic tablic.

Zalety tego podejścia programowego polegają na tym, że działają w pełni niezawodnie: możesz być pewien, że zostanie wykryte przepełnienie stosu. Ich wadą jest to, że zwiększają rozmiar kodu i czas wykonywania. Sprzęt może pomóc, zapewniając metodę wykrywania większości przepełnień bez żadnych kosztów, o ile nie nastąpi przepełnienie. W architekturze z MMU ¹ środowisko wykonawcze może zorganizować mapowanie stosu na granicy strony, przy czym następna strona pozostaje niezmapowana.

+---------------+---------------+---------------+---------------+
| stack                         | unmapped      | other stuff   |
|    ----> direction of growth  |               |               |
+---------------+---------------+---------------+---------------+
^               ^               ^               ^               ^  page boundaries

W ten sposób, jeśli oprogramowanie spróbuje uzyskać dostęp do danych poza granicę strony (niezależnie od tego, czy wskaźnik stosu przesunął się poza granicę, czy też dlatego, że dostęp do tablicy jest poza granicami i poza granicą), spowoduje to błąd, uzyskując dostęp do niezapisanego obszaru . Dzieje się tak tylko wtedy, gdy przepełnienie jest wystarczająco małe: jeśli ilość przepełnienia jest zbyt duża, program może uzyskać dostęp do innych rzeczy po drugiej stronie przerwy w przestrzeni adresowej.

Wady podejścia sprzętowego polegają na tym, że nie jest ono w pełni niezawodne, ponieważ przepełnienie dużej ilości może nie zostać wykryte i że nie wykrywa przepełnień tablicy, które pozostają w przestrzeni adresowalnej.

Aby wykryć przepełnienie tablicy, inną techniką oprogramowania jest kanarek : umieść specjalną wartość na górze stosu lub między ramkami i sprawdź, czy wartość kanarka nie zmieniła się po powrocie funkcji. Jest to również technika niedoskonała, ponieważ przelew może całkowicie uniknąć kanarka lub może nie zostać wykryty, ponieważ wartość kanarka została przywrócona do czasu sprawdzenia. Niemniej jednak warto utrudnić wykorzystanie niektórych luk w zabezpieczeniach.

Najbezpieczniejszym i najtańszym sposobem uniknięcia przepełnienia stosu jest obliczenie ilości stosu, którego program będzie potrzebował przed rozpoczęciem jego wykonywania, za pomocą analizy statycznej. Jednak nie zawsze jest to praktyczne: ilość stosu wymagana przez program jest w ogóle nierozstrzygalna i zależy od danych, którymi manipuluje program.

¹ Tę samą zasadę można również zastosować tylko z jednostką MPU lub bez ochrony pamięci, jeśli istnieje jeden wątek, którego stos znajduje się na krawędzi istniejących mapowań fizycznych.


4
Nie wywołałbym dostępu do tablicy poza granicami przepełnienia stosu, nawet jeśli tablica jest na stosie. To tylko specjalny przypadek przepełnienia bufora.
CodesInChaos

Nieprzydzielenie do podstawowych elementów stosu, do których istnieją odniesienia w stosunku do wskaźnika stosu / ramki lub niestałego przesunięcia, pozwoliłoby uniknąć przepełnienia stosu. Użycie osobnego stosu adresów zwrotnych (lub stosu rozlewania RA / rejestru, takiego jak Itanium) co najmniej znacznie ograniczy możliwości programowania zorientowanego na zwrot.
Paul A. Clayton

Dostęp poza granicami jest bardziej poprawnie nazywany przekroczeniem , a nie przepełnieniem.
Ben Voigt

3
@ awesomebing1 nie każda platforma wykrywa przepełnienie stosu. Możesz po prostu zastąpić wszystko, co następuje po stosie (podobnie jak w przypadku innych przepełnień bufora).
user253751,

1
@CodesInChaos, czasami przepełnienie bufora w buforach przydzielonych do stosu nazywane jest „przepełnieniem stosu” (w skrócie). To prawda, że ​​ta terminologia może być nieco myląca bez kontekstu.
DW
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.