In the given example below I try to set the stacksize to 1kb.
Why is it now possible to allocate an array of ints on the stack with size 8kb
in foo()
?
#include <stdio.h>
#include <sys/resource.h>
void foo(void);
int main() {
struct rlimit lim = {1024, 1024};
if (setrlimit(RLIMIT_STACK, &lim) == -1)
return 1;
foo();
return 0;
}
void foo() {
unsigned ints[2048];
printf("foo: %u\n", ints[2047]=42);
}
I think
setrlimit
moves the "resource pointers" but doesn't apply the new limits until youexec
a new copy of the program.And a test run:
Why the process gets killed before printing the limits (and before calling foo), I don't know.
The limit is set immediately but only checked when trying to allocate a new stack or trying to grow the existing stack. A grep for RLIMIT_STACK (or a LXR identifier search) on the kernel sources should tell.
Apparently, the initial size of the stack is whatever is needed to the filename + env strings + arg strings plus some extra pages allocated on
setup_arg_pages
(20 pages in 2.6.33 1,2, 128 Kb on 2.6.34 3).In summary:
where
Additionally, kernels with Ingo Molnar's
exec-shield
patch (Fedora, Ubuntu, ...) have an additional EXEC_STACK_BIAS "(2MB more to cover randomization effects.)", see the call to the new functionover_stack_limit()
fromacct_stack_growth()
([Ubuntu1], [Ubuntu2], [Ubuntu3]).I've edited the original program to show this:
Which results in: