Débordement de cours scanf(“%8”, string)?

Je sais que c'est possible de débordement du code ordinaire:

char string[9];

scanf("%s", string).

Mais est-il possible de débordement scanf("%8", string)? 8 est juste un exemple.

Je sais "%8" fonctionne comme un délimiter, mais je remarque aussi quand j'ai de la chaîne d'entrée de plus de 8 caractères, le programme prendra fin en raison:

* stack smashing détecté *: ./un.hors mis fin

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

...

Évidemment il y a un drapeau qui détecte écrasement de la pile activée par GCC par défaut. Puisque c'est un écrasement de la pile, puis je pense qu'il est encore possible de débordement et d'exécuter du code arbitraire.

Contraire à la normale débordement de mangles l'appelant de scanf("%s"), si scanf("%8") peuvent déborder, elle déborde à l'intérieur de fonction scanf, de sorte que lorsque scanf essayez de retour, le contrôle est acquis.

Mais scanf est un syscall qui nécessite de commutation de mode (passage du mode utilisateur en mode noyau), et à l'intérieur il va appeler des trucs comme lecture de l'entrée standard stdin etc. Si vous ne savez pas si nous pouvons débordement en mode noyau ou quelque chose..

Commentaires sont les bienvenus!!

Mise à JOUR >>

char string[9] est supposé dans l'exemple ci-dessus. char chaine[8] dans la suite du code réel.

La question est vraiment à propos de l'apparente contradictoires histoire entre sûre scanf("%8") et GCC l'avortement suite à l'écrasement de la pile.

Simplifié 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;
       ...
   } 

}

}

Remarque:

  1. foo est appelé par quelqu'un d'autre.
  2. Si la chaîne est de 8 octets dans la vraie
    code avec "%8", je ne pense pas que ce
    conduire à des smashing.
scanf est une fonction de bibliothèque runtime—pas de commutateur de mode est nécessaire parce qu'il opère dans l'espace utilisateur, à moins qu'il a à la demande de remplissage de la mémoire tampon, dans ce cas, il ferait appel de lire ou fread.
comme l'a noté à plusieurs reprises dans les réponses, un octet nul est ajouté, de sorte que vous avez besoin d'un 9 tampon de caractère pour accepter jusqu'à 8 caractères de l'entrée.
Comme beaucoup de gens l'ont souligné, votre hypothèse à la Note 2." est faux. Cet exemple permet à un seul octet de dépassement de, qui est ce que gcc est la détection.
vous les gars sont à droite. Je l'ai testé avec un programme plus simple mais c'est en quelque sorte de ne pas planter la dernière fois que j'ai essayé. Maintenant quand je rentre "12345678" pour la chaîne[8] et scanf(%8s) il se bloque en raison de l'écrasement de la pile! Voici donc la leçon apprise. Smashing ne signifie pas nécessairement qu'il y a un débordement de la pile d'attaque.
Même si la mémoire tampon se trouve être sur la pile dans ce cas, le bug de programmation est un débordement de la mémoire tampon pas de un débordement de pile. J'ai utilisé la question en conséquence.

OriginalL'auteur Figo | 2009-11-24