public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Szabolcs Nagy <szabolcs.nagy@arm.com>
Cc: libc-alpha@sourceware.org, rick.p.edgecombe@intel.com
Subject: Re: [PATCH 11/17] x86/cet: Sync with Linux kernel 6.6 shadow stack interface
Date: Mon, 11 Dec 2023 08:44:55 -0800	[thread overview]
Message-ID: <CAMe9rOqXfs6Ow1vGNmaviS0_UopU62GUFSVNVF_o11a7SXZJSQ@mail.gmail.com> (raw)
In-Reply-To: <ZXbzsxUTwdp08l9D@arm.com>

On Mon, Dec 11, 2023 at 3:34 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>
> The 12/06/2023 09:20, 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 stack
> > is in use.  Use the current shadow stack pointer as the marker for the
> > default shadow stack.
>
> what is the role of ssp_base in the tcb?

It is used to identify if the current stack is the same as the target
shadow stack when switching ucontexts.  If yes, INCSSP will
be used to unwind shadow stack.  Otherwise, shadow stack
restore token will be used.

> > 2. Allocate shadow stack with the map_shadow_stack syscall.
> > 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 enable
> > shadow stack during startup.
> ...
> > +/* NB: This can be treated as a syscall by caller.  */
> > +
> > +#ifndef __x86_64__
> > +__attribute__ ((regparm (2)))
> > +#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
> > +    = stack_size >> STACK_SIZE_TO_SHADOW_STACK_SIZE_SHIFT;
> > +  /* Align shadow stack to 8 bytes.  */
> > +  shadow_stack_size = ALIGN_UP (shadow_stack_size, 8);
>
> since sigaltstack shares shadow stack with the current context
> in the thread, this should include the shadow stack requirement
> for signal handlers too. otherwise a user can use makecontext
> to fill up a shadow stack such that a stack overflow signal
> handler cannot run (presumably a crash handler should be able
> to handle crashes in all situations).
>
> i think a fixed fixed size is enough to cover for reasonable
> signal handler (e.g. ~20 stack frames).

It sounds reasonable.

>
> > +  void *shadow_stack = (void *)INLINE_SYSCALL_CALL
> > +    (map_shadow_stack, NULL, shadow_stack_size, SHADOW_STACK_SET_TOKEN);
> > +  /* Report the map_shadow_stack error.  */
> > +  if (shadow_stack == MAP_FAILED)
> > +    return -errno;
> > +
> > +  /* Save the shadow stack base and size on child stack.  */
> > +  child_stack[0] = (uintptr_t) shadow_stack;
> > +  child_stack[1] = shadow_stack_size;
> > +
> > +  return 0;
> > +#else
> > +  return -ENOSYS;
> > +#endif
> > +}
> ...
> > --- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> > +++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
> > @@ -24,6 +24,8 @@
> >  # include <pthread.h>
> >  # include <libc-pointer-arith.h>
> >  # include <sys/prctl.h>
> > +# include <sys/mman.h>
> > +# include <allocate-shadow-stack.h>
> >  #endif
> >
> >  #include "ucontext_i.h"
> > @@ -88,23 +90,24 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
> >    if ((feature_1 & X86_FEATURE_1_SHSTK) != 0)
> >      {
> >        /* Shadow stack is enabled.  We need to allocate a new shadow
> > -         stack.  */
> > -      unsigned long ssp_size = (((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 = ALIGN_UP (ssp_size, 8);
> > -
> > -      ucp->__ssp[1] = ssp_size;
> > -      ucp->__ssp[2] = ssp_size;
> > -
> > -      /* Call __push___start_context to allocate a new shadow stack,
> > -      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
> > +     = __allocate_shadow_stack (((uintptr_t) sp
> > +                                 - (uintptr_t) ucp->uc_stack.ss_sp),
> > +                                &ucp->__ssp[1]);
>
> this allocation in glibc does not seem to be freed in glibc.
>
> so normal makecontext use will leak the shadow stack.
>
> (e.g. this is true even if the makecontext function returns
> and thus the shadow stack lifetime ends).

Correct.  Since there is no function to explicitly release ucontext,
there is no place to release shadow stack and shadow stack will
be leaked.

> > +      if (ret != 0)
> > +     {
> > +       /* FIXME: What should we do?  */
> > +       abort ();
>
> makecontext cannot report errors, so we can make this an
> error in setcontext/swapcontext (not sure if that's
> better in practice, but it is more compatible with the
> posix api).
>
> > +     }
> > +
> > +      ucp->__ssp[0] = 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);
> ...
> > --- 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;
>
> is this abi between libc/unwinder or compiler or something else?

This is used by ucontext functions internally in glibc.

Thanks.

-- 
H.J.

  reply	other threads:[~2023-12-11 16:45 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-06 17:19 [PATCH 00/17] x86/cet: Update CET kernel interface H.J. Lu
2023-12-06 17:19 ` [PATCH 01/17] x86/cet: Check user_shstk in /proc/cpuinfo H.J. Lu
2023-12-06 17:19 ` [PATCH 02/17] x86/cet: Update tst-cet-vfork-1 H.J. Lu
2023-12-06 17:19 ` [PATCH 03/17] x86/cet: Don't assume that SHSTK implies IBT H.J. Lu
2023-12-06 17:19 ` [PATCH 04/17] x86/cet: Check legacy shadow stack applications H.J. Lu
2023-12-06 17:19 ` [PATCH 05/17] x86/cet: Check CPU_FEATURE_ACTIVE when CET is disabled H.J. Lu
2023-12-06 23:53   ` Noah Goldstein
2023-12-07 21:07     ` H.J. Lu
2023-12-06 17:19 ` [PATCH 06/17] x86/cet: Add tests for GLIBC_TUNABLES=glibc.cpu.hwcaps=-SHSTK H.J. Lu
2023-12-06 17:20 ` [PATCH 07/17] x86/cet: Check legacy shadow stack code in .init_array section H.J. Lu
2023-12-06 17:20 ` [PATCH 08/17] x86/cet: Check CPU_FEATURE_ACTIVE in permissive mode H.J. Lu
2023-12-06 17:20 ` [PATCH 09/17] x86: Check PT_GNU_PROPERTY early H.J. Lu
2023-12-06 23:57   ` Noah Goldstein
2023-12-07 21:06     ` H.J. Lu
2023-12-06 17:20 ` [PATCH 10/17] x86: Modularize sysdeps/x86/dl-cet.c H.J. Lu
2023-12-06 17:20 ` [PATCH 11/17] x86/cet: Sync with Linux kernel 6.6 shadow stack interface H.J. Lu
2023-12-11 11:34   ` Szabolcs Nagy
2023-12-11 16:44     ` H.J. Lu [this message]
2023-12-12 18:02       ` Szabolcs Nagy
2023-12-12 18:39         ` H.J. Lu
2023-12-13 10:48           ` Szabolcs Nagy
2023-12-13 22:45             ` H.J. Lu
2023-12-13 23:54               ` Edgecombe, Rick P
2023-12-14  0:20                 ` H.J. Lu
2023-12-14  2:21                   ` H.J. Lu
2023-12-14 17:13                     ` szabolcs.nagy
2023-12-14 17:40                       ` H.J. Lu
2023-12-14 23:00                         ` Edgecombe, Rick P
2023-12-14 23:47                           ` H.J. Lu
2023-12-15  1:00                             ` Edgecombe, Rick P
2023-12-15  9:23                         ` szabolcs.nagy
2023-12-15 17:08                           ` H.J. Lu
2023-12-18 10:53                             ` szabolcs.nagy
2023-12-18 19:06                               ` H.J. Lu
2023-12-19 17:15                                 ` szabolcs.nagy
2023-12-19 18:12                                   ` H.J. Lu
2023-12-06 17:20 ` [PATCH 12/17] elf: Always provide _dl_get_dl_main_map in libc.a H.J. Lu
2023-12-06 17:20 ` [PATCH 13/17] x86/cet: Enable shadow stack during startup H.J. Lu
2023-12-06 17:20 ` [PATCH 14/17] x86/cet: Check feature_1 in TCB for active IBT and SHSTK H.J. Lu
2023-12-06 17:20 ` [PATCH 15/17] x86/cet: Don't disable CET if not single threaded H.J. Lu
2023-12-06 17:20 ` [PATCH 16/17] x86/cet: Don't set CET active by default H.J. Lu
2023-12-06 17:20 ` [PATCH 17/17] x86/cet: Run some CET tests with shadow stack H.J. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAMe9rOqXfs6Ow1vGNmaviS0_UopU62GUFSVNVF_o11a7SXZJSQ@mail.gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=libc-alpha@sourceware.org \
    --cc=rick.p.edgecombe@intel.com \
    --cc=szabolcs.nagy@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).