On Thu, 2026-10-08 at 21:50 +0000, Richard Patel wrote: > > How can it defeat protection? If doesn't process the shadow stack sigframe > > at > > all, leaving the SSP where ever it was originally. What am I missing? > > The selftest demonstrates that 'int $0x80' rt_sigreturn from 64-bit mode > jumps to an arbitrary %eip in the signal frame (zero-extended to %rip), \ > whereas the 'syscall' variant raises SIGSEGV if %rip is corrupt. >
It should just be restoring the SSP from the shadow stack signal frame. Perhaps you saw the syscall variant fail because it was not at the restorer. Since you are manually calling sigreturn instead of returning normally. So then it was was not at the shadow stack signal frame and the shadow stack signal check thought it was a forged SSP. And the 32 bit one succeed because there was nothing checked. But that doesn't have to do with checking EIP matches where the signal was generated? > > I don't think it matters that SSP is still at the old place. It would > only break 'ret' after sigreturn, but the problem is that the sigreturn > itself is a wild jump. > > "defeat protection" was badly worded, I just meant that the 'syscall' > path has protections that the 'int $0x80' path doesn't have, so I > thought it'd be worth fixing. > > I might be missing something, maybe SHSTK never intended to defend > against a wild sigreturn? Either way, it's not a security thing. Hmm, I guess its kind of on the line between forward edge and backwards edge. I see your point. But today setting EIP to an arbitrary point is fairly easy. But even in a future case of IBT enabled, shadow stack would still need enhancements for the normal 64 bit runtime to prevent this. In the past we discussed hashing some amount of the sigframe and putting it on the shadow stack to give some sigframe integrity. But this runs the risk of breaking apps so would need to be an opt-in enhancement.

