On Wed, Jun 21, 2023 at 6:07 PM Edgecombe, Rick P <rick.p.edgecombe@xxxxxxxxx> wrote: > > On Wed, 2023-06-21 at 16:15 -0700, Rick Edgecombe wrote: > > On Wed, 2023-06-21 at 16:05 -0700, H.J. Lu wrote: > > > > Which makes me think if we did want to make a more compatible > > > > longjmp() > > > > a better the way to do it might be an arch_prctl that emits a > > > > token > > > > at > > > > the current SSP. This would be loosening up the security somewhat > > > > (have > > > > to be an opt-in), but less so then enabling WRSS. But it would > > > > also > > > > be > > > > way simpler, work for all cases (I think), and be faster (maybe?) > > > > than > > > > INCSSPing through a bunch of stacks. > > > > > > Since longjmp isn't required to be called after setjmp, leaving a > > > restore > > > token doesn't work when longjmp isn't called. > > > > Oh good point. Hmm. > > Just had a quick chat with HJ on this. It seems like it *might* be able > to made to work. How it would go is setjmp() could act as a wrapper by > calling it's own return address (the function that called setjmp()). > This would mean in the case of longjmp() not being called, control flow > would return through setjmp() before returning from the calling method. It may not work since we can't tell if RAX (return value) is set by longjmp or function return. > This would allow libc to do a RSTORSSP when returning though setjmp() > in the non-shadow stack case, and essentially skip over the kernel > placed restore token, and then return from setjmp() like normal. In the > case of longjmp() being called, it could RSTORSSP directly to the > token, and then return from setjmp(). > > Another option could be getting the compilers help to do the RSTORSSP > in the case of longjmp() not being called. Apparently compilers are > aware of setjmp() and already do special things around it (makes sense > I guess, but news to me). > > And also, this all would actually work with IBT, because the compiler > knows already to add an endbr at that point right after setjmp(). > > I think neither of us were ready to bet on it, but thought maybe it > could work. And even if it works it's much more complicated than I > first thought, so I don't like it as much. It's also unclear what a > change like that would mean for security. > > As for unwinding through the existing swapcontext() placed restore > tokens, the problem was as assumed - that it's difficult to find them. > Even considering brute force options like doing manual searches for a > nearby token to use turned up edge cases pretty quick. So I think that > kind of leaves us where we were originally, with no known solutions > that would require breaking kernel ABI changes. > > > Are you interested in helping get longjmp() from a ucontext stack > working for shadow stack? One other thing that came up in the > conversation was that while it is known that some apps are doing this, > there are no tests for mixing longjmp and ucontext in glibc. So we may > not know which combinations of mixing them together even work in the > non-shadow stack case. > > It could be useful to add some tests for this to glibc and we could get > some clarity on what behaviors shadow stack would actually need to > support. -- H.J.