Technical | 2020-10-19

Warum 12 + 7 = 3 ergibt?

Eine seltsame Realität

Ariane 5, Boeing’s 787 Dreamliner und eine 105-jährige Dame aus Schweden, die in die Vorschule gehen sollte. All diese Ereignisse haben eines gemeinsam – sie wurden durch Softwarefehler hervorgerufen. Wie die Zahl 2,147,483,647 (zwei Milliarden einhundertsiebenundvierzig Millionen vierhundertdreiundachtzigtausend sechshundertsiebenundvierzig) mit diesen historischen Zwischenfällen in Verbindung steht, werden wir euch heute zeigen.

Wie Overflows entstehen

Eine Softwarelösung arbeitet grundsätzlich mithilfe von Variablen. Diese Variablen können unterschiedliche Typen haben, wie beispielsweise Zeichen oder Zahlen. Natürlich haben wir alle irgendwann schon einmal davon gehört, dass ein Computer mit Nullen und Einsen arbeitet, welche Bits genannten werden. Definiert man eine Variable, so wird diese in der Regel auf eine bestimmte Anzahl von Bits beschränkt. Nehmen wir an, dass wir eine Variable deklarieren die eine natürliche Zahl mit 4 Bits beinhaltet. Nun können wir die Zahlen von 0 bis 15 darstellen:

Werte einer 4 Bit Zahl

Was passiert also wenn wir eine Addition durchführen möchte, die nicht mehr mit 4 Bits darstellbar ist? Beispielsweise wenn man 12 + 7 mit 4-Bit-Variablen berechnet: Das überraschende Resultat ist 3 und nicht 19, da 19 nicht mehr mit einer 4-Bit-Variable dargestellt werden kann. Um das korrekte Ergebnis ausdrücken zu können würde man ein zusätzliches Bit benötigen, sprich 5 anstelle von 4 Bits.

Additionsüberlauf

Somit tritt ein sogenannter Überlauf auf, wenn man versucht eine Zahl in einer Variable zu speichern die nicht in den Wertebereich dieser Variable passt. Dabei ist diese größer, als die maximale Zahl, die genau diese Variable darstellen kann. Typischerweise tritt dies bei der Durchführung von arithmetischen Operationen auf und wird in der Fachsprache als “Overflow” bezeichnet. Viele Softwareanwendungen verwenden 32-Bit-Variablen, mit denen Zahlen im Wertebereich von -2,147,483,648 bis +2,147,483,647 dargestellt werden können. Entwickler gehen oftmals davon aus, dass rund 2 Milliarden positive Zahlen durchaus reichen und übersehen es, dass es im Laufe der Zeit zu einem Überlauf kommen kann. In diesem Fall tritt genauso wie in unserem demonstrativen Beispiel ein Overflow auf. Handelt es sich dabei um einen Ganzzahligen Datentyp spricht man von einem “Integer Overflow”. Overflows sind oftmals die Ursache für Sicherheitslücken. Die nachfolgenden Beispiele zeigen, welche unerwarteten und verheerenden Folgen Overflow-Fehler mit sich bringen können.

Nicht wenige Overflows haben es in die Geschichtsbücher geschafft. Die drei krassesten haben wir für euch herausgesucht:

Der Inbegriff eines Softwarebugs dieser Art ist wohl am besten anhand des Raketenstarts der Ariane 5 zeigbar. Am 4. Juni 1996 sollte sich die unbemannte Rakete der European Space Agency (ESA) auf den Weg in den Orbit machen. Mit an Bord waren vier hochkomplexe Satelliten, welche in die Erdumlaufbahn gebracht werden sollten. Nach lediglich 39 Sekunden endete jedoch der Flug in einem Desaster: Die Rakete löste sich in einem Ball aus Feuer und Rauch auf.

Ermittlungen des Vorfalls haben gezeigt, dass es sich bei dem Absturz nicht um einen mechanischen Fehler handelte. Die Hauptursache dafür war ein Softwarebug, der durch statische Analysen und Unit-Tests leicht auffindbar gewesen wäre.

