[PATCH 05/12] aarch64: fix swapcontext for BTI

Adhemerval Zanella adhemerval.zanella@linaro.org
Thu May 7 18:42:16 GMT 2020



On 30/04/2020 14:41, Szabolcs Nagy wrote:
> From c156ff9d5e332ad17d7fa74b777e8f5466aff0a4 Mon Sep 17 00:00:00 2001
> From: Szabolcs Nagy <szabolcs.nagy@arm.com>
> Date: Wed, 1 Apr 2020 10:31:41 +0100
> Subject: [PATCH 05/12] aarch64: fix swapcontext for BTI
> 
> setcontext returns to the specified context via an indirect jump,
> so there should be a BTI j.
> 
> In case of getcontext (and all other returns_twice functions) the
> compiler adds BTI j at the call site, but swapcontext is a normal
> c call that is currently not handled specially by the compiler.
> 
> So we change swapcontext such that the saved context returns to a
> local address that has BTI j and then swapcontext returns to the
> caller via a normal RET. For this we save the original return
> address in the slot for x1 of the context because x1 need not be
> preserved by swapcontext but it is restored when the context saved
> by swapcontext is resumed.
> 
> The alternative fix (which is done on x86) would make swapcontext
> special in the compiler so BTI j is emitted at call sites, on
> x86 there is an indirect_return attribute for this, on AArch64
> we would have to use returns_twice. It was decided against because
> such fix may need user code updates: the attribute has to be added
> when swapcontext is called via a function pointer and it breaks
> always_inline functions with swapcontext.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  sysdeps/unix/sysv/linux/aarch64/swapcontext.S | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/aarch64/swapcontext.S b/sysdeps/unix/sysv/linux/aarch64/swapcontext.S
> index d30c543e6f..b60cf04c92 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/swapcontext.S
> +++ b/sysdeps/unix/sysv/linux/aarch64/swapcontext.S
> @@ -28,8 +28,12 @@
>  	.text
>  ENTRY(__swapcontext)
>  	DELOUSE (0)
> -	/* Set the value returned when swapcontext() returns in this context. */
> -	str	xzr,      [x0, oX0 +  0 * SZREG]
> +	/* Set the value returned when swapcontext() returns in this context.
> +	   And set up x1 to become the return address of the caller, so we
> +	   can return there with a normal RET instead of an indirect jump.  */
> +	stp	xzr, x30, [x0, oX0 +  0 * SZREG]
> +	/* Arrange the oucp context to return to 2f.  */
> +	adr	x30, 2f
>  
>  	stp	x18, x19, [x0, oX0 + 18 * SZREG]
>  	stp	x20, x21, [x0, oX0 + 20 * SZREG]
> @@ -97,5 +101,12 @@ ENTRY(__swapcontext)
>  
>  1:
>  	b	C_SYMBOL_NAME(__syscall_error)
> +2:
> +	/* The oucp context is restored here via an indirect branch,
> +	   x1 must be restored too which has the real return address.  */
> +	BTI_J
> +	mov	x30, x1
> +	RET
>  PSEUDO_END (__swapcontext)
>  weak_alias (__swapcontext, swapcontext)
> +END_FILE
> -- 
> 2.17.1


More information about the Libc-alpha mailing list