1
votes

I am doing some basic research on stack overflow and have some trouble how to overwrite/modify a local variable that is located below the buffer in the memory.

Consider the following piece of pseudo C code

char buff[20];
int pass=0;
.
.
.
gets(buff)
check if buff equals something, if true set pass == 1
if pass == 1, grant access

Now, from what I gather the variables declared are ordered inversely on the stack. That is, buff is located above pass in the stack. When gets copies something into buff, the buffer grows towards high address space - towards the return address and away from the pass variable. It doesn't matter what input I type - I simply cannot overwrite pass since it is on the 'wrong' side of the buffer?

1
How variables' storage is arranged is implementation-specific. There doesn't even need to be a stack. Moreover, any kind of object overrun invokes undefined behavior as far as C is concerned, so C provides no answer for you about what happens in such a case. You need to study the characteristics of the particular C implementation you're working with. And the relevant characteristics are not necessarily documented. - John Bollinger
Sometimes poor programming can allow negative indices to be generated, which can allow memory before a buffer to be accessed. - EOF
There are no guarantees on how separate objects are ordered in memory, and you should not expect any ordering to be meaningful. Some objects may be optimized out of existence altogether. Buffer overflows will clobber something, but what that something is depends on the specific implementation, code, optimization settings, etc. - John Bode

1 Answers

2
votes

You get no guarantees about the location of the variables on the stack. The compiler may rearrange them. And it does not matter if pass happens to be located right after buff[19]. Trying to access buff[20] is still undefined behavior. And undefined behavior is undefined, so anything may happen.

However, if you declare a struct it is a bit different. Let's take this simple example:

struct foobar {
    int foo;
    char bar;
    struct foobar * next;
}

Here you have guarantees that foo, bar and next will be in the order you have specified.