diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2019-12-13 16:46:07 -0800 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2020-02-07 23:25:37 +0000 |
commit | 34675b2ba942f81a74bd8bc46b937604dca0a645 (patch) | |
tree | 5273284c30fdef96e48d5b9eab1a0277b6357f7e /crypto/async | |
parent | 0e43960e88128bb86031a45c0fe9ca3e3a310c3b (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.c | 2 | ||||
-rw-r--r-- | crypto/async/arch/async_posix.h | 19 |
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; } |