我的系统(linux内核2.6.32-24)正在实现一个名为地址空间布局随机化(ASLR)的功能。 ASLR似乎改变了堆栈大小:
void f(int n)
{
printf(" %d ", n);
f(n + 1);
}
int main(...)
{
f(0);
}
显然,如果执行该程序,您将获得堆栈溢出。问题是在每次执行时,分段错误发生在不同的“n”值上。这显然是由ASLR引起的(如果你禁用它,程序总是以相同的“n”值退出)。
我有两个问题:
答案 0 :(得分:1)
这可能意味着在一个实例中,堆栈恰好流入其他已分配的块,而在另一个实例中,它会跳过未分配的地址空间。
答案 1 :(得分:1)
ASLR代表“地址空间布局随机化”。它的作用是在每次运行时更改各个段/段起始地址,是的,这包括堆栈。
这不是一个错误;这是设计的。它的目的部分是为了使溢出缓冲区更难获取访问权限,因为为了执行任意代码,您需要欺骗CPU“返回”到堆栈上的某个点或运行时库中。合法的代码会知道在哪里返回,但是一些罐头利用不会 - 每次都可能是不同的地址。
至于为什么表观堆栈大小会发生变化,堆栈空间是以页为单位分配的,而不是以字节为单位。调整堆栈指针,特别是如果它不是页面大小的倍数,则会更改您看到的可用空间量。