
STACK OVERFLOW: Wir hören das technische Wort manchmal, wenn z.B. Sicherheitsschwachstellen entdeckt und diese beschrieben werden.
Aber was ist ein Stack Overflow und was kann es verursachen?
Nehmen wir an, sie experimentieren auf einem Arduino-Board und wollen, dass das Board-LED (PIN13) zufällig blinkt. Sie schreiben dafür eine Routine (Code) innerhalb einer Funktion namens blink();
Weil sie nicht wollen, dass das Blinken nach einem einzigen Programmdurchlauf wieder aufhört, bauen sie eine sogenannte Rekursion ein, in dem sie die Funktion in sich selbst aufrufen.
Damit das ganze läuft, setzen sie die Funktion zum Schluss noch in die Built-In Funktion loop() des Boards. Was wir an dieser Stelle ggf. nicht wissen ist, dass diese Funktion nicht einmalig durchlaufen wird, sondern eine systemseitige Endlosschleife ist, die für wiederkehrende Tasks genutzt wird.
Ein rekursiver Aufruf unserer blink-Funktion in einer Endlosschleife würde den Stack (Stapelspeicher) schnell zum Überlauf bringen, da der Adressraum nicht unendlich ist und die verursachten „Schleifen in den Schleifen“ den begrenzten Funktionsstapel exponentiell belegen würden, was zu einem Programm- oder System-Crash führen kann.

Stack Overflow-Schwächen – Ein grosses Sicherheitsrisiko
Manchmal werden solche Fehler auch dazu genutzt, schädlichen Code ausserhalb des Programmspeichers auszuführen. Im Vergleich zu Puffer-Überläufen (Buffer Overflows) sind Stack Overflows nicht weniger bedrohlich, was Code Ausführungen betrifft, da der Stapel (Stack) die Rücksprungadressen für alle aktiven Funktionsaufrufe enthält.
Wenn ein Angreifer den Stapel überschreibt, kann er auch die Rücksprungadressen manipulieren. Dies bedeutet, dass er die Programmausführung in beliebige Speicherbereiche leiten kann, was die Ausführung von bösartigem Code ermöglichen kann.
Ein Beispiel einer möglichen Crash-Sequenz im Arduino Code, die zu einem Stack Overflow führen kann:
// Definiere LED pin
const int ledPin = 13; // Standard Arduino LED PIN
void setup() {
// Initialisiere LED pin als output
pinMode(ledPin, OUTPUT);
// Setzt den Zufallszahlengenerator mit der aktuellen Zeit
randomSeed(millis());
}
void blink() {
// Setze LED auf ON
digitalWrite(ledPin, HIGH);
// Zufällige Verzögerung zwischen 100ms und 500ms
delay(random(100, 500));
// Setze LED auf OFF
digitalWrite(ledPin, LOW);
//Weitere zufällige Verzögerung
delay(random(100, 500));
blink(); // <-- Rekursiver Aufruf der Funktion
}
void loop() //Built-In Funktion einer Endlosschleife
{
blink(); // Start des rekursiven Aufrufs, somit der Schleife im LOOP
}
In eines der nächsten Beiträge wird es darum gehen, wie wir solche einfachen Fehler mit ggf. grösseren Auswirkungen vermeiden können und wie wir heute von solchen Bedrohungen i.d.R. durch das Betriebssystem geschützt werden.