[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