[PATCH v2 2/3] nptl: Add libc allocated shadow stack for new threads
Florian Weimer
fweimer@redhat.com
Mon Sep 8 12:14:34 GMT 2025
* Florian Weimer:
> * Mark Brown:
>
>> On Fri, Sep 05, 2025 at 02:22:46PM -0300, Adhemerval Zanella Netto wrote:
>>
>>> So what is the advantage of extending clone3 to accept a map_shadow_stack
>>> stack if the idea is to not allow user re-use the allocated shadow guard
>>> region and forcing it to always deallocate it after thread finishes?
>>
>> It is possible to switch between shadow stacks at runtime with no kernel
>> intervention, if a userspace is doing that then there is no guarantee
>> that the shadow stack in use at the time the thread exits is the same
>> one that the thread was started with. Potentially a thread will be
>> started with a stack that was previously in use in another context. You
>> either end up with userspace having to deallocate stacks when they're
>> finished with or having the kernel always allocate a stack and userspace
>> pivot off that if it wants something else.
>
> 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). So the regular stack is always the same as the original
> stack. Due to the unwinding, the shadow stack does not necessarily have
> to be the same because we never return from a frame that already existed
> when pthread_exit/pthread_cancel were called. On the other hand, we use
> a generic mechanism (either setjmp or DWARF unwinding) which supports
> that. I expect that either approach will switch back the shadow stack
> to its original value, too.
Correction: on x86-64, we do not switch shadow stacks for some
complicated reason, but we could restore it before we make the exit
system call (from the function that is called from clone). Restoring on
intermediate frames is tricky (almost impossible).
Thanks,
Florian
More information about the Libc-alpha
mailing list