使用 setrlimit() 设置堆栈大小并引发堆栈溢出/段错误
在下面给出的示例中,我尝试将堆栈大小设置为 1kb。
为什么现在可以在 foo()
中在堆栈上分配大小为 8kb
的整数数组?
#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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该限制会立即设置,但仅在尝试分配新堆栈或尝试增加现有堆栈时进行检查。内核源代码上的 RLIMIT_STACK(或 LXR 标识符搜索)的 grep 应该告诉我们。
显然,堆栈的初始大小是文件名 + env 字符串 + arg 字符串加上在
setup_arg_pages
上分配的一些额外页面(2.6.33 中的 20 页 1,2,2.6.34 128 Kb 3)。总结:
此外
,带有 Ingo Molnar 的
exec-shield
补丁的内核(Fedora、Ubuntu 等)还有一个额外的 EXEC_STACK_BIAS “(多出 2MB 来覆盖随机化效果。)”,请参阅acct_stack_growth()
对新函数over_stack_limit()
的调用 ([Ubuntu1], [Ubuntu2],[Ubuntu3])。我编辑了原始程序以显示以下
结果:
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:
我认为 setrlimit 移动了“资源指针”,但在您执行程序的新副本之前不会应用新的限制。
并进行测试运行:
为什么进程在打印限制之前(以及调用 foo 之前)被终止,我不知道。
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.