linux是不是在较低的堆栈端下方提供了保证的不可访问的内存区域?

Posted

技术标签:

【中文标题】linux是不是在较低的堆栈端下方提供了保证的不可访问的内存区域?【英文标题】:Does linux provide a guaranteed inaccessible memory area below the lower stack end?linux是否在较低的堆栈端下方提供了保证的不可访问的内存区域? 【发布时间】:2014-04-27 18:24:50 【问题描述】:

Linux 是否在具有保证的最小大小的较低堆栈端下方提供不可访问的内存区域?如果存在这样的保证最小尺寸,它是什么?

或者换句话说,我什么时候应该开始担心alloca() 或者给我指向有效的非堆栈内存的指针?

【问题讨论】:

有系统提供吗? @ElliottFrisch 好吧,我希望如此......否则你可能会导致堆栈运行到任何程序的堆中,这些程序可能会被强制分配足够的 RAM,然后执行任意大的递归。跨度> 好的。在你见过它的系统上它叫什么? Stack smashing protection? @ElliottFrisch 不,这是针对缓冲区溢出的保护,而不是堆栈的“下溢”,它发生在编译器/用户空间中,并且不使用内存映射等强制执行。 这个问题或多或少与***.com/questions/5543330/…重复 【参考方案1】:

正如alloca man page 所说:

如果堆栈帧无法扩展,则没有错误指示。 (但是,在分配失败后,程序很可能会收到 SIGSEGV 信号,如果它试图访问未分配的空间。)

所以根本没有任何迹象,它还说:

如果分配导致堆栈溢出,则程序行为未定义。

堆栈溢出问题是递归的普遍问题,并不是alloca 或变长数组所特有的。通常,您需要找到一种方法来限制递归的深度、重构为迭代解决方案或使用您自己的动态堆栈(可能不适用于这种情况)。

更新

当 OP 通过生成 SIGBUS 信号发现堆栈溢出的 Linux does provide an after the fact indication using a guard page after the stack 时,该信号解决了问题的第一部分。

【讨论】:

“正如 OP 发现的那样,Linux 确实通过生成 SIGBUS 信号提供了堆栈溢出的事后指示。”但我的问题是关于大分配的可靠性——你并不总是得到这个信号,有时你的程序会默默地继续做一些愚蠢的事情。我的问题是 alloca() 的最大大小是多少,然后我才不得不担心我的程序会做一些非常糟糕的事情而不仅仅是崩溃。 @thejh 我补充说只是为了完整性,因为您的问题确实有两个部分。这个问题对递归来说更普遍,解决方案需要重新设计。 当然,当你把你的代码弄乱了,以至于有无限递归的代码路径时,这应该被修复——但是是否有人可以让我的程序崩溃或让它运行任意代码,这是一个巨大的差异,这就是我的问题所在。【参考方案2】:

感谢 @ElliottFrisch 让我用正确的名称在 Google 上搜索它...哎呀。

看起来答案是“在较新的内核中:一页,在较旧的内核中:没有这种保护”。

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=320b2b8de12698082609ebbc1a17165727f4c893

【讨论】:

以上是关于linux是不是在较低的堆栈端下方提供了保证的不可访问的内存区域?的主要内容,如果未能解决你的问题,请参考以下文章

大小端存储

如何在较低的 API 模拟器中使用 Google Play 服务

Postgres - 在较低的 UNION 选择语句中插入 NUMERIC[] 值“0”

VideoView 不在 android Q 中播放视频,但在较低的 android 版本中工作正常

关闭堆栈中较低的 ViewController 的行为不符合预期

为啥堆栈会增长到较低的地址? [复制]