Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It is stored in a register on some architectures like ARM. However, that register gets spilled to the stack to store another return address there when calling another level deeper. It doesn't change much. It does make it easier to implement return address control flow integrity that's not vulnerable to a race window between the CFI check and the return.


There have been machines with a separate return address stack in on-chip hardware. Forth CPUs were built that way, as was a National Semiconductor part used for running embedded BASIC. Running out of return point stack was a problem, since those 1980s machines were transistor-limited and came with small return stack sizes.


PICs are still popular and have hardware return stacks.

Modern high-end CPUs have hardware return stacks too, but only as a hint to the branch predictor of where a ret instruction will jump to (return stack buffer).

Separately... there are exploit mitigations that create a separate stack just for return addresses, making them impossible to reach through stack buffer overflows. For a recent implementation, see Clang's SafeStack:

https://clang.llvm.org/docs/SafeStack.html

Or for a hardware-assisted version, there's Intel CET (not yet implemented on shipping CPUs, AFAIK):

https://software.intel.com/en-us/blogs/2016/06/09/intel-rele...

There are serious limitations to this approach, though: there's a lot of important data on the stack other than return addresses, and overwriting it is often enough for an attacker to redirect control flow eventually, just more indirectly.


SafeStack is indeed very interesting, this is the only thing I see here which I consider to be fully superseding the idea of return-to-abort.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: