5 ms·
There is an argument for making the call/return stack a separate non-addressable region from argument passing. So a malicious app can't overwrite return address
by JoeAltmaier 6y ago
There is an argument for making the call/return stack a separate non-addressable region from argument passing. So a malicious app can't overwrite return addresses and execute arbitrary code. Intel considered this early on, and rejected it.
Why? Because of Fortran. There are (were?) cases where a Fortran app would reach back on the stack to retrieve values from before the last call or some such. Rather than find some other way of making that work for those folks, the separate-return-stack idea was shelved.
And we all live with this debacle for decades.
- stevemk14ebr 6y agoCheckout the shadow stack used for CET (control flow enforcement technology). It is literally this idea
- Someone 6y agoI don’t understand that argument. All function arguments still would be on a single stack (just as in Forth). That would only be a valid argument if some FORTRAN code inspected the return address, for example to behave differently, depending on the caller. I would guess it’s more because early systems had small address spaces. If your heap grows up from the bottom of memory, and one stack grows down from top of your address space, how do you know where to place that second stack, especially in a system with, say, a 64kB address space?
- JoeAltmaier 6y agoYes, exactly. Some FORTRAN code did exactly that. And the stack could go in a page not addressable by general purpose instructions, save call and return instructions (and perhaps some kernel debug). Some limited-RAM embedded devices have dedicated stack RAM. But my point was about Intel x86
- monocasa 6y agoIf that was an issue, they managed to fix it decades ago. Itanium had separate return address and data stacks, and scientific computing was one of it's few competitive strongsuits.
- titzer 6y agoYou cannot address the call stack in WebAssembly, thus there can be no stack-smashing attacks (that overwrite return addresses). For languages that pass pointers into the stack, they must use a "shadow" stack allocated as a separate region and managed with an explicit stack pointer.
- userbinator 6y agoThere are architectures with a separate (and limited) call stack. They also tend to be Harvards, with the data and program memory completely separate. In other words, go down that path and you end up with what amounts to a restricted microcontroller instead of a general-purpose computer... which unfortunately seems to be where things are heading with the rising authoritarian technocracy.