cracq
cracq

Reputation: 91

Why can't I overflow a global variable?

I have this code below:

char buffer[10];      

void main(int argc, char *argv[]) {

   strcpy(buffer, argv[1]);
   printf("value of buffer %s\n",buffer);
}

I know that placing the buffer variable inside the main function I could overflow the stack, however by declaring it as a global variable, no matter how many ascii characters I enter from the command line that nothing happens. I was expecting a segmentation fault but it seems that it prints all the characters I enter. How come?

I have another question related to the topic, if a program has a buffer overflow vulnerability, e.g. stack overflow, could I enter a code as large as I wanted into the vulnerable variable or would the SO throw a segmentation default exception if the code surpasses the boundaries of the memory allocated for the user program?

Upvotes: 1

Views: 1955

Answers (6)

ouah
ouah

Reputation: 145829

Try with a larger input buffer, for example:

 ./tst $(perl -e "print 'A'x10000")

and you'll probably end up with the segfault.

As some of have mentioned in their answers writing past the object is undefined behavior and anything can happen.

Also while C does not talk about stack or heap, file-scope variables (like buffer in your program) are not usually stored in the stack.

When the buffer is in the stack you are very quickly (i.e., without the need of a very large input) buffer overwriting the return address of the function with some random address and that's the reason you get a segfault when the function returns.

Upvotes: 1

hmakholm left over Monica
hmakholm left over Monica

Reputation: 23332

As other answers explain, the language specification gives you have no right to expect any particular reaction to a buffer overrun (whether in a global variable or a local one).

What happens in practice is that some memory that was not reserved to be used for buffer does get overwritten. However, since your program exits right after your printf, it may well happen that whatever was using that memory don't get any chance to notice that the values that ought to be there aren't there anymore. It is also possible that the linker allocated a bunch of unused space after buffer, for example if it's rounding up the size of your writable data segment to a multiple of 4096 or some other convenient block size.

Upvotes: 1

Guillaume
Guillaume

Reputation: 1032

Global variables aren't stored on the stack. Theyre stored in .data/.bss and grow towards higher address spaces. Stack variables grow towards lower address space. The program instructions are held lower (in .text) than .data so overflowing a global won't overwrite them So you won't see anything obvious happen (like a seg fault).

On linux anyways.

Upvotes: 1

Dale Hagglund
Dale Hagglund

Reputation: 16440

You are overflowing your global variable, it's just that nothing (obviously) bad happens because of it. Try changing your code to look like:

char before[20];
char buffer[10];
char after[20];

Depending on how your tool-chain lays out memory, you should be able to see the consequences of overflowing buffer in either before or after.

The specific reason you don't get a SEGV is that those only happen when a location you try to store to is outside the region the operating system has allocated to your process. This allocation is done on 4k units (typically) and usually several of those, so you'll probably have to overflow global by at least 4kB, and probably 1MB or more to trigger a SEGV.

Upvotes: 4

alk
alk

Reputation: 70931

Try the follwing mod to see some side effect:

char buffer[10];      
char buffer1[10] = "123456789";      

void main(int argc, char *argv[]) {

   strcpy(buffer, argv[1]);
   printf("value of buffer %s\n",buffer);
   printf("value of buffer1 %s\n",buffer1);
}

Upvotes: 6

md5
md5

Reputation: 23699

This code leads to an undefined behavior, ie you can't expect a segmentation fault. Anything can happen.

Upvotes: 7

Related Questions