Wie schützte ich eine funktion davor ihren Stack zu vernichten.
-
Hallo NG,
beim Compilieren mit -Wstack-protector meint der Compiler öfters "warning: not protecting function: no buffer at least 8 bytes long". Nun sagt mir das jetzt recht wenig und Google weiß zu diesem Thema ganze acht Treffer, die mir auch nicht helfen zu verstehen, warum mein Quellcode seinen Stack vernichten soll. Und das gcc Handbuch ist da auch nicht sehr hilfreich. Hier eine Beispielfunktion.
unsigned char now = 0; unsigned char last = 0; const unsigned char FIRST_LETTER = 65; static void function (void) { unsigned char array[4]; if ((now < last) || (now > (last + FIRST_LETTER))) { array[0] = FIRST_LETTER; array[1] = FIRST_LETTER + now; array[2] = (now) ? 'Y' : 'N'; array[3] = 0; do_something (now); last = now; } }Gruß,
BlackPepper
-
RTFM
man gcc-Wstack-protector This option is only active when -fstack-protector is active. It warns about functions that will not be protected against stack smashing. ... -fstack-protector Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits.
-
Hallo Krümelkacker,
Dein Beitrag macht mich auch nicht schlauer als vorher. Eigentlich will ich ja verstehen, warum der Code ein Problem hat. Den es wird vom Compiler nicht jede Funktion angemeckert. Warum also diese?
Gruß,
BlackPepper
-
This includes functions that
call alloca, and functions with buffers larger than 8 bytes.Erfüllt deine Funktion eine dieser Kriterien?
-
Hallo Fellhuhn,
ja, aber das tun andere auch, die dann nicht angemeckert werden.
Gruß,
BlackPepper
-
Und die verwenden auch Arrays?
-
Hallo Fellhuhn,
ja. Aber falls Du versuchst mich auf die Antwort zu schubsen, mußt Du schon etwas präziser werden. Ich weiß nicht warum das ein Problem sein soll.
Gruß,
BlackPepper
-
Du verwendest als einziges auf dem Stack einen Array der zu klein ist als das er in das Muster des Schutzes fällt. Steht aber auch in der Erklärung. Dieses Limit kannst du aber auch verändern. Aber dazu musst du einfach nur die Anleitung lesen. Oder danach googlen. Steht da alles.
Hab mich mit dem Thema noch nie beschäftigt und das alles innerhalb weniger Minuten herausgefunden. Daher kann ich nicht glauben das du dich damit ernsthaft beschäftigt hast.
-
Hallo Fellhuhn und Rest der Welt,
ich habe mir nun mal alle "not protecting function..." Warnungen angesehen und dies mit den gegoogelten Sachen verglichen. Die Meldung tritt bei mir ohne erkennbares Muster auf. Das sind Funktionen ohne Übergabeparameter und mit mehr als acht Byte Übergabeparameter. Mit und ohne Rückgabewert. Da werden Arrays kleiner und größer acht Byte angelegt. Das sind auch Funktionen ohne Arrays. Da wird Speicher alloziiert.
Ich hätte gern ein Beispiel von jemandem, der mir sagen kann was typische Ursachen für diese Warnung sind. Das
int array[10]; array[10] = 100;oder ähnliches eine Stackverletzung ist, weiß ich aber auch selber. Und zumindesr passiert das nicht auf anhieb erkennbar. Und meine Anwendung steigt nicht mit einem Stack Smashing detected aus.
Gruß,
BlackPepper
-
Les dir doch endlich mal durch was das Teil überhaupt macht. Es scheint mir du hast das Prinzip nicht im Ansatz verstanden.
-
Hallo Fellhuhn,
fstack-protector fügt zusätzlichen Code ein, der Stackverletztungen sucht. Hierfür fügt der Compiler in Funktionen mit Verwundbaren Objekten (Arrays, malloc aufrufen, Buffer > 8 Byte u.ä.) eine Variable ein. Die Variable wird mit einem Wert initialisiert und vor dem Verlassen der Funktion wird überprüft, ob der Wert noch gültig ist. Wenn der Wert ungültig geworden ist wird eine Fehlermeldung ausgegeben (Stack smashing detected) und die Anwendung beendet.
Ich denke das reicht, oder?
Jetzt weiß ich aber noch immer nicht warum meine Bespielfunktion angemeckert wird, denn eine Prüfung kann eigentlich nicht schief gehen. Die Arrayindexe sind nicht ungültig und fix codiert. Und weil das Array kleiner acht Byte ist, dürfte gar keine Prüfung stattfinden. Warum also die Warnung? Ja, ich hab das Prinzip nicht verstanden, sonst wäre ich nicht hier. Wenn Du (oder irgend jemand anders) es weißt, wäre ich Dir dankbar, wenn Du mich an Deinem Wissen teil haben läßt.
Gruß,
BlackPepper
-
Deine Beispielfunktion aus dem ersten Post wird nicht angemeckert, du wirst nur informiert das sie nicht geschützt wird, weil sie die Bedingungen dafür nicht erfüllt.
-
BlackPepper, Du hättest ruhig mal mehr Beispiele von Code und Compielrausgaben geben können.
Es scheint auch, als würdest Du den Sinn der Warnung nicht verstehen. Dass diese Warnung auftritt heißt nicht, Dass Du etwas falsch gemacht hast, sondern nur, dass der Compiler hier diese nützlichen "guards" nicht überall eingeführt hat, wo sie theoretisch Sinn machen würden. Der Compiler teilt Dir das einfach nur mit. Warum er das nicht macht, steht in der Doku; denn Du hast hier nur ein 4-byte array. Die 8-byte grenze ist wahrscheinlich dazu da, den Stack nicht unnötig mit den "guards" aufzublähen. Wenn für jeses klirze kleine Array so ein Guard eingeführt werden soll (welcher wer weiß wie groß ist) geht es mit der Speichereffizienz den Bach runter.
Ich rate jetzt einfach mal (Anwendung des gesunden Menschenverstandes): Die Warnung wird genau dann ausgegeben, wenn die Funktion ein Array verwendet, was aber nicht größer als 8 Bytes groß ist. Es wäre also einerseits eine "schützenswerte" Funktion, andererseits würde zuviel Overhead dabei entstehen.
Fazit: Alles ist gut. Achte vielleicht verstärkt auf die Korrektheit der Funktionen, die der Compiler nicht "schützt".
Gruß,
SP
-
Hallo Sebastian,
wenn ich Dich recht verstehe, wird dieser Guard für _JEDES_ schützenswertes Objekt eingefügt, wenn er die Kriterien erfüllt und nicht nur einmal für den Stack. Dann verstehe ich warum Funktionen angemeckert werden, die _auch_ ein oder die mehrere kleine Arrays enthalten, aber auch große, Mallocs... Denn die haben im Stack auch schützenswerte Objekte größer acht Byte. Und der der Stack ist dann erst recht größer acht Byte. Ich hatte gedacht dieser Gurad wird nur einmal am ende des Stacks eingefügt wird. Die Beispielfunktion war nur die erste aus einer Reihe an Funktionen die angemeckert werden, die klein genug ist um sie schnell unkenntlich zu machen. Ich kann ja meinen Sourcecode nicht online stellen. Das hat mir jetzt geholfen.
In Zukunft mache ich aber mehr angaben. Vielleicht wäre dann schnelle aufgefallen wo mein Problem lag.
Gruß,
BlackPepper
-
Grundsätzlich verschiebt er Arrays ans Ende des Stacks, um eben Probleme zu vermeiden. Bei kleinen Arrays macht er das nicht. Kann man aber einstellen.
Bei Wikipedia steht auch eine zwar kurze aber knackige Erklärung.
-
Ich bezweifle übrigens dass malloc bei dieser Entscheidung irgendeine Rolle spielt, da es rein garnichts mit dem Stack am Hut hat. In der Erklärung steht auch alloca und nicht malloc.