我了解到每个进程的默认堆栈大小限制在8MB以内,mmap_base是根据堆栈大小( rlimit和随机值)计算的。下面的代码是x86(linux/include/uapi/asm-generic/resource.h).中计算mmap_base地址的mmap_base函数
static unsigned long mmap_base(unsigned long rnd)
{
unsigned long gap = rlimit(RLIMIT_STACK);
if (gap < MIN_GAP)
gap = MIN_GAP;
else if (gap > MAX_GAP)
gap = MAX_GAP;
return PAGE_ALIGN(TASK_SIZE - gap - rnd);
}我想知道如果程序堆栈的大小大于8MB+rnd值呢?我的意思是,如果堆栈大小超过mmap_base会怎样?如果我将堆栈内存分配到8MB以上,那么是否只是由于分段错误而失败了?如果内核自动扩大堆栈大小,是否可以将mmap_base中的内容移动到其他空间?
发布于 2017-11-28 19:03:25
进程主线程堆栈大小不能超过设置限制。此限制的默认值为8MB。超过这一限制将导致分割错误,进程将被发送一个SIGSEGV信号,默认情况下会杀死它。在启动程序之前,可以用ulimit -s更改堆栈的最大大小。程序启动后,内核不会在内存区域(如mmap区域)周围移动,也不会这样做,因为通常会有指向该区域的指针指向移动后的错误地址。
但是,在访问堆栈内存时会执行堆栈溢出检查,因此仅在堆栈上执行大分配或以其他方式更改堆栈指针的值并不一定会触发故障。
2017年夏天,有一些关于利用这种行为的可能性的讨论。如果某些攻击者可以欺骗一个程序来分配大量内存,这可能导致堆栈指针跳过一个保护区域并指向一个有效的但不同的区域。这为一些巧妙的技巧提供了控制过程的机会。有关此问题的讨论,请参见这篇lwn.net文章。
https://unix.stackexchange.com/questions/407204
复制相似问题