I was curious about how the kernel prevents the stack from growing too big, and I found this Q/A:
Q: how does the linux kernel enforce stack size limits?
A: The kernel can control this due to the virtual memory. The virtual memory (also known as memory mapping), is basically a list of virtual memory areas (base + size) and a target physically memory area that the kernel can manipulate that is unique to each program. When a program tries to access an address that is not on this list, an exception happens. This exception will cause a context switch into kernel mode. The kernel can look up the fault. If the memory is to become valid, it will be put into place before the program can continue (swap and mmap not read from disk yet for instance) or a SEGFAULT can be generated.
In order to decide the stack size limit, the kernel simply manipulates the virtual memory map. - Stian Skjelstad
But I didn't quite find this answer satisfactory. "When a program tries to access an address that is not on this list, an exception happens." - But wouldn't the text section (instructions) of the program be part of the virtual memory map?
.text
section is mapped read-only in normal user-space processes. And at the opposite end of virtual address space, so there are lots of unused pages in the way before a stack-clash could happen. (Some of those pages intentionally left unmapped as guard pages below the stack-growth region). See Linux process stack overrun by local variables (stack guarding) for more about stack-growth limits and stuff. – Royoulimit -s
. How is Stack memory allocated when using 'push' or 'sub' x86 instructions?. Or for thread stacks (not the main thread), it's just a normal mmap allocation with no growth; the only lazy allocation is physical pages to back the virtual ones. – Royo.text
. (And the guard pages make sure there's a segfault if the stack does overflow past the growth limit.) Only if you setulimit -s unlimited
could you maybe grow the stack into some other mapping, if Linux truly does allow unlimited growth in that case without reserving a guard page as you approach another mapping. – Royo