Guten Morgen, folgende Situation: innerhalb einer mehrfach verschachtelten Aufrufhierachie wird ein memcpy (innerhalb von Funktion7) aufgerufen. Es handelt sich dabei um eine Socket-Funktion. In den Einstellungen des GCC habe ich -fstack-protector-all übergeben. Der Stackframe ist zunächst wie folgt: -000|Funktion7 -001|Funktion6 -002|Funktion5 -003|Funktion4 -004|Funktion3 -005|Funktion2 -006|Funktion1 -007|Funktion1 ---|end of frame Nach dem Aufruf der memcpy-Funktion sind nur noch die Einträge von Funktion7 und Funktion6 im Debugger sichtbar. Nach dem return in der Funktion6 schlägt wie zu erwarten die vorher Stack-Protection des GCC zu. Meine Frage ist jetzt: wie geht man generell an solche Probleme ran? Ich kann genau sehen an welcher Stelle das memcpy schief geht weil ich den RAM mit einem bestimmten pattern vorinitialisiere. Für ein paar Anregungen wäre ich sehr dankbar. Schönen Gruß!
Als kleine Ergänzung: Unter [1] ist die Beschreibung des Stack Protectors. Das Ganze spielt sich auf einem Cortex A9 ab. [1] http://wiki.osdev.org/Stack_Smashing_Protector
Moegliche Abhilfen: - mehr Stack vorsehen - kein grossen Variaben in Funktionen definieren - keine rekursiven Funktionen - mehr Speicher vorsehen - das ganze Konzept ueberdenken
Du solltest allerdings schon klären, ob das ein Programmierfehler deinerseits ist, oder der Stack einfach zu klein ist. Oliver
Da gibts einen schönen Artikel der das alles erklärt und Ideen gibt: http://insecure.org/stf/smashstack.html "Smashing The Stack For Fun And Profit" Man kann damit relativ viele schöne Sachen machen. Idealerweise überschreibst Du Deinen Stack mit Benutzereingaben, das macht mehr Spaß.
Hm, überprüfe doch mal Zieladresse und Länge, die Du an memcpy übergibst. Entweder hast Du zu viel auf den Stack gelegt, so dass er in den Bereich einer Variablen gelaufen ist, die Du mit memcpy beschreibst, oder Du schreibst an eine völlig falsche Adresse bzw. fängst an der richtigen Adresse an, aber schreibst mehr als das was dort hin passt. Ein weiterer Klassiker fällt in die Rubrik "use after free" : Du hast eine lokale Variable und einen Zeiger, der auf sie zeigt. Nachdem die Variable längst Geschichte ist, weil die Funktion, zu der sie gehört beendet ist, greifst Du über den Zeiger auf ihren Ex-Speicherbereich zu. Compiler legen meist lokale Variablen auf dem Stack an, deshalb liegt die Vermutung nahe, dass in deren Zusammenhang etwas schief läuft.
eine mögliches Fehreszenario: deine memcpy Zielvariabel liegt vermutlich auf dem Stack -> nicht gut + die Bytegröße von memcpy stimmt nicht mit dem Ziel überein -> echter tödlicher Fehler
Lernwilliger schrieb: > Nach dem Aufruf der memcpy-Funktion sind nur noch die Einträge von > Funktion7 und Funktion6 im Debugger sichtbar. Dann ist das kein Stacküberlauf. Der Stack "wächst" normalerweise vom Speicherende hin zu niedrigeren Adressen - ein Stacküberlauf wäre dann der Fall, wenn er in die .bss- oder .data-Section hineinwachsen und dort Unsinn anstellen würde. Nachdem hier aber offensichtlich der Stack "von oben her" überschrieben wird, hast Du mit ziemlicher Sicherheit einen simplen Programmierfehler (ein "&" z.B., wo keins hingehört).
Vielen Dank schonmal für die ganzen Denkanstöße! Uwe B. schrieb: > - mehr Stack vorsehen > - kein grossen Variaben in Funktionen definieren > - keine rekursiven Funktionen > - mehr Speicher vorsehen > - das ganze Konzept ueberdenken Ich arbeite mit einem Echtzeitsystem. Die Stacks für die Threads sind alle zu maximal 25% ausgelastet. Due Funktion ist eine Netzwerk-Socket-Funktion eines anderen Anbieters die in anderen Situationen auch schon funktionierte. Oliver S. schrieb: > Du solltest allerdings schon klären, ob das ein Programmierfehler > deinerseits ist, oder der Stack einfach zu klein ist. Klar! Mir fehlt nur einfach die Routine wie man an sowas strukturiert und zielführend rangeht... Christian B. schrieb: > Da gibts einen schönen Artikel der das alles erklärt und Ideen gibt: > http://insecure.org/stf/smashstack.html Danke, werde ich mir durchlesen. fop schrieb: > Hm, überprüfe doch mal Zieladresse und Länge, die Du an memcpy > übergibst. Volle schrieb: > die Bytegröße von memcpy stimmt nicht mit dem Ziel überein Wenn ich den Speicher der Zieladresse ansehe, dann sehe ich vier Byte 0 und danach das MagicPattern. Die übergebene Länge, ermittelt mit sizeof ist 132... Autsch. Ich befürchte es gibt konkurrierende Definitionen der Struktur die ich kopieren möchtes (fd_set), einmal vom Netzwerkstack und einmal vom Betriebssystem. Volle schrieb: > deine memcpy Zielvariabel liegt vermutlich auf dem Stack > -> nicht gut Wie genau kann ich das denn feststellen? Vielen Dank nochmal!
Markus F. schrieb: > Dann ist das kein Stacküberlauf. Stack-Überlauf habe ich es deswegen genannt, weil eben der Stack Protector zuschlägt. Ich kann auch im Debugger sehen, dass das Magic Pattern überschrieben wird...
Dann ist es eher ein BufferOverflow eines auf dem Stack abgelegten Array, oder ein use after free eine Stackvariable
Lernwilliger schrieb: > Due Funktion ist eine > Netzwerk-Socket-Funktion eines anderen Anbieters die in anderen > Situationen auch schon funktionierte. > ... >Die übergebene Länge, ermittelt mit sizeof > ist 132... Autsch. Ich befürchte es gibt konkurrierende Definitionen der > Struktur die ich kopieren möchtes (fd_set), einmal vom Netzwerkstack und > einmal vom Betriebssystem. > Oder die Struktur ist bei dem anderen Anbieter mit einem anderen Alignment wie bei dir compiliert.
Mit was wurden das memcpy() gefüttert? Ist die Zieladresse vielleicht eine lokale Pointervariable, von der dann versehentlich die Adresse statt dem Inhalt übergeben wurde. So wäre dann der Stack das Ziel und damit kaputt sobald die Kopierlänge > sizeof(void*).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.