|
|
Subscribe / Log in / New account

A return-oriented programming defense from OpenBSD

A return-oriented programming defense from OpenBSD

Posted Sep 12, 2017 16:20 UTC (Tue) by zlynx (guest, #2285)
In reply to: A return-oriented programming defense from OpenBSD by itvirta
Parent article: A return-oriented programming defense from OpenBSD

I believe that *every* recent CPU instruction set does a separate return stack. Well, as far as I can tell RISC-V puts it in a register, then it is up to a function caller to save the "ra" register wherever it wants before making the call. It can save it to the stack, a different stack or a linked list, the processor doesn't care. Itanium was similar, return addresses were saved in registers, and the registers would overflow into a separate stack.

If only people would stop relying on the x86 / amd64 ISA.


to post comments

A return-oriented programming defense from OpenBSD

Posted Sep 12, 2017 18:32 UTC (Tue) by excors (subscriber, #95769) [Link]

RISC-V sounds similar to ARMv8 AArch64, where (if I understand correctly) the "BLR" instruction branches and stores the return address in the X30 (LR) register, and the "RET Xn" instruction returns to the address stored in some register, and that's the only proper way to call a function. A non-leaf function can preserve X30 however it wants; usually it will push/pop X30 on the stack associated with the slightly magic SP register, but the push/pop instructions (store-and-decrement/load-and-increment) can use any register as the index, so I think you could create a separate control stack for approximately zero cost (just one more reserved register) to keep the frame pointers and return addresses away from all the "char surely_this_is_big_enough[256];" buffers and other local variables.

(ARMv7/AArch32 is similar but more confusing, because there are lots of mostly-deprecated ways of returning by using PC as a destination register, and you usually push/pop LR/PC in the same instruction as all the other registers you want to preserve (whereas AArch64 can only push/pop a pair of registers at once), and the Thumb instruction encoding has lots of limitations, and there are only half as many registers as AArch64, so a separate control stack might be significantly more expensive there.)


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds