Überlauf über scanf("%8s", string)?

Ich weiß, es ist möglich zu überlaufen ordentlichen code:

char string[9];

scanf("%s", string).

Aber ist es möglich, mit überlauf scanf("%8s", string)? 8 ist nur ein Beispiel.

Ich weiß, "%8s" funktioniert wie eine Abgrenzung, aber ich merke auch, wenn ich den input-string länger als 8 Zeichen, wird das Programm beendet durch:

* stack smashing detected *: ./ein.aus gekündigt

======= Backtrace: =========

...

Offensichtlich gibt es ein flag, das erkennt stack-smashing eingeschaltet, indem Sie GCC standardmäßig. Da dies ist ein stack-smashing, dann meine Vermutung ist, dass es immer noch möglich zu überlaufen und beliebigen code ausführen.

Im Gegensatz zu normalen überlauf, mangles der Aufrufer scanf("%s"), wenn scanf("%8s") können überlauf, überlauf wird innerhalb der scanf-Funktion, so dass, wenn scanf versuchen, wieder die Kontrolle gewonnen.

Aber scanf ist eine syscall, die erfordert, dass der Modus-Schalter (Umschaltung vom Benutzermodus in den Kernelmodus), und intern wird Sie nennen Dinge wie Lesen von stdin, etc. Also nicht sicher, ob wir können-overflow im kernel-Modus oder so..

Kommentare sind herzlich willkommen!!

UPDATE >>

char string[9] angenommen im obigen Beispiel. char string[8] im folgenden code.

Die Frage ist wirklich über die scheinbare widersprüchliche Geschichte zwischen sicheren scanf("%8s") und GCC Abtreibung aufgrund stack-smashing.

Vereinfachte code:

void foo(pass some pointer) {
char input[8];
int input_number = 0;

while (1) { //looping console
   printf some info;
   scanf("%8s", input);

   input_number = atoi(input);

   if ((strlen(input) == 1) && (strncmp(input, "q", 1) == 0)) {
       input_number = -1;
   }
   switch (input_number) {
       case -1: to quit the console if input = 'q';
       default: to print info that pointer refers to;
       ...
   } 

}

}

Hinweis:

  1. foo aufgerufen wird, der von jemand anderem.
  2. Obwohl der string ist 8 bytes in real
    code mit "%8s", ich glaube nicht, dass dies
    führen zu zerschlagen.
scanf ist eine runtime-library-Funktion—kein Modus-Schalter ist notwendig, da es arbeitet im user-space, es sei denn, es hat zu Anfrage-Puffer-Füllung, in dem Fall würde es nennen, Lesen oder fread.
wie bereits mehrfach in den Antworten, ein nul-byte Hinzugefügt, so benötigen Sie ein 9-Zeichen-Puffer zu akzeptieren, bis zu 8 Zeichen der Eingabe.
Wie viele Menschen haben darauf hingewiesen, den Ihre Annahme, in "Note 2." ist falsch. Das Beispiel ermöglicht es einem einzelnen byte-überlauf, was gcc zu erkennen.
Sie Jungs sind richtig. Ich habe es getestet mit ein noch einfacheres Programm, aber es irgendwie nicht zum Absturz der letzten Zeit habe ich versucht. Wenn ich jetzt enter "12345678" für string[8] und scanf(%8s) es stürzt ab, weil der stack-smashing! Hier ist also die Lektion gelernt. Smashing bedeutet nicht unbedingt, es gibt eine stack-overflow-Angriff.
Obwohl der buffer geschieht, werden auf dem stack in diesem Fall, der Programmier-Fehler ist ein buffer overflow nicht zu einem stack-überlauf. Ich retagged die Frage entsprechend.

InformationsquelleAutor Figo | 2009-11-24

Schreibe einen Kommentar