Reputation: 91
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
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
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
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
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
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
Reputation: 23699
This code leads to an undefined behavior, ie you can't expect a segmentation fault. Anything can happen.
Upvotes: 7