Wird ein Stapelüberlauf von Hardware oder Software erkannt?


26

Ist es die Aufgabe der Software (des Betriebssystems), Stapelüberläufe zu erkennen, oder wird ein Stapelüberlauf in der Hardware festgestellt, der eine Ausnahme in der CPU verursacht?


Ich würde sagen, Hardware durch MMU-Fehler auf den meisten CPUs. x86 im 32-Bit-Modus hatte zusätzlich zum Paging eine Segmentierung, und das "Stapelsegment" ist wie die Segmente Code, Data, Ext ... sowohl mit einer Basisadresse als auch mit einer Größe verknüpft. Jeder Zugriff außerhalb dieses Bereichs würde einen Fehler auslösen.
TEMLIB

Antworten:


25

Es kann sich um Software, Hardware oder beides handeln.

Es gibt zwei Arten von Überläufen: Überlauf beim Erweitern des Stapels (beim Eingeben einer Funktion) und Überlauf beim Zugriff auf ein Array im Stapel. Überläufe beim Wachsen des Stapels können erkannt werden, indem die Funktionseingabe einer Begrenzungsüberprüfung unterzogen wird, um sicherzustellen, dass genügend Platz vorhanden ist (und entweder einen Fehler anzuzeigen oder den Stapel zu vergrößern, wenn dies nicht der Fall ist). Überläufe beim Zugriff auf ein Array auf dem Stapel sind nur in einfachen Sprachen ein Problem, bei denen die Array-Grenzen nicht überprüft werden. Die Lösung besteht darin, die Array-Grenzen zu überprüfen.

Diese Softwareansätze haben den Vorteil, dass sie absolut zuverlässig funktionieren: Sie können sicher sein, dass ein Stapelüberlauf erkannt wird. Ihr Nachteil ist, dass sie die Codegröße und die Ausführungszeit erhöhen. Hardware kann dabei helfen, indem eine Methode bereitgestellt wird, mit der die meisten Überläufe kostenlos erkannt werden, solange kein Überlauf auftritt. Bei einer Architektur mit einer MMU ¹ kann die Laufzeitumgebung den Stapel auf eine Seitengrenze abbilden, wobei die nächste Seite nicht zugeordnet wird.

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

Auf diese Weise verursacht die Software einen Fehler, wenn sie versucht, auf Daten über die Seitengrenze hinaus zuzugreifen (unabhängig davon, ob der Stapelzeiger über die Grenze hinaus verschoben wurde oder der Arrayzugriff außerhalb der Grenzen und außerhalb der Grenze liegt), indem sie auf einen nicht zugeordneten Bereich zugreift . Dies geschieht nur, wenn der Überlauf klein genug ist: Wenn der Überlauf zu groß ist, greift das Programm möglicherweise auf andere Elemente auf der anderen Seite der Lücke im Adressraum zu.

Die Nachteile des Hardware-Ansatzes bestehen darin, dass er nicht vollständig zuverlässig ist, da ein Überlauf durch eine große Menge möglicherweise nicht erkannt wird, und dass er keine Array-Überläufe erkennt, die im adressierbaren Bereich verbleiben.

Um Array-Überläufe zu erkennen, ist eine andere Softwaretechnik ein Kanarienvogel : Setzen Sie einen speziellen Wert oben auf den Stapel oder zwischen Frames und überprüfen Sie, ob sich der Kanarienwert bei der Funktionsrückgabe nicht geändert hat. Dies ist auch eine unvollständige Technik, da der Überlauf den Kanarienvogel möglicherweise vollständig meidet oder nicht erkannt wird, da der Kanarienwert zum Zeitpunkt der Überprüfung wiederhergestellt wurde. Es ist jedoch hilfreich, die Ausnutzung einiger Sicherheitslücken zu erschweren.

Die sicherste und kostengünstigste Möglichkeit, Stapelüberläufe zu vermeiden, besteht darin, die Stapelmenge zu berechnen, die das Programm benötigt, bevor es mit der Ausführung beginnt, und zwar durch statische Analyse. Dies ist jedoch nicht immer praktisch: Die von einem Programm benötigte Stapelmenge ist im Allgemeinen nicht bestimmbar und hängt von den Daten ab, die vom Programm bearbeitet werden.

¹ Das gleiche Prinzip kann auch mit nur einer MPU oder ohne Speicherschutz angewendet werden, wenn ein einzelner Thread vorhanden ist, dessen Stapel sich am Rand der vorhandenen physischen Zuordnungen befindet.


4
Ich würde den Array-Zugriff außerhalb der Grenzen nicht als Stapelüberlauf bezeichnen, selbst wenn sich das Array auf dem Stapel befindet. Es ist nur ein Sonderfall eines Pufferüberlaufs.
CodesInChaos

Wenn die primären Stapelelemente, auf die in Bezug auf einen Nicht-Stapel- / Rahmenzeiger oder einen nicht konstanten Versatz verwiesen wird, nicht zugewiesen werden, werden herkömmliche Stapelüberläufe vermieden. Die Verwendung eines separaten Rücksendeadressenstapels (oder RA / Register-Spill-Stacks wie Itanium) würde die Möglichkeiten der rücksendungsorientierten Programmierung zumindest erheblich reduzieren.
Paul A. Clayton

Out-of-Bound-Zugriff wird eher als Überlauf , nicht als Überlauf bezeichnet.
Ben Voigt

3
@ awesomebing1 Nicht jede Plattform erkennt Stapelüberläufe. Möglicherweise überschreiben Sie nur das, was sich hinter dem Stapel befindet (ähnlich wie bei jedem anderen Pufferüberlauf).
user253751

1
@CodesInChaos, manchmal werden Pufferüberläufe in gestapelten Puffern als "Stapelüberläufe" (kurz "stack overflows") bezeichnet. Zugegeben, diese Terminologie kann ohne Kontext etwas verwirrend sein.
DW
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.