这与问题'Why do stacks typically grow downwards?'有关,但从安全角度来看更多。我通常指的是x86。
奇怪的是,当缓冲区通常在内存中向上写入时,堆栈会向下增长。例如,典型的C ++字符串的结尾位于比起始值更高的内存地址。
这意味着如果存在缓冲区溢出,则会进一步覆盖调用堆栈,我理解这是一种安全风险,因为它可以更改返回地址和本地变量内容。
如果堆栈在内存中向上增长,那么缓冲区溢出会不会简单地运行到内存中?这会提高安全性吗?如果是这样,为什么还没有这样做?那么x64,那些堆栈是否会向上增长,如果没有,为什么不呢?
答案 0 :(得分:25)
从技术上讲,这取决于OS / CPU,但通常这是因为堆栈和堆在相反的方向上生长,并且从地址空间的相对端生长。
这种安排使您能够最灵活地在堆和堆栈之间拆分/分配内存,而不会导致它们发生冲突。如果它们都朝着相同的方向增长,那么你需要有一个堆栈的起始地址,它会对堆的最大大小设置一个硬限制(以及堆栈大小的硬限制)
ETA:
找到一个interesting piece on wikipedia,说明为什么使堆栈增长不一定会阻止堆栈溢出 - 它只会使它们的工作方式有所不同。
答案 1 :(得分:3)
好吧,我不知道堆栈增长方向是否会对安全性产生太大影响,但是如果你看一下机器架构,那么在负地址方向增长堆栈确实简化了调用约定,堆栈帧指针,局部变量分配等等。
答案 2 :(得分:3)
8088的体系结构(x86系列的开始)使用了向下增长的堆栈,并且为了兼容性,从那时起就一直如此。当时,(80年代早期)家用电脑上的缓冲区溢出漏洞远远不够。
我无法告诉你为什么他们选择让它长大,但是当它变得更加直观。如前所述,内存通常在堆栈和堆之间分配;也许CPU设计师认为堆积大是很重要的,因此堆栈的结果会逐渐减少。
答案 3 :(得分:1)
可能是因为大多数CPU的架构是在男性为男性的时候设计的,你可以相信你的程序员不想窃取人们的信用卡号码......现在改变已经太晚了(尽管如你所说) ,它可能适用于像Itanium which actually has two stacks这样的新架构!)