3 ms·
> Because the stack frame for main contains a bunch of other stuff - environment variables, cli args, etc - […] > a) I bet some insane userland processes fuck w
by eqvinox 4y ago
> Because the stack frame for main contains a bunch of other stuff - environment variables, cli args, etc -
[…]
> a) I bet some insane userland processes fuck with their stacks
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.
- jart 4y agoWell it technically does if you make a new stack with mmap(MAP_STACK) (or simply round down the stack pointer by a page size) and remove the write access to the top of the original stack and mimmutable it.
- eqvinox 4y agoProblem is that those "magic variables" are defined by ABI to be directly above main()'s stack frame… if you're throwing that out, you may equally well leave the stack alone and put the magic stuff in some new place :) … 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?
- jart 4y agoYou mean _start()'s stack pointer. Libc can secure them and it's fine. It would probably break the ANSI C standard though if you can't modify argv and environ though. So Libc would need to copy them. But that limits the usefulness of the original tooling proposal unless the operating system has something like /proc/pid/maps that tells you the extent of the system provided stack. I don't think OpenBSD has that. Please prove me wrong since if it does, I'd love to know how.
- eqvinox 4y ago> You mean _start()'s stack pointer. 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.)
- 7vUYjPAG2fnx7fd 4y agoNo setproctitle on Linux. As far as I know you have to overwrite the argv space (and hopefully not also the environment space).
- eqvinox 4y agoLooking at the sibling post to yours, I'm assuming the "better" approach these days is to allocate a new buffer distinct from argv space and use PR_SET_MM_ARG_{START,END} to point the kernel there.
- jcranmer 4y ago> 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.
- eqvinox 4y agoNow I'm sad :( … but Thanks for removing a misconception of mine!
- 4y ago