[PATCH v2 2/3] nptl: Add libc allocated shadow stack for new threads

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Sep 17 19:29:36 GMT 2025



On 17/09/25 14:37, Mark Brown wrote:
> On Wed, Sep 17, 2025 at 11:27:18AM -0300, Adhemerval Zanella Netto wrote:
> 
> [Your mail is a bit hard to read due to being more than 80 columns wide]
> 
>> But what is the point in adding composability (map_shadow_stack) on clone3, when the 
>> expected usage does not allow the reuse of the previously allocated shadow stack and 
>> forces the userland to manually manage and always deallocate the shadow stack when 
>> the thread finishes?
> 
> The main things are control of the stack placement and size, and the
> green threads cases.

It is not clear to me how to properly implement green-threads on top of the
glibc, since, as Florian has pointed out, we will longjmp back to initial thread
state when the threads finishes (which might leak pre-allocate shadow stack
usage).  But it also might not be real or supported usercase.

> 
>> The runtime flexibility could make sense in a runtime where green-threads are 
>> first-order primitives, where it exchanges the stack of the underlying OS threads 
>> depending on the workload. However, for the C runtime (and I believe for many other 
>> runtimes as well), and more specifically, pthread, it would be much simpler if 
>> userland could simply specify the shadow stack size. Even for C++ coroutines or other 
>> runtimes built on top of C, I believe it will require some assistance from the C
>> runtime to properly manage the shadow stack.
> 
> I think if we want to add an interface that's purely for configuring the
> stack size to use that should be separate to clone3() since that's also
> an issue for things using plain clone(), including workloads that can't
> switch to clone3() due to it not playing nicely with seccomp.

It is not clear to me how can you accomplish it without also tying the
allocation to some handler the kernel would provide (which is what 
map_shadow_stack does essentially).  

> 
> I also previously suggested that if we want to enable reuse of stacks
> after a thread has exited we should support having the kernel write a
> token to the current pointer of exiting threads (mirroring how the stack
> pivot instructions work), I didn't get any feedback on that suggestion.
> I would expect this to be gated behind a separate ABI (most likely a new
> permission on PR_SHADOW_STACK_SET_STATUS) so readily discoverable if
> added independently.

Sorry if I missed it, if the kernel can provide it I think it would
be useful.

> 
>> So, imho, the current clone3 interface for shadow stack token only adds an extra burden 
>> to the C runtime, and since it is not yet in master, perhaps we can still refine it.
> 
> I have to say it is a little surprising to have this come up almost two
> years into the review.

Perhaps because it was only recently discussed how it would be implemented in glibc?
(I do not follow lkml that clone, but maybe I should more).

Previously, when I reviewed the initial GCS work, I had the impression that the shadow 
stack was supposed to be transparently managed by the kernel through the clone3 syscall 
and that map_shadow_stack was added to manage the corner cases of setjmp calls and the 
possible usage of green-threads.

What I am trying to say is that with the current ABI, it only adds an extra burden on 
userland to manage the shadow stacks for most runtimes. However, if the defined kernel 
ABI is used, it can work out this on glibc. 

I am cc'ing Rich Felker from musl; he might add some more ideas if this interface could 
fit in a different Linux C runtime with different constraints (I am not sure if musl 
supports GCS or plans to).


More information about the Libc-alpha mailing list