views:

100

answers:

2

My system (linux kernel 2.6.32-24) is implementing a feature named Address Space Layout Randomization (ASLR). ASLR seems to change the stack size:

void f(int n) 
{
    printf(" %d ", n);
    f(n + 1);
}

int main(...)
{
    f(0);
}

Obviously if you execute the program you'll get a stack overflow. The problem is that segmentation fault happens on different values of "n" on each execution. This is clearly caused by the ASLR (if you disable it the program exits always at the same value of "n").

I have two questions:

  1. does it mean that ASLR make stack size slightly variable?
  2. if so, do you see a problem in this fact? Could be a kernel bug?
+1  A: 

It might mean that in one instance the stack happens to flow into some other allocated block, and in the other instance, it trips over unallocated address-space.

Marcelo Cantos
I thought this at first too, but I've been trying it out and watching the /proc/<pid>/maps file. The stack segment never gets close to another mapping and its size gets significantly (more than a page) larger than the rlimit (rlim_cur) for stack before it segfaults.
jdizzle
Do you mean that if default stack size is 8192k, the segmentation fault happens much after it exceeds this limit?Could you post instructions to check this behavior?
agori
i just have a loop catting the /proc/<test>/maps file and look at the last thing it printed before the proc crashed. The memory range allocated to the stack has been consistently larger at crash time than the rlimit'd amount (I get/print the rlimit value before I start the infinite recursion)
jdizzle
+1  A: 

ASLR stands for "address space layout randomization". What it does is change various section/segment start addresses on each run, and yes, this includes the stack.

It's not a bug; it's by design. Its purpose, in part, is to make it harder to gain access by overflowing buffers, since in order to execute arbitrary code, you need to trick the CPU into "returning" to a certain point on the stack, or in the runtime libraries. Legitimate code would know where to return to, but some canned exploit wouldn't -- it could be a different address every time.

As for why the apparent stack size changes, stack space is allocated in pages, not bytes. Tweaking the stack pointer, especially if it's not by a multiple of the page size, changes the amount of space you see available.

cHao
Are you sure that ASLR could change section/segment sizes? Do you have some reference about this?
agori
Besides that's being its whole purpose in life (hence the name), see http://en.wikipedia.org/wiki/Address_space_layout_randomization or http://netsecurity.about.com/od/quicktips/qt/whatisaslr.htm for some more info.
cHao
ASLR surely changes addresses, but I can't see any document speaking about a changing stack size.
agori
This does not answer how changing the *stack size* can occur and if has a purpose. Not everyone's happy with the stack size changes: http://gnats.netbsd.org/41877
Luther Blissett
IMHO a program that almost fills the stack is not a well coded program. It could raise error for different inputs, with or without ASLR.
agori
Most section sizes couldn't change, as they need to be big enough for the code that uses them, and they are hardly ever bigger than that. The stack's a bit different; it gets set up in a certain spot (either from 0 to limit or from limit to -1, with the latter being more common), meaning one end or the other is fixed -- usually both. The quick-and-easy way to change the stack pointer is to push a random amount of data onto the stack, which by definition takes up some space and effectively makes the stack a little "smaller".
cHao
@cHao: if crash happens after stack limit is reached (the one documented by ulimit -a), there is not a **real** change of the stack size. I mean if ASRL guarantees at least the default size, then we can't speak of a changing stack size. Do you agree?
agori
@agori: Semi. The size does change, but not enough to negatively affect legitimate code. Especially if it's increased rather than decreased. Good point though.
cHao