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?
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?
Odpowiedzi:
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.