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?
computer-architecture
stacks
gilianzz
quelle
quelle
Antworten:
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.
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.
quelle