Was tun wenn der Stack überschrieben wird?

Gast #4411781
Lesenswert?
• ▲
▼
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ß!
Gast #4411841
Lesenswert?
• ▲
▼
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.
#4411859
Lesenswert?
• ▲
▼
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).
Gast #4411862
Lesenswert?
• ▲
▼
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!
#4411909
Lesenswert?
• ▲
▼
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.
#4411950
Lesenswert?
• ▲
▼
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*).

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.