On Tue, Feb 20, 2024 at 06:59:58PM -0500, Stefan O'Rear wrote:
On Tue, Feb 20, 2024, at 6:30 PM, Edgecombe, Rick P wrote:
Maybe I'm misunderstanding. I thought the proposal included allowing shadow stack access to convert normal address ranges to shadow stack, and normal writes to convert shadow stack to normal.
Ideally for riscv only writes would cause conversion, an incssp underflow which performs shadow stack reads would be able to fault early.
For arm, since a syscall is needed anyway to set up the token in a new shadow stack region, it would make sense for conversion from non-shadow to shadow usage to never be automatic.
Well, we only need the token to pivot in userspace so we could *potentially* work something out as part of the conversion process. It's not filling me with enthusiasm though, and I've certainly not actually thought it through yet.
I agree though that the late allocation failures are not great. Mark is working on clone3 support which should allow moving the shadow stack allocation to happen in userspace with the normal stack. Even for riscv though, doesn't it need to update a new register in stack switching?
BTW, x86 shadow stack has a mode where the shadow stack is writable with a special instruction (WRSS). It enables the SSP to be set arbitrarily by writing restore tokens. We discussed this as an option to make the existing longjmp() and signal stuff work more transparently for glibc.
We have this feature on arm64 too, plus a separately controllable push instruction (though that's less useful here).
BTW, when I talk about "not supporting" I don't mean the app should crash. I mean it should instead run normally, just without shadow stack enabled. Not sure if that was clear. Since shadow stack is not essential for an application to function, it is only security hardening on top.
I appreciate that. How far can we go in that direction? If we can automatically disable shadow stacks on any call to makecontext, sigaltstack, or pthread_attr_setstack without causing other threads to crash if they were in the middle of shadow stack maintenance we can probably simplify this proposal, although I need to think more about what's possible.
Aside from concerns about disabling over all the threads in the process (which should be solvable if annoying) this would be incompatible with policies which prevent disabling of shadow stacks, and it feels like it might end up being a gadget people could use which will concern some people. There's a tension here between compatibility and the security applications of these features.