Digital > Fefes Blog 2.0 > a7b7880f
  Leserreporter: Wer schöne Verschwörungslinks für mich hat: ab an felix-bloginput (at) fefe.de!
[zurück][ältere Posting][neuere Posting]  Dienstag, 20 Juni 2017 | Blog: 10 | No: 38729     feed-image

der Stack nach unten, was wenn die sich treffen?

wie man eine Kollision zwischen Heap und Stack ausnutzen kann

Gerade geht ein schönes Paper rum, wie man eine Kollision zwischen Heap und Stack ausnutzen kann.
Dass das ein Problem ist, war schon immer klar. Der Heap wächst nach oben, der Stack nach unten, was wenn die sich treffen?
Das Problem ist so alt, dass früher die "Lösung" einfach war, zu sagen, naja, dann ist Speicher alle, und wenn Speicher alle ist, dann crashen die Programme ja auch ohne Kollision!1!!
Die besseren Programme haben dann irgendwann angefangen, Speicherknappheit zu erkennen und nicht zu crashen, und so gab es auch irgendwann eine halbherzige "Lösung" für das Kollisionsproblem — eine "Guard Page". Speicherschutz funktioniert über eine Hardware-Komponente namens MMU, Memory Management Unit, und die arbeitet nicht auf Bytes sondern auf Pages. Pages sind im Allgemeinen 4KiB groß. Wenn man auf eine Page zugreift, die nicht da ist, dann wirft der Prozessor eine Exception, die das Betriebssystem abfangen kann. So wird beispielsweise Swapping implementiert. Aber wenn der Zugriff auf eine Page war, die nicht da sein sollte, dann kriegt das laufende Programm einen Segmentation Violation signalisiert (theoretisch auch abfangbar, aber üblicherweise nicht abgefangen und prinzipiell auch keine so gute Idee) und crasht.
Die Idee der Guard Page ist, dass man zwischen dem Ende des Heaps und dem Anfang des Stacks eine Page leer und ungemappt lässt. Das klingt erstmal gut, ist es aber nicht.
Denn auf dem Stack kann man auch lokale Variablen deklarieren, die größer als eine Page sind, und so die Guard Page überspringen.
Nichts hiervon ist irgendwie überraschend oder eine neue Erkenntnis. Und die Lösung ist auch offensichtlich. Wenn der Compiler auf dem Stack etwas größer als eine Page alloziert, dann emittiert er eben auch Code, der alle Pages auf dem Weg einmal kurz anfasst.
Visual Studio tut das seit über 10 Jahren, wahrscheinlich schon viel länger. Seit ich mir das erste Mal deren Disassemblat angeguckt habe, tut es das.
gcc tut es aber nicht.
Ich erinnere mich noch, mich 2005/2006 mit meinem Kumpel Ilja über genau dieses Problem unterhalten zu haben, und ich bin mir fast sicher, dass er den gcc-Leuten gesagt hat, sie sollen da mal solchen Code emittieren. Aber er findet gerade kein verlinkbares Material. Dafür, dass gcc da seit 20 Jahren auf einem bekannten Problem sitzt, lege ich aber meine Hand ins Feuer. das war komplett vermeidbar, und die, die es hätten vermeiden müssen, haben es nicht getan. Ohne eine Ausrede dafür zu haben. Hier ist z.B. ein Beitrag von 2013, der das Problem beschreibt. Krasserweise gibt es sogar grundsätzlich Support für Stack Probing in gcc, der ist nur bei C und C++ nicht angeschaltet. Hier ist ein Bug von 2007 dazu. Ich bin mir aber sicher, dass das Problem schon länger bekannt ist.

[zurück] [ältere Posting][neuere Posting]
[zurück] [ältere Posting][neuere Posting]

Fefes Latest Youtube Video Links