The 06/22/2023 16:47, Edgecombe, Rick P wrote: > On Thu, 2023-06-22 at 09:27 +0100, szabolcs.nagy@xxxxxxx wrote: > > > [ snip ] > > > swapcontext is currently *not* supported: for it to work you have to > > be able to jump *back* into the signal handler, which does not work > > if > > the swapcontext target is on the original thread stack (instead of > > say a makecontext stack). > > > > jumping back can only be supported if alt stack can be paired with > > an alt shadow stack. > > > > unwinding across a series of signal interrupts should work even > > with discontinous shstk. libgcc does not implement this which is > > a problem i think. > > I would be helpful if you could enumerate the cases you think are > important to support. I would like to see how we could support them in > the future in some mode. > > > > > > But how does the proposed token placed by the kernel on the > > > original > > > stack help this problem? The longjmp() would have to be able to > > > find > > > the location of the restore tokens somehow, which would not > > > necessarily > > > be near the setjmp() point. The signal token could even be on a > > > different shadow stack. > > > > i posted the exact longjmp code and it takes care of this case. > > I see how it works for the simple case of longjmp() from an alt shadow > stack. I would still prefer a different solution that works with the > overflow case. (probably new kernel functionality) > > But I don't see how it works for unwinding off of a ucontext stack. Or > unwinding off of an ucontext stack that was swapped to from an alt > shadow stack. why? a stack can be active or inactive (task executing on it or not), and if inactive it can be live or dead (has stack frames that can be jumped to or not). this is independent of shadow stacks: longjmp is only valid if the target is either the same active stack or an inactive live stack. (there are cases that may seem to work, but fundamentally broken and not supportable: e.g. two tasks executing on the same stack where the one above happens to not clobber frames deep enough to collide with the task below.) the proposed longjmp design works for both cases. no assumption is made about ucontext or signals other than the shadow stack for an inactive live stack ends in a restore token, which is guaranteed by the isa so we only need the kernel to do the same when it switches shadow stacks. then longjmp works by construction. the only wart is that an overflowed shadow stack is inactive dead instead of inactive live because the token cannot be added. (note that handling shstk overflow and avoiding shstk overflow during signal handling still works with alt shstk!) an alternative solution is to allow jump to inactive dead stack if that's created by a signal interrupt. for that a syscall is needed and longjmp has to detect if the target stack is dead or live. (the kernel also has to be able to tell if switching to the dead stack is valid for security reasons.) i don't know if this is doable (if we allow some hacks it's doable). unwinding across signal handlers is just a matter of having enough information at the signal frame to continue, it does not have to follow crazy jumps or weird coroutine things: that does not work without shadow stacks either. but unwind across alt stack frame should work.