Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260922180425.GR23438@brightrain.aerifal.cx>
Date: Tue, 22 Sep 2026 14:04:25 -0400
From: Rich Felker <dalias@...c.org>
To: Khosro Moeini <khosro@...edu>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH v3] x86_64: add CET shadow stack support

On Tue, Sep 22, 2026 at 01:38:19PM -0400, Khosro Moeini wrote:
> On 9/20/26 10:56 PM, Rich Felker wrote:
> > On Sun, Sep 20, 2026 at 07:33:17PM +0000, Khosro Moeini wrote:
> > > Enable CET shadow stack on x86_64 when the executable and all loaded
> > > shared objects have the GNU_PROPERTY_X86_FEATURE_1_SHSTK bit set in
> > > their .note.gnu.property note. If shadow stack is enabled for a process
> > > dlopen of an object without the shadow stack property note fails.
> > > Unlike glibc, this implementation does not check environment variables.
> > > All the changes are guarded by SHSTK_ENABLED which is set through
> > > the --enable-cet configuration option.
> > > 
> > > Signed-off-by: Khosro Moeini <khosro@...edu>
> > > ---
> > > > > Thanks for the feedback. Regarding the concerns discussed in the older
> > > > > thread:
> > > > > 
> > > > > sigaltstack: The main program and its signal handlers use the same
> > > > > shadow stack, so there won't be resource problems. Please see:
> > > > >       https://docs.kernel.org/next/x86/shstk.html#signal
> > > > 
> > > > That is exactly the problem. It breaks the property that overflow of
> > > > the normal stack cannot prevent the signal handler from running.
> > > 
> > > The size of the shadow stack is MIN(RLIMIT_STACK, 4 GB) and the shadow
> > > stack only stores return addresses. Given the 16-byte stack alignment
> > > in the x86_64 calling convention, in the extreme case where no extra
> > > stack space is used, the shadow stack would be half empty when the
> > > normal stack is overflowing. The Linux doc says:
> > > "Because the shadow stack stores only return addresses, a large shadow
> > > stack covers the condition that both the program stack and the signal
> > > alternate stack run out."
> > 
> > You mean there's RLIMIT_STACK committed for every thread?
> > 
> > Or is it not committed and crashes the process on OOM?
> 
> The kernel allocates a new shadow stack for every thread/process.
> 
> > What happens if RLIMIT_STACK is small but the thread stack size
> > selected in the pthread_attr_t is large?
> 
> Depends on how the thread is created. If via clone, RLIMIT_STACK is
> allocated and as you mentioned that might be a problem. If via clone3,
> the stack size specified in clone3 is allocated. Would it be possible to
> use clone3 in pthread_create? If using clone3 is not an option, there
> might be a way to use the map_shadow_stack syscall to allocate a new
> shadow stack of the right size.

Hmm, this sounds promising. I can't find any documentation for
map_shadow_stack though. We could probably conditionally use clone3 if
built for shadow stack, but this would need a fallback path to use
clone and disable shadow stack if clone3 is not available.

> > > > > ucontext: removed from POSIX and not supported in musl
> > > > 
> > > > That just means we don't presently have it in musl; distros are using
> > > > libucontext.
> > > 
> > > This shouldn't be an issue. If the library supports shadow stack and
> > > has the shadow stack note, then shadow stack can be safely activated.
> > > If the library does not support shadow stack it wouldn't have the
> > > shadow stack note and thus shadow stack won't be activated for programs
> > > using this library.
> > 
> > So on a system built for shadow stack by default, would someone
> > building libuconext need to explicitly pass LDFLAGS to mark it not
> > compatible?
> > 
> > Also, it sounds like you are assuming "library" means .so; that is not
> > an assumption we make. Or are there .o level markings that would cause
> > the program to link without shadow stack?
> 
> The SHSTK mark/note is at .o level and lack of it means incompatibility.
> Compilers don't mark objects by default so when building libucontext (or
> any program) extra flags must be passed to mark it as compatible. So if
> libucontext isn't explicitly marked as compatible, shadow stack won't be
> activated in both static and dynamic linking scenarios.

That sounds like it works. I was thinking of the situation where a
distro (or user's build environment for self builds) is enabling
shadow stacks by default though -- in this case, I think they'd need
to explicitly override CFLAGS to turn it off when building libucontext
or anything similar.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.