…
Actually, now that I think about it, I guess you could try to put the boundary between main() and the magic bits right on a page boundary, and then change attrs on the magic bits?
Right, yeah.
> It would probably break the ANSI C standard though if you can't modify argv and environ though.
AFAIK it would also break setproctitle(), unless my memory is off that works by just writing over the argv space.
On the plus side, on Linux /proc/<pid>/environ is a snapshot created at the time of execve() and kept by the kernel, nothing other than execve() can change it (don't quote me on this, I'm only 90% sure.)
prctl(PR_SET_MM_ENV_{START,END}) will change the contents of /proc/<pid>/environ.
From what it looks like in Linux's source code, twiddling the bits at the base of the stack will also cause the procfs file to change--it seems to read directly from the process's memory. Ditto for /cmdline and /auxv, it seems.
… but Thanks for removing a misconception of mine!
The new OpenBSD `mimmutable()` call, when applied on the stack, does absolutely nothing to prevent writing or reading the stack. It prevents changing the (virtual memory/pagetable) mapping itself, i.e. mapping in something else, removing the mapping, or changing the mapping attributes (primarily RWX).
Even if some userland process requires an executable stack, that would be indicated with ELF flags and set up by the loader - and then frozen in place.