wouldn't it be easier to just say "any access to stack memory above X is invalid" instead of "check if this specific slice of Stark is being read"?
It would probably be slower.
If I remember correctly, the translation of process address space to physical addresses is implemented in hardware as a Memory-Management-Unit.
- The memory is organized into pages (pieces) and the MMU has a table that maps the virtual pages to physical pages.
- The physical pages are only allocated lazily when the program actually writes to them, so some of the virtual memory allocated by your program may not have a mapped physical address.
- When the program accesses a page that does not have a physical address, a page fault is triggered and only now the control is given to the OS. The OS may decide to allocate a new physical page, or kill the program if it tries to access something it should not.
So for most memory operation, a fast hardware-implemented lookup table is used, and the OS is asked only when a new page is needed. That is why it was convenient for them to to check for stack overflow using a guard page.
A stack allocation is just changing the value of the stack pointer register.
To detect the overflow, you would have to switch to kernel mode, check the stack pointer and switch back - a significant overhead given that stack allocations happen at least once per function call.
But I have no idea why this leads to privilege escalation.