2

(This is in the context of x86-64 Linux.)

I am trying to write a high-reliability userland executable, and I have total control over the generated assembly. I don't want to rely on automatic stack allocation, so I would like to put the stack in a known location. Suppose I have calculated that my program uses at most 414 bytes of stack space (exactly). Is it safe to allocate 414 bytes in the .bss section and point RSP to the top? I want to ensure that no bytes outside this region are touched by stack management at any point.

While I can be sure that my program won't write outside the region, I need to make some syscalls (using the syscall instruction), and I think at least some part of the kernel code operates in the calling executable context. Will it smash my stack?

Also, interrupts can happen at any point in the program, and the story behind the "Red Zone" seems to suggest that an arbitrarily large region beyond RSP-128 can be written to at will by interrupt handlers, possibly mangling my data. What kinds of guarantees do I have about this behavior?

1

Is it safe to allocate 414 bytes in the .bss section and point RSP to the top?

Since you’re controlling all the content of your executable, and presumably not linking to any libraries, this should be fine. Notably, the MAP_STACK mmap flag currently has no effect, any readable and writable page can be used for the stack.

at least some part of the kernel code operates in the calling executable context

Yes, system calls operate inside the calling process, but ...

Will it smash my stack?

... the kernel operates on its own stacks — otherwise userspace could change values inside the kernel during system call execution! It doesn’t touch the userspace stacks, although some system calls do care about the stack (clone in particular).

Also, interrupts can happen at any point in the program, and the story behind the "Red Zone" seems to suggest that an arbitrarily large region beyond RSP-128 can be written to at will by interrupt handlers, possibly mangling my data. What kinds of guarantees to I have about this behavior?

Hardware interrupts also use their own stacks, so you’re safe there too. To protect yourself from signal handlers, you can set up a dedicated stack using sigaltstack.

  • Signal handlers are all implemented by the calling process, right (with some default behavior like process kill otherwise)? So if I haven't implemented any (or if I do, I take that into account in the stack bound), then the "Red Zone" doesn't actually mean anything, and unless I interface with the C ABI, RSP is just a number. – Mario Carneiro Jan 28 '20 at 20:30
  • I haven’t checked what the default handler does, but yes, I think it’s OK to assume that as long as you don’t interface with an external library (C or otherwise), RSP is just a number. – Stephen Kitt Jan 31 '20 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.