可变堆栈大小

时间:2010-07-29 09:21:30

标签: c linux stack stack-overflow

我的系统(linux内核2.6.32-24)正在实现一个名为地址空间布局随机化(ASLR)的功能。 ASLR似乎改变了堆栈大小:

void f(int n) 
{
    printf(" %d ", n);
    f(n + 1);
}

int main(...)
{
    f(0);
}

显然,如果执行该程序,您将获得堆栈溢出。问题是在每次执行时,分段错误发生在不同的“n”值上。这显然是由ASLR引起的(如果你禁用它,程序总是以相同的“n”值退出)。

我有两个问题:

  1. 是否意味着ASLR使堆栈大小略有变化?
  2. 如果是的话,你看到这个问题吗?可能是内核错误吗?

2 个答案:

答案 0 :(得分:1)

这可能意味着在一个实例中,堆栈恰好流入其他已分配的块,而在另一个实例中,它会跳过未分配的地址空间。

答案 1 :(得分:1)

ASLR代表“地址空间布局随机化”。它的作用是在每次运行时更改各个段/段起始地址,是的,这包括堆栈。

这不是一个错误;这是设计的。它的目的部分是为了使溢出缓冲区更难获取访问权限,因为为了执行任意代码,您需要欺骗CPU“返回”到堆栈上的某个点或运行时库中。合法的代码会知道在哪里返回,但是一些罐头利用不会 - 每次都可能是不同的地址。

至于为什么表观堆栈大小会发生变化,堆栈空间是以页为单位分配的,而不是以字节为单位。调整堆栈指针,特别是如果它不是页面大小的倍数,则会更改您看到的可用空间量。