Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overflow over scanf("%8s", string)?

I know it's possible to overflow ordinary code:

char string[9];

scanf("%s", string).

But is it possible to overflow scanf("%8s", string)? 8 is just an example.

I know "%8s" works like a delimit, but I also notice when I input string longer than 8 chars, the program will terminate due to:

* stack smashing detected *: ./a.out terminated

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

...

Obviously there's a flag that detects stack smashing turned on by GCC by default. Since this is a stack smashing, then my guess is that it is still possible to overflow and execute arbitrary code.

Contrary to normal overflow that mangles the caller of scanf("%s"), if scanf("%8s") can overflow, it will overflow within scanf function so that when scanf try to return, control is gained.

But scanf is a syscall that requires mode-switch (switching from user mode into kernel mode), and internally it will call stuff like read to the stdin etc. So not sure if we can overflow in kernel mode or something..

Comments are welcome!!

UPDATE >>

char string[9] is assumed in the above example. char string[8] in following real code.

The question is really about the seeming conflicting story between safe scanf("%8s") and GCC abortion due to stack smashing.

Simplified 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;
       ...
   } 

}

}

Note:

  1. foo is called by someone else.
  2. Though string is 8 bytes in real code with "%8s", I don't think this lead to smashing.
like image 670
Figo Avatar asked Dec 10 '22 18:12

Figo


1 Answers

See http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html:

Each directive is composed of one of the following...An optional non-zero decimal integer that specifies the maximum field width.

s
Matches a sequence of bytes that are not white-space characters. The application shall ensure that the corresponding argument is a pointer to the initial byte of an array of char, signed char, or unsigned char large enough to accept the sequence and a terminating null character code, which shall be added automatically.

So it won't overflow a 9-byte string buffer.

like image 164
ysth Avatar answered Dec 21 '22 19:12

ysth