From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb32.google.com (mail-yb1-xb32.google.com [IPv6:2607:f8b0:4864:20::b32]) by sourceware.org (Postfix) with ESMTPS id 367DB3858D37 for ; Thu, 21 Dec 2023 19:07:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 367DB3858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 367DB3858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b32 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703185664; cv=none; b=BQRQzYj9mBuYHjmhAelbTlZi9gUlT+itEc+eXaz3IXYhUBBM6+T9LMhe4vCQRtGMwgUi90F1xS/e02ps+VTwkqmy8kAD7G2ZfVj/vapwU5UFts8bAFOWDoZ7r1G0Lzl44mMOPR2ueLkti6wmlVDgTzm7G2WUBuX7eMkr3G0js2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703185664; c=relaxed/simple; bh=Kz1nOLMmXMBDLroOb3XSuhg0/dB+PimbCG5wiFZtOZ8=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=APZ6gtLT8BFggAGfCNxD82LBbDRr8qiJ8mhebfdOUUnDHSeC3iYgu4YPglO+oUN+MlVJFJljKqdREv+Gg+rubGptUBUwf2hdLt/FCfvaFQRDN815WrUEr+ha8xAIOEaovGdV/deH2eH0IIwjMdTTi7gwG/OxKAGBOGQN4q5lGa8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-yb1-xb32.google.com with SMTP id 3f1490d57ef6-dbd73cc1e52so1089547276.0 for ; Thu, 21 Dec 2023 11:07:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1703185659; x=1703790459; darn=sourceware.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=FwW1Wd+P3ct1MgkRs6uhDI2xUPUxDJrSWbwF/xeP5Es=; b=RHtp5dgVu6tMDu/DdqmvgjH72z0CPkid7sMKBmLcH76K+2pFD9X0JhlRB60Ah3YMub XWmhLPvZ7vtmqThyOFEop2b+JGUgSOkrY+NHVo/8mi0oi6tSKeToKHzgwVQHBLqdH0GB ms5cGR+kRRqjXGQj8SQGqhiBgKiNo0HrXopM7HUPb77Ym3+2xetGCbZOVXigrsGOYTvY yB5bXTmcikGjbFwvzOK3fkjzmqRHC7IOZX3RpILH3bf41Zw+n/SOw6h6R84vK7wXen6d zqKgvnBsC6mschoROiNZbQsF/dG7etNs5QO1TUZ/4oULUgi7Ia6mTdNd50BLXYUKQi80 hANw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703185659; x=1703790459; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FwW1Wd+P3ct1MgkRs6uhDI2xUPUxDJrSWbwF/xeP5Es=; b=Xy9LtfxASTnPPI/58KsamOY8q6rQRy3nL+9Sc2/3LEwqH9Od1asnNhPOme/e5Cl6hL 8hDIt14xbRXdJOIRK+gsF1AYepD9JidJe+W8TWseq/NNwvjNa1P/X4B2t5m1p2PUEScJ CZY/LF56e737nyRYcdHg2PLWPeNUsmL/nyCJbgmmI8GOBJB2qOJ4wbtCW1F44CIS54nO F82CzzNz2sOfVRSd+iobhMIZKH0Q4q6M88QZWLJqJSny1zu5F3cNdP/I/z3hvKmgEp+j 8CACT9lExsd61RnH6lP01JmR2U3tk8xUOVl+NMQVHYoYhzdBvk4zMfAdBdB99fBAWwA5 h26A== X-Gm-Message-State: AOJu0YxDaA1ctuNiEDJg4tCIhsCN7NQAqVaeC0JB3W9CpE8vFFQY0Kyw x1NEZcMv3kgDhlIb9PZvUvCxhh2G4pv6UH6xfkY= X-Google-Smtp-Source: AGHT+IFnvlAbwxexO0XXdgxpVtgT0TmHDYx1oUjoPb5yDQr55SDTXPwABxKhgKuF5+sOFomoWMmJdGpXTRhmEB41u04= X-Received: by 2002:a25:d883:0:b0:dbd:c1d7:2dfc with SMTP id p125-20020a25d883000000b00dbdc1d72dfcmr219496ybg.18.1703185658730; Thu, 21 Dec 2023 11:07:38 -0800 (PST) MIME-Version: 1.0 References: <20231219160740.3079330-1-hjl.tools@gmail.com> <20231219160740.3079330-4-hjl.tools@gmail.com> In-Reply-To: From: "H.J. Lu" Date: Thu, 21 Dec 2023 11:07:02 -0800 Message-ID: Subject: Re: [PATCH v3 3/9] x86/cet: Sync with Linux kernel 6.6 shadow stack interface To: Noah Goldstein Cc: libc-alpha@sourceware.org, rick.p.edgecombe@intel.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-3021.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, Dec 21, 2023 at 11:01=E2=80=AFAM Noah Goldstein wrote: > > On Wed, Dec 20, 2023 at 1:06=E2=80=AFPM H.J. Lu wro= te: > > > > On Wed, Dec 20, 2023 at 12:53=E2=80=AFPM Noah Goldstein wrote: > > > > > > On Tue, Dec 19, 2023 at 8:08=E2=80=AFAM H.J. Lu = wrote: > > > > > > > > Sync with Linux kernel 6.6 shadow stack interface. Since only x86-= 64 is > > > > supported, i386 shadow stack codes are unchanged and CET shouldn't = be > > > > enabled for i386. > > > > > > > > 1. When the shadow stack base in TCB is unset, the default shadow s= tack > > > > is in use. Use the current shadow stack pointer as the marker for = the > > > > default shadow stack. It is used to identify if the current shadow = stack > > > > is the same as the target shadow stack when switching ucontexts. I= f yes, > > > > INCSSP will be used to unwind shadow stack. Otherwise, shadow stac= k > > > > restore token will be used. > > > > 2. Allocate shadow stack with the map_shadow_stack syscall. Since = there > > > > is no function to explicitly release ucontext, there is no place to > > > > release shadow stack allocated by map_shadow_stack in ucontext func= tions. > > > > Such shadow stacks will be leaked. > > > > 3. Rename arch_prctl CET commands to ARCH_SHSTK_XXX. > > > > 4. Rewrite the CET control functions with the current kernel shadow= stack > > > > interface. > > > > > > > > Since CET is no longer enabled by kernel, a separate patch will ena= ble > > > > shadow stack during startup. > > > > --- > > > > sysdeps/unix/sysv/linux/x86/Makefile | 1 + > > > > .../sysv/linux/x86/allocate-shadow-stack.c | 62 +++++++++++++++= ++++ > > > > .../sysv/linux/x86/allocate-shadow-stack.h | 27 ++++++++ > > > > sysdeps/unix/sysv/linux/x86/bits/mman.h | 5 ++ > > > > sysdeps/unix/sysv/linux/x86/cpu-features.c | 13 ++-- > > > > sysdeps/unix/sysv/linux/x86/dl-cet.h | 16 +++-- > > > > .../unix/sysv/linux/x86/include/asm/prctl.h | 37 +++++------ > > > > .../sysv/linux/x86/tst-cet-setcontext-1.c | 17 +++-- > > > > .../unix/sysv/linux/x86_64/__start_context.S | 38 +++--------- > > > > sysdeps/unix/sysv/linux/x86_64/getcontext.S | 30 ++------- > > > > sysdeps/unix/sysv/linux/x86_64/makecontext.c | 29 +++++---- > > > > sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 22 ++----- > > > > sysdeps/x86/cpu-features.c | 15 +++-- > > > > sysdeps/x86/dl-cet.c | 2 +- > > > > sysdeps/x86_64/nptl/tls.h | 2 +- > > > > 15 files changed, 184 insertions(+), 132 deletions(-) > > > > create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-sta= ck.c > > > > create mode 100644 sysdeps/unix/sysv/linux/x86/allocate-shadow-sta= ck.h > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sy= sv/linux/x86/Makefile > > > > index 9dfdd689a9..ed0d6500b9 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/Makefile > > > > +++ b/sysdeps/unix/sysv/linux/x86/Makefile > > > > @@ -44,6 +44,7 @@ CFLAGS-tst-cet-vfork-1.c +=3D -mshstk > > > > endif > > > > > > > > ifeq ($(subdir),stdlib) > > > > +sysdep_routines +=3D allocate-shadow-stack > > > > tests +=3D tst-cet-setcontext-1 > > > > CFLAGS-tst-cet-setcontext-1.c +=3D -mshstk > > > > endif > > > > diff --git a/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c b/= sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c > > > > new file mode 100644 > > > > index 0000000000..d7938b6ea9 > > > > --- /dev/null > > > > +++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.c > > > > @@ -0,0 +1,62 @@ > > > > +/* Helper function to allocate shadow stack. > > > > + Copyright (C) 2023 Free Software Foundation, Inc. > > > > + This file is part of the GNU C Library. > > > > + > > > > + The GNU C Library is free software; you can redistribute it and= /or > > > > + modify it under the terms of the GNU Lesser General Public > > > > + License as published by the Free Software Foundation; either > > > > + version 2.1 of the License, or (at your option) any later versi= on. > > > > + > > > > + The GNU C Library is distributed in the hope that it will be us= eful, > > > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the G= NU > > > > + Lesser General Public License for more details. > > > > + > > > > + You should have received a copy of the GNU Lesser General Publi= c > > > > + License along with the GNU C Library; if not, see > > > > + . */ > > > > + > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > + > > > > +/* NB: This can be treated as a syscall by caller. */ > > > > + > > > > +#ifndef __x86_64__ > > > > +__attribute__ ((regparm (2))) > > > can you just add inl assembly constraints instead of this? > > > > This tells the compiler to pass parameters in registers instead of > > on stack for i386. Assembly constraints don't apply here. > > > > > > +#endif > > > > +long int > > > > +__allocate_shadow_stack (size_t stack_size, > > > > + shadow_stack_size_t *child_stack) > > > > +{ > > > > +#ifdef __NR_map_shadow_stack > > > > + size_t shadow_stack_size > > > > + =3D stack_size >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT; > > > > + /* Align shadow stack to 8 bytes. */ > > > > + shadow_stack_size =3D ALIGN_UP (shadow_stack_size, 8); > > > > + /* Since sigaltstack shares shadow stack with the current contex= t in > > > > + the thread, add extra 20 stack frames in shadow stack for sig= nal > > > > + handlers. */ > > > > +# ifdef __x86_64__ > > > > + shadow_stack_size +=3D 20 * 8; > > > > +# else > > > > + shadow_stack_size +=3D 20 * 4; > > > > +# endif > > > > + void *shadow_stack =3D (void *)INLINE_SYSCALL_CALL > > > > + (map_shadow_stack, NULL, shadow_stack_size, SHADOW_STACK_SET_T= OKEN); > > > > + /* Report the map_shadow_stack error. */ > > > > + if (shadow_stack =3D=3D MAP_FAILED) > > > > + return -errno; > > > > + > > > > + /* Save the shadow stack base and size on child stack. */ > > > > + child_stack[0] =3D (uintptr_t) shadow_stack; > > > > + child_stack[1] =3D shadow_stack_size; > > > > + > > > > + return 0; > > > > +#else > > > > + return -ENOSYS; > > > > +#endif > > > > +} > > > > diff --git a/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h b/= sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h > > > > new file mode 100644 > > > > index 0000000000..834373e0d3 > > > > --- /dev/null > > > > +++ b/sysdeps/unix/sysv/linux/x86/allocate-shadow-stack.h > > > > @@ -0,0 +1,27 @@ > > > > +/* Helper function to allocate shadow stack. > > > > + Copyright (C) 2023 Free Software Foundation, Inc. > > > > + This file is part of the GNU C Library. > > > > + > > > > + The GNU C Library is free software; you can redistribute it and= /or > > > > + modify it under the terms of the GNU Lesser General Public > > > > + License as published by the Free Software Foundation; either > > > > + version 2.1 of the License, or (at your option) any later versi= on. > > > > + > > > > + The GNU C Library is distributed in the hope that it will be us= eful, > > > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the G= NU > > > > + Lesser General Public License for more details. > > > > + > > > > + You should have received a copy of the GNU Lesser General Publi= c > > > > + License along with the GNU C Library; if not, see > > > > + . */ > > > > + > > > > +#include > > > > + > > > > +typedef __typeof (((ucontext_t *) 0)->__ssp[0]) shadow_stack_size_= t; > > > > + > > > > +extern long int __allocate_shadow_stack (size_t, shadow_stack_size= _t *) > > > > +#ifndef __x86_64__ > > > > + __attribute__ ((regparm (2))) > > > > +#endif > > > > + attribute_hidden; > > > > diff --git a/sysdeps/unix/sysv/linux/x86/bits/mman.h b/sysdeps/unix= /sysv/linux/x86/bits/mman.h > > > > index 3d356e86a0..221f7c82bd 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/bits/mman.h > > > > +++ b/sysdeps/unix/sysv/linux/x86/bits/mman.h > > > > @@ -27,6 +27,11 @@ > > > > #define MAP_32BIT 0x40 /* Only give out 32-bit add= resses. */ > > > > #define MAP_ABOVE4G 0x80 /* Only map above 4GB. */ > > > > > > > > +#ifdef __USE_MISC > > > > +/* Set up a restore token in the newly allocatd shadow stack */ > > > allocatd -> allocated > > > > Fixed. > > > > > > +# define SHADOW_STACK_SET_TOKEN 0x1 > > > > +#endif > > > > + > > > > #include > > > > > > > > /* Include generic Linux declarations. */ > > > > diff --git a/sysdeps/unix/sysv/linux/x86/cpu-features.c b/sysdeps/u= nix/sysv/linux/x86/cpu-features.c > > > > index 41e7600668..0e6e2bf855 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/cpu-features.c > > > > +++ b/sysdeps/unix/sysv/linux/x86/cpu-features.c > > > > @@ -23,10 +23,15 @@ > > > > static inline int __attribute__ ((always_inline)) > > > > get_cet_status (void) > > > > { > > > > - unsigned long long cet_status[3]; > > > > - if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_STATUS, cet_stat= us) =3D=3D 0) > > > > - return cet_status[0]; > > > > - return 0; > > > > + unsigned long long kernel_feature; > > > > + unsigned int status =3D 0; > > > > + if (INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_STATUS, > > > > + &kernel_feature) =3D=3D 0) > > > > + { > > > > + if ((kernel_feature & ARCH_SHSTK_SHSTK) !=3D 0) > > > > + status =3D GNU_PROPERTY_X86_FEATURE_1_SHSTK; > > > > + } > > > > + return status; > > > > } > > > > > > > > # ifndef SHARED > > > > diff --git a/sysdeps/unix/sysv/linux/x86/dl-cet.h b/sysdeps/unix/sy= sv/linux/x86/dl-cet.h > > > > index c885bf1323..da220ac627 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/dl-cet.h > > > > +++ b/sysdeps/unix/sysv/linux/x86/dl-cet.h > > > > @@ -21,12 +21,20 @@ > > > > static inline int __attribute__ ((always_inline)) > > > > dl_cet_disable_cet (unsigned int cet_feature) > > > > { > > > > - return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_DISABLE= , > > > > - cet_feature); > > > > + if (cet_feature !=3D GNU_PROPERTY_X86_FEATURE_1_SHSTK) > > > > + return -1; > > > > + long long int kernel_feature =3D ARCH_SHSTK_SHSTK; > > > > + return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_DISAB= LE, > > > > + kernel_feature); > > > > } > > > > > > > > static inline int __attribute__ ((always_inline)) > > > > -dl_cet_lock_cet (void) > > > > +dl_cet_lock_cet (unsigned int cet_feature) > > > > { > > > > - return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_CET_LOCK, 0= ); > > > > + if (cet_feature !=3D GNU_PROPERTY_X86_FEATURE_1_SHSTK) > > > > + return -1; > > > > + /* Lock all SHSTK features. */ > > > > + long long int kernel_feature =3D -1; > > > > + return (int) INTERNAL_SYSCALL_CALL (arch_prctl, ARCH_SHSTK_LOCK, > > > > + kernel_feature); > > > > } > > > > diff --git a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h b/sysd= eps/unix/sysv/linux/x86/include/asm/prctl.h > > > > index 45ad0b052f..2f511321ad 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h > > > > +++ b/sysdeps/unix/sysv/linux/x86/include/asm/prctl.h > > > > @@ -4,24 +4,19 @@ > > > > > > > > #include_next > > > > > > > > -#ifndef ARCH_CET_STATUS > > > > -/* CET features: > > > > - IBT: GNU_PROPERTY_X86_FEATURE_1_IBT > > > > - SHSTK: GNU_PROPERTY_X86_FEATURE_1_SHSTK > > > > - */ > > > > -/* Return CET features in unsigned long long *addr: > > > > - features: addr[0]. > > > > - shadow stack base address: addr[1]. > > > > - shadow stack size: addr[2]. > > > > - */ > > > > -# define ARCH_CET_STATUS 0x3001 > > > > -/* Disable CET features in unsigned int features. */ > > > > -# define ARCH_CET_DISABLE 0x3002 > > > > -/* Lock all CET features. */ > > > > -# define ARCH_CET_LOCK 0x3003 > > > Are these not already part of the API? > > > > Glibc defines these constants so that glibc can be > > built against older kernel header files which don't > > define them. > can we remove ARCH_CET_* then? Or could people > be relying on them being defined. They can be removed only when kernel 6.6 is required to build glibc. > > > > > > -/* Allocate a new shadow stack with unsigned long long *addr: > > > > - IN: requested shadow stack size: *addr. > > > > - OUT: allocated shadow stack address: *addr. > > > > - */ > > > > -# define ARCH_CET_ALLOC_SHSTK 0x3004 > > > > -#endif /* ARCH_CET_STATUS */ > > > > +#ifndef ARCH_SHSTK_ENABLE > > > > +/* Enable SHSTK features in unsigned long int features. */ > > > > +# define ARCH_SHSTK_ENABLE 0x5001 > > > > +/* Disable SHSTK features in unsigned long int features. */ > > > > +# define ARCH_SHSTK_DISABLE 0x5002 > > > > +/* Lock SHSTK features in unsigned long int features. */ > > > > +# define ARCH_SHSTK_LOCK 0x5003 > > > > +/* Unlock SHSTK features in unsigned long int features. */ > > > > +# define ARCH_SHSTK_UNLOCK 0x5004 > > > > +/* Return SHSTK features in unsigned long int features. */ > > > > +# define ARCH_SHSTK_STATUS 0x5005 > > > > + > > > > +/* ARCH_SHSTK_ features bits */ > > > > +# define ARCH_SHSTK_SHSTK 0x1 > > > > +# define ARCH_SHSTK_WRSS 0x2 > > > > +#endif > > > > diff --git a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c b/s= ysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c > > > > index 837a9fd0eb..2ea66c803b 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c > > > > +++ b/sysdeps/unix/sysv/linux/x86/tst-cet-setcontext-1.c > > > > @@ -87,15 +87,14 @@ do_test (void) > > > > ctx[4].uc_link =3D &ctx[0]; > > > > makecontext (&ctx[4], (void (*) (void)) f1, 0); > > > > > > > > - /* NB: When shadow stack is enabled, makecontext calls arch_prct= l > > > > - with ARCH_CET_ALLOC_SHSTK to allocate a new shadow stack whic= h > > > > - can be unmapped. The base address and size of the new shadow > > > > - stack are returned in __ssp[1] and __ssp[2]. makecontext is > > > > - called for CTX1, CTX3 and CTX4. But only CTX1 is used. New > > > > - shadow stacks are allocated in the order of CTX3, CTX1, CTX4. > > > > - It is very likely that CTX1's shadow stack is placed between > > > > - CTX3 and CTX4. We munmap CTX3's and CTX4's shadow stacks to > > > > - create gaps above and below CTX1's shadow stack. We check > > > > + /* NB: When shadow stack is enabled, makecontext calls map_shado= w_stack > > > > + to allocate a new shadow stack which can be unmapped. The ba= se > > > > + address and size of the new shadow stack are returned in __ss= p[1] > > > > + and __ssp[2]. makecontext is called for CTX1, CTX3 and CTX4.= But > > > > + only CTX1 is used. New shadow stacks are allocated in the or= der > > > > + of CTX3, CTX1, CTX4. It is very likely that CTX1's shadow st= ack is > > > > + placed between CTX3 and CTX4. We munmap CTX3's and CTX4's sh= adow > > > > + stacks to create gaps above and below CTX1's shadow stack. W= e check > > > > that setcontext CTX1 works correctly in this case. */ > > > > if (_get_ssp () !=3D 0) > > > > { > > > > diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sys= deps/unix/sysv/linux/x86_64/__start_context.S > > > > index f6436dd6bb..ae04203c90 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86_64/__start_context.S > > > > +++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S > > > > @@ -24,20 +24,14 @@ > > > > /* Use CALL to push __start_context onto the new stack as well as = the new > > > > shadow stack. RDI points to ucontext: > > > > Incoming: > > > > - __ssp[0]: The original caller's shadow stack pointer. > > > > - __ssp[1]: The size of the new shadow stack. > > > > - __ssp[2]: The size of the new shadow stack. > > > > - Outgoing: > > > > __ssp[0]: The new shadow stack pointer. > > > > __ssp[1]: The base address of the new shadow stack. > > > > __ssp[2]: The size of the new shadow stack. > > > > */ > > > > > > > > ENTRY(__push___start_context) > > > below in __start_constext rbx is used. Does it need to be saved/resto= red? > > > > RBX is used to pass the address of next context. See comments in > > makecontext.c. > > > > > > - /* Save the pointer to ucontext. */ > > > > - movq %rdi, %r9 > > > > /* Get the original shadow stack pointer. */ > > > > - rdsspq %r8 > > > > + rdsspq %rcx > > > > /* Save the original stack pointer. */ > > > > movq %rsp, %rdx > > > > /* Load the top of the new stack into RSI. */ > > > > @@ -45,24 +39,12 @@ ENTRY(__push___start_context) > > > > /* Add 8 bytes to RSI since CALL will push the 8-byte retur= n > > > > address onto stack. */ > > > > leaq 8(%rsi), %rsp > > > > - /* Allocate the new shadow stack. The size of the new shad= ow > > > > - stack is passed in __ssp[1]. */ > > > > - lea (oSSP + 8)(%rdi), %RSI_LP > > > > - movl $ARCH_CET_ALLOC_SHSTK, %edi > > > > - movl $__NR_arch_prctl, %eax > > > > - /* The new shadow stack base is returned in __ssp[1]. */ > > > > - syscall > > > > - testq %rax, %rax > > > > - jne L(hlt) /* This should never happen. */ > > > > - > > > > - /* Get the size of the new shadow stack. */ > > > > - movq 8(%rsi), %rdi > > > > - > > > > - /* Get the base address of the new shadow stack. */ > > > > - movq (%rsi), %rsi > > > > - > > > > + /* The size of the new shadow stack is stored in __ssp[2]. = */ > > > > + mov (oSSP + 16)(%rdi), %RSI_LP > > > > + /* The new shadow stack base is stored in __ssp[1]. */ > > > > + mov (oSSP + 8)(%rdi), %RAX_LP > > > > /* Use the restore stoken to restore the new shadow stack. = */ > > > > - rstorssp -8(%rsi, %rdi) > > > > + rstorssp -8(%rax, %rsi) > > > > > > > > /* Save the restore token on the original shadow stack. */ > > > > saveprevssp > > > > @@ -73,18 +55,12 @@ ENTRY(__push___start_context) > > > > jmp __start_context > > > > 1: > > > > > > > > - /* Get the new shadow stack pointer. */ > > > > - rdsspq %rdi > > > > - > > > > /* Use the restore stoken to restore the original shadow st= ack. */ > > > > - rstorssp -8(%r8) > > > > + rstorssp -8(%rcx) > > > > > > > > /* Save the restore token on the new shadow stack. */ > > > > saveprevssp > > > > > > > > - /* Store the new shadow stack pointer in __ssp[0]. */ > > > > - movq %rdi, oSSP(%r9) > > > > - > > > > /* Restore the original stack. */ > > > > mov %rdx, %rsp > > > > ret > > > > diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/= unix/sysv/linux/x86_64/getcontext.S > > > > index a00e2f6290..71f3802dca 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S > > > > +++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S > > > > @@ -58,35 +58,15 @@ ENTRY(__getcontext) > > > > testl $X86_FEATURE_1_SHSTK, %fs:FEATURE_1_OFFSET > > > > jz L(no_shstk) > > > > > > > > - /* Save RDI in RDX which won't be clobbered by syscall. */ > > > > - movq %rdi, %rdx > > > > - > > > > xorl %eax, %eax > > > > cmpq %fs:SSP_BASE_OFFSET, %rax > > > > jnz L(shadow_stack_bound_recorded) > > > > > > > > - /* Get the base address and size of the default shadow stac= k > > > > - which must be the current shadow stack since nothing has > > > > - been recorded yet. */ > > > > - sub $24, %RSP_LP > > > > - mov %RSP_LP, %RSI_LP > > > > - movl $ARCH_CET_STATUS, %edi > > > > - movl $__NR_arch_prctl, %eax > > > > - syscall > > > > - testq %rax, %rax > > > > - jz L(continue_no_err) > > > > - > > > > - /* This should never happen. */ > > > > - hlt > > > > - > > > > -L(continue_no_err): > > > > - /* Record the base of the current shadow stack. */ > > > > - movq 8(%rsp), %rax > > > > + /* When the shadow stack base is unset, the default shadow > > > > + stack is in use. Use the current shadow stack pointer > > > > + as the marker for the default shadow stack. */ > > > > + rdsspq %rax > > > > movq %rax, %fs:SSP_BASE_OFFSET > > > > - add $24, %RSP_LP > > > > - > > > > - /* Restore RDI. */ > > > > - movq %rdx, %rdi > > > > > > > > L(shadow_stack_bound_recorded): > > > > /* Get the current shadow stack pointer. */ > > > > @@ -94,7 +74,7 @@ L(shadow_stack_bound_recorded): > > > > /* NB: Save the caller's shadow stack so that we can jump b= ack > > > > to the caller directly. */ > > > > addq $8, %rax > > > > - movq %rax, oSSP(%rdx) > > > > + movq %rax, oSSP(%rdi) > > > > > > > > /* Save the current shadow stack base in ucontext. */ > > > > movq %fs:SSP_BASE_OFFSET, %rax > > > > diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps= /unix/sysv/linux/x86_64/makecontext.c > > > > index de9e03eb81..788b730132 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c > > > > +++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c > > > > @@ -24,6 +24,8 @@ > > > > # include > > > > # include > > > > # include > > > > +# include > > > > +# include > > > > #endif > > > > > > > > #include "ucontext_i.h" > > > > @@ -88,23 +90,24 @@ __makecontext (ucontext_t *ucp, void (*func) (v= oid), int argc, ...) > > > > if ((feature_1 & X86_FEATURE_1_SHSTK) !=3D 0) > > > > { > > > > /* Shadow stack is enabled. We need to allocate a new shado= w > > > > - stack. */ > > > > - unsigned long ssp_size =3D (((uintptr_t) sp > > > > - - (uintptr_t) ucp->uc_stack.ss_sp) > > > > - >> STACK_SIZE_TO_SHADOW_STACK_SIZE_= SHIFT); > > > > - /* Align shadow stack to 8 bytes. */ > > > > - ssp_size =3D ALIGN_UP (ssp_size, 8); > > > > - > > > > - ucp->__ssp[1] =3D ssp_size; > > > > - ucp->__ssp[2] =3D ssp_size; > > > > - > > > > - /* Call __push___start_context to allocate a new shadow stac= k, > > > > - push __start_context onto the new stack as well as the new > > > > - shadow stack. NB: After __push___start_context returns, > > > > + stack. NB: > > > > ucp->__ssp[0]: The new shadow stack pointer. > > > > ucp->__ssp[1]: The base address of the new shadow stack. > > > > ucp->__ssp[2]: The size of the new shadow stack. > > > > */ > > > > + long int ret > > > > + =3D __allocate_shadow_stack (((uintptr_t) sp > > > > + - (uintptr_t) ucp->uc_stack.ss_= sp), > > > > + &ucp->__ssp[1]); > > > > + if (ret !=3D 0) > > > > + { > > > > + /* FIXME: What should we do? */ > > > > + abort (); > > > > + } > > > > + > > > > + ucp->__ssp[0] =3D ucp->__ssp[1] + ucp->__ssp[2] - 8; > > > > + /* Call __push___start_context to push __start_context onto = the new > > > > + stack as well as the new shadow stack. */ > > > > __push___start_context (ucp); > > > > } > > > > else > > > > diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps= /unix/sysv/linux/x86_64/swapcontext.S > > > > index 5925752164..2f2fe9875b 100644 > > > > --- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S > > > > +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S > > > > @@ -109,25 +109,11 @@ ENTRY(__swapcontext) > > > > cmpq %fs:SSP_BASE_OFFSET, %rax > > > > jnz L(shadow_stack_bound_recorded) > > > > > > > > - /* Get the base address and size of the default shadow stac= k > > > > - which must be the current shadow stack since nothing has > > > > - been recorded yet. */ > > > > - sub $24, %RSP_LP > > > > - mov %RSP_LP, %RSI_LP > > > > - movl $ARCH_CET_STATUS, %edi > > > > - movl $__NR_arch_prctl, %eax > > > > - syscall > > > > - testq %rax, %rax > > > > - jz L(continue_no_err) > > > > - > > > > - /* This should never happen. */ > > > > - hlt > > > > - > > > > -L(continue_no_err): > > > > - /* Record the base of the current shadow stack. */ > > > > - movq 8(%rsp), %rax > > > > + /* When the shadow stack base is unset, the default shadow > > > > + stack is in use. Use the current shadow stack pointer > > > > + as the marker for the default shadow stack. */ > > > > + rdsspq %rax > > > > movq %rax, %fs:SSP_BASE_OFFSET > > > > - add $24, %RSP_LP > > > > > > > > L(shadow_stack_bound_recorded): > > > > /* If we unwind the stack, we can't undo stack unwinding. = Just > > > > diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.= c > > > > index 0bf923d48b..f180f0d9a4 100644 > > > > --- a/sysdeps/x86/cpu-features.c > > > > +++ b/sysdeps/x86/cpu-features.c > > > > @@ -1121,8 +1121,9 @@ no_cpuid: > > > > > > > > # ifndef SHARED > > > > /* Check if IBT and SHSTK are enabled by kernel. */ > > > > - if ((cet_status & GNU_PROPERTY_X86_FEATURE_1_IBT) > > > > - || (cet_status & GNU_PROPERTY_X86_FEATURE_1_SHSTK)) > > > > + if ((cet_status > > > > + & (GNU_PROPERTY_X86_FEATURE_1_IBT > > > > + | GNU_PROPERTY_X86_FEATURE_1_SHSTK))) > > > > { > > > > /* Disable IBT and/or SHSTK if they are enabled by kernel= , but > > > > disabled by environment variable: > > > > @@ -1131,9 +1132,11 @@ no_cpuid: > > > > */ > > > > unsigned int cet_feature =3D 0; > > > > if (!CPU_FEATURE_USABLE (IBT)) > > > > - cet_feature |=3D GNU_PROPERTY_X86_FEATURE_1_IBT; > > > > + cet_feature |=3D (cet_status > > > > + & GNU_PROPERTY_X86_FEATURE_1_IBT); > > > > if (!CPU_FEATURE_USABLE (SHSTK)) > > > > - cet_feature |=3D GNU_PROPERTY_X86_FEATURE_1_SHSTK; > > > > + cet_feature |=3D (cet_status > > > > + & GNU_PROPERTY_X86_FEATURE_1_SHSTK); > > > > > > > > if (cet_feature) > > > > { > > > > @@ -1148,7 +1151,9 @@ no_cpuid: > > > > lock CET if IBT or SHSTK is enabled permissively. */ > > > > if (GL(dl_x86_feature_control).ibt !=3D cet_permissive > > > > && GL(dl_x86_feature_control).shstk !=3D cet_permissi= ve) > > > > - dl_cet_lock_cet (); > > > > + dl_cet_lock_cet (GL(dl_x86_feature_1) > > > > + & (GNU_PROPERTY_X86_FEATURE_1_IBT > > > > + | GNU_PROPERTY_X86_FEATURE_1_SHSTK)= ); > > > > } > > > > # endif > > > > } > > > > diff --git a/sysdeps/x86/dl-cet.c b/sysdeps/x86/dl-cet.c > > > > index 67c51ee8c2..8b911fd931 100644 > > > > --- a/sysdeps/x86/dl-cet.c > > > > +++ b/sysdeps/x86/dl-cet.c > > > > @@ -201,7 +201,7 @@ dl_cet_check_startup (struct link_map *m, struc= t dl_cet_info *info) > > > > feature_1_lock |=3D GNU_PROPERTY_X86_FEATURE_1_SHSTK; > > > > > > > > if (feature_1_lock !=3D 0 > > > > - && dl_cet_lock_cet () !=3D 0) > > > > + && dl_cet_lock_cet (feature_1_lock) !=3D 0) > > > > _dl_fatal_printf ("%s: can't lock CET\n", info->program); > > > > } > > > > > > > > diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h > > > > index 1403f939f7..4bcc2552a1 100644 > > > > --- a/sysdeps/x86_64/nptl/tls.h > > > > +++ b/sysdeps/x86_64/nptl/tls.h > > > > @@ -60,7 +60,7 @@ typedef struct > > > > void *__private_tm[4]; > > > > /* GCC split stack support. */ > > > > void *__private_ss; > > > > - /* The lowest address of shadow stack, */ > > > > + /* The marker for the current shadow stack. */ > > > > unsigned long long int ssp_base; > > > > /* Must be kept even if it is no longer used by glibc since prog= rams, > > > > like AddressSanitizer, depend on the size of tcbhead_t. */ > > > > -- > > > > 2.43.0 > > > > > > > > Thanks. > > > > -- > > H.J. --=20 H.J.