summaryrefslogtreecommitdiffstats
path: root/crypto/async
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2019-12-13 16:46:07 -0800
committerMatt Caswell <matt@openssl.org>2020-02-07 23:25:37 +0000
commit34675b2ba942f81a74bd8bc46b937604dca0a645 (patch)
tree5273284c30fdef96e48d5b9eab1a0277b6357f7e /crypto/async
parent0e43960e88128bb86031a45c0fe9ca3e3a310c3b (diff)
Use swapcontext for Intel 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. Reviewed-by: Paul Dale <paul.dale@oracle.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10983)
Diffstat (limited to 'crypto/async')
-rw-r--r--crypto/async/arch/async_posix.c2
-rw-r--r--crypto/async/arch/async_posix.h19
2 files changed, 20 insertions, 1 deletions
diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c
index 7476970e6b..3432320bcf 100644
--- a/crypto/async/arch/async_posix.c
+++ b/crypto/async/arch/async_posix.c
@@ -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) {
diff --git a/crypto/async/arch/async_posix.h b/crypto/async/arch/async_posix.h
index aba713e759..4fb09b71dc 100644
--- a/crypto/async/arch/async_posix.h
+++ b/crypto/async/arch/async_posix.h
@@ -25,17 +25,33 @@
# 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;
}