Die Ariane 5 wurde seitens der ESA mit der identen Software des vorherigen Raketenmodells, der Ariane 4, ausgestattet. Da die neue Trägerrakete wesentlich höhere Geschwindigkeiten erreicht als das Vorgängermodell, hat das System bei der Überschreitung eines Grenzwertes eine Selbstzerstörungssequenz eingeleitet. Explizit hat es sich hierbei um die Seitwärts-Geschwindigkeit gehandelt, welche überschritten wurde. Der daraus resultierende Schaden betrug $ 500 Millionen.

Ein weiteres berühmtes Beispiel wie ein trivialer “Integer Overflow” nicht nur die Unternehmensexistenz gefährdet, sondern auch Menschen in Gefahr bringen kann, ist anhand des 787 Dreamliners von Boeing ersichtlich. Dort schlich sich ein Bug ein, der die Steuereinheit nach 248 Tagen Dauerbetrieb in den ausfallsicheren Modus schalten ließ. Wenn dieser Fehler während eines Fluges eintritt, verliert der Pilot die Kontrolle über die Maschine und ein Absturz ist die unausweichliche Konsequenz. Wenn man die Zahl jedoch genauer betrachtet sind 248 Tage in Hundertstel-Sekunden genau 2,147,483,647. Um dieses signifikante Problem zu beheben gab es für Boeing 2 Lösungsansätze:

Einerseits die Steuereinheit vor dem Ablauf der 248 Tage neu starten. Oder die wesentlich sichere Variante: adäquates Softwaretesten.

Der wohl berühmteste Overflow Bug in der Geschichte ist der allseits gehypte Millennium Bug, Y2K. Das Problem des 2000er Jahres sorgte bei vielen Entwicklern für Kopfschmerzen: Nicht alle Anwendungen waren darauf ausgelegt Jahreszahlen abzulegen die nach dem Jahr 1999 liegt. Unzählige Unternehmen mussten Aktualisierungen ihrer Softwarelösungen durchführen, um eventuelle Störfälle zu vermeiden. Bei der Wende in das neue Jahrtausend selbst blieben durch die Arbeit zahlreicher Entwickler schwerwiegende Folgen allerdings aus.

Zwölf Jahre später kam es jedoch zu einem amüsanten Vorfall: Eine schwedische Dame im Alter von 105 Jahren erhielt eine Einladung für den Start in die Vorschule. Im gesamten schwedischen Königreich wurden Einladungen an Kinder versandt, welche die Endziffern “07” im Geburtsjahr hatten. Die Entwickler haben dabei nicht bedacht, dass es Individuen gibt, die 1907 geboren wurden.

Wie man Overflows automatisch findet

Overflows gehören mitunter zu den am häufigsten auftretenden Sicherheitslücken. Bei der Entwicklung selbst wird zwar penibel darauf geachtet, solche Fehler zu vermeiden, jedoch gelingt dies oftmals nicht. Wie unsere ausgewählten Beispiele auch sehr gut veranschaulichen.

Einfache Programme bestehen häufig schon aus mehreren 100.000 Zeilen Code. Dabei ist es nahezu unmöglich, jeden einzelnen Fehler im Programm zu finden, geschweige denn zu testen. Je höher die Komplexität einer Anwendung ist, desto anfälliger ist diese für Softwarefehler. Um dieses Problem zu eliminieren, haben wir Symflower entwickelt. Symflower generiert vollautomatisch Unit-Tests und findet dadurch potentielle Overflows im Source-Code. Unabhängig von der Anzahl der Zeilen Code und der Komplexität der Anwendung. Dies geschieht ohne jeglichen menschlichen Einfluss.

Mehr über die Leichtigkeit des Unit-Testens findet ihr auf unserer Übersichtsseite. Schickt uns am besten gleich eine Anfrage für eine Produkt-Demo und macht euch selbst ein Bild von der Zukunft des Softwaretestens.