简体   繁体   中英

Program do not crash on heap overflow

I have written following program:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main(int argc, char *argv[]){
  char *input;
  input = (char*)malloc(16);
  printf("input is : %s\n", input);
}

When I run this as:

./test `python -c 'print "A"*5000'`

it does not crash. It rather prints data.

When I use free(input) after printf , it crashes.

Why does this happen?

The code shown ignores its command line arguments:

int main(int argc, char *argv[]){
  char *input;
  input = (char*)malloc(16);
  printf("input is : %s\n", input);
}

It shouldn't matter what the Python script provides. However, your printf() is printing uninitialized data; that leads to undefined behaviour. If the printf() doesn't crash and there is a free(input); call after the printf() , then the free() shouldn't crash.

If you missed out a copy operation and intended to show something like this, then the rules are different:

int main(int argc, char *argv[]){
  char *input;
  input = (char*)malloc(16);
  strcpy(input, argv[1]);
  printf("input is : %s\n", input);
  free(input);
  return 0;
}

Now you are not checking that argv[1] is not a null pointer before you use it — that could cause a crash. And you are trampling way out of bounds of the allocated memory if you pass 5000 characters in argv[1] . Something will probably trigger a crash; it isn't defined what will cause the crash. The strcpy() may fail; the printf() probably won't fail if the copy doesn't (but that isn't guaranteed); the free() will probably fail because you trampled out of bounds (but even that isn't guaranteed). Such are the wonders of 'undefined behaviour'; anything could happen and it is valid behaviour.

Why does this happen?

Buffer overflow (in this case heap overflow ) doesn't cause immediately crash. Writing outside of bounds of allocated memory causes undefined behavior - anything might happen; even it can work correctly.

Is there a reliable way to create crash without having free()

If you don't even initialize pointer input and dereference it (read or write there), most likely you will get a SEGFAULT, but it's still 'only' undefined behavior.

From C99 draft standard

Possible undefined behavior ranges from ignoring the situation completely with unpredictable results , to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).


But be be careful

An overflow may result in data corruption or unexpected behavior by any process which uses the affected memory area . On operating systems without memory protection, this could be any process on the system .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM