On Fri, 2025-09-26 at 17:03 +0100, Mark Brown wrote:
On Fri, Sep 26, 2025 at 03:39:46PM +0000, Edgecombe, Rick P wrote:
On Fri, 2025-09-26 at 16:07 +0100, Yury Khrustalev wrote:
What do you mean by "a fuller solution from the glibc side"? A solution for re-using shadow stacks?
I mean some code or a fuller explained solution that uses this new kernel functionality. I think the scheme that Florian suggested in the thread linked above (longjmp() to the start of the stack) will have trouble if the thread pivots to a new shadow stack before exiting (e.g. ucontext).
Is that supported even without user managed stacks?
IIUC longjmp() is sometimes used to implement user level thread switching. So for non-shadow stack my understanding is that longjmp() between user level threads is supported.
For shadow stack, I think user level threads are intended to be supported. So I don't see why a thread could never exit from another shadow stack? Is that what you are asking? Maybe we need to discuss this with the glibc folks.
What I read in that thread you linked was that Florian was considering using longjmp() as a way to inherit the solution to these unwinding problems: Not sure if it helps, but glibc always calls the exit system call from the start routine, after unwinding the stack (with longjmp if necessary). https://marc.info/?l=glibc-alpha&m=175733266913483&w=2
Reading into the "...if necessary" a bit on my part. But if longjmp() doesn't work to unwind from a non-thread shadow stack, then my question would be how will glibc deal with if an app exits while on another shadow stack? Just declare shadow stack re-use is not supported with any user shadow stack pivoting? Does it need a new elf header bit then?
Again, I'm just thinking that we should vet the solution a bit more before actually adding this to the kernel. If the combined shadow stack effort eventually throws its hands up in frustration and goes with WRSS/GCSSTR for apps that want to do more advanced threading patterns, then we are already done on the kernel side.