防止堆栈溢出的硬件解决方案是什么? 例如,当我们想要设计一个新的操作系统时,我们如何防止堆栈溢出?
谢谢
答案 0 :(得分:4)
如果可以静态确认代码不具有任何直接或间接递归,则静态分析可能会产生最坏情况的堆栈使用情况。确保堆栈足够大并且不会有任何堆栈溢出。最大的困难是可能很难确定哪些函数指针可以调用哪些函数。例如,如果一个函数指针可以指向foo1()或foo2(),另一个可以指向bar1()或bar2(),而foo1()调用第二个函数指针(因此到达bar1或bar2)则不会递归的可能性,但如果编译器无法确定第二个指针只能指向bar1()或bar2(),它可能不知道。
如果可以确定应用程序是非递归的,并且如果静态分析最坏情况调用图并不比实际发生的情况差太多,则可以完全避免堆栈并分配所有变量都是静态的。在某些情况下(特别是在没有有效索引的架构上),与使用堆栈相比,这种方法可以显着提高性能。
从安全角度来看,避免堆栈/缓冲区溢出攻击的一种好方法是避免在“普通”指针可以访问的任何地方存储真正的程序计数器地址。将程序计数器堆栈与参数/自动变量堆栈完全分开存储,并且不直接存储任何函数指针。相反,每个“函数指针”都是具有相同签名的函数表的索引,并在使用它之前检查索引以确保它在范围内;如果两个或多个函数组具有不同的安全含义并且应该由完全不同的指针调用,则根据需要调整一个组的签名以使其与另一个组不同(因此对第一组中的函数的调用不能是转换为对第二个函数的调用。
答案 1 :(得分:3)
哈佛架构为堆栈溢出攻击提供了一些保护。 Are Harvard architecture computers immune to arbitrary code injection and execution attacks?
但是,在操作系统级别,您可能需要考虑使用non-executable stack。
答案 2 :(得分:2)
您可能会感到惊讶,但其中一个选项是无堆栈硬件架构(实际或模拟)(discussed here)。显然,没有堆栈 - 没有堆栈溢出。
答案 3 :(得分:1)
当堆栈处于预定义阈值时,某些微控制器会提供硬件陷阱。这可以用于正常关闭,或者将堆栈分页到外部RAM并重新启动。有一个类似的“下溢”陷阱来重新填充旧堆栈。