Use swapcontext for Intel CET
authorH.J. Lu <hongjiu.lu@intel.com>
Sat, 14 Dec 2019 00:46:07 +0000 (16:46 -0800)
committerMatt Caswell <matt@openssl.org>
Fri, 7 Feb 2020 23:25:37 +0000 (23:25 +0000)
When Intel CET is enabled, makecontext will create a different shadow
stack for each context.  async_fibre_swapcontext cannot use _longjmp.
It must call swapcontext to swap shadow stack as well as normal stack.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10983)

crypto/async/arch/async_posix.c
crypto/async/arch/async_posix.h

index 7476970e6ba86fe935b8243ad75f8f7e3c23fe46..3432320bcfe7c956904cbee64a5f1b0d9f4dc94f 100644 (file)
@@ -34,7 +34,9 @@ void async_local_cleanup(void)
 
 int async_fibre_makecontext(async_fibre *fibre)
 {
+#ifndef USE_SWAPCONTEXT
     fibre->env_init = 0;
+#endif
     if (getcontext(&fibre->fibre) == 0) {
         fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE);
         if (fibre->fibre.uc_stack.ss_sp != NULL) {
index aba713e75906eee85726f9098281031bb5c67343..4fb09b71dc4d1276a871df994de3f90825ca009e 100644 (file)
 #  define ASYNC_POSIX
 #  define ASYNC_ARCH
 
+#  ifdef __CET__
+/*
+ * When Intel CET is enabled, makecontext will create a different
+ * shadow stack for each context.  async_fibre_swapcontext cannot
+ * use _longjmp.  It must call swapcontext to swap shadow stack as
+ * well as normal stack.
+ */
+#   define USE_SWAPCONTEXT
+#  endif
 #  include <ucontext.h>
-#  include <setjmp.h>
+#  ifndef USE_SWAPCONTEXT
+#   include <setjmp.h>
+#  endif
 
 typedef struct async_fibre_st {
     ucontext_t fibre;
+#  ifndef USE_SWAPCONTEXT
     jmp_buf env;
     int env_init;
+#  endif
 } async_fibre;
 
 static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)
 {
+#  ifdef USE_SWAPCONTEXT
+    swapcontext(&o->fibre, &n->fibre);
+#  else
     o->env_init = 1;
 
     if (!r || !_setjmp(o->env)) {
@@ -44,6 +60,7 @@ static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, i
         else
             setcontext(&n->fibre);
     }
+#  endif
 
     return 1;
 }