[v3,10/13] aarch64: configure check for pac-ret code generation
Commit Message
Return address signing requires unwinder support, which is
present in libgcc since >=gcc-7, however due to bugs the
support may be broken in <gcc-10 (and similarly there may
be issues in custom unwinders), so pac-ret is not always
safe to use. So in assembly code glibc should only use
pac-ret if the compiler uses it too. Unfortunately there
is no predefined feature macro for it set by the compiler
so pac-ret is inferred from the code generation.
---
config.h.in | 3 +++
sysdeps/aarch64/configure | 39 ++++++++++++++++++++++++++++++++++++
sysdeps/aarch64/configure.ac | 21 +++++++++++++++++++
3 files changed, 63 insertions(+)
Comments
On 15/05/2020 11:40, Szabolcs Nagy wrote:
> Return address signing requires unwinder support, which is
> present in libgcc since >=gcc-7, however due to bugs the
> support may be broken in <gcc-10 (and similarly there may
> be issues in custom unwinders), so pac-ret is not always
> safe to use. So in assembly code glibc should only use
> pac-ret if the compiler uses it too. Unfortunately there
> is no predefined feature macro for it set by the compiler
> so pac-ret is inferred from the code generation.
OK with this fixes below.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> config.h.in | 3 +++
> sysdeps/aarch64/configure | 39 ++++++++++++++++++++++++++++++++++++
> sysdeps/aarch64/configure.ac | 21 +++++++++++++++++++
> 3 files changed, 63 insertions(+)
>
> diff --git a/config.h.in b/config.h.in
> index 506b0c416c..f441470385 100644
> --- a/config.h.in
> +++ b/config.h.in
> @@ -112,6 +112,9 @@
> /* AArch64 BTI support enabled. */
> #undef HAVE_AARCH64_BTI
>
> +/* AArch64 PAC-RET code generation is enabled. */
> +#undef HAVE_AARCH64_PAC_RET
> +
> /* C-SKY ABI version. */
> #undef CSKYABI
>
Use
#define HAVE_AARCH64_PAC_RET 0
instead so we can check the define value instead of the its existence.
> diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
> index 70477a7fa5..5f1cdf5d9b 100644
> --- a/sysdeps/aarch64/configure
> +++ b/sysdeps/aarch64/configure
> @@ -214,3 +214,42 @@ if test $libc_cv_aarch64_bti = yes; then
> $as_echo "#define HAVE_AARCH64_BTI 1" >>confdefs.h
>
> fi
> +
> +# Check if glibc is built with return address signing, i.e.
> +# if -mbranch-protection=pac-ret is on. We need this because
> +# pac-ret relies on unwinder support so it's not safe to use
> +# it in assembly code unconditionally, but there is no
> +# feature test macro for it in gcc.
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if pac-ret is enabled" >&5
> +$as_echo_n "checking if pac-ret is enabled... " >&6; }
> +if ${libc_cv_aarch64_pac_ret+:} false; then :
> + $as_echo_n "(cached) " >&6
> +else
> + cat > conftest.c <<EOF
> +int bar (void);
> +int foo (void) { return bar () + 1; }
> +EOF
> + libc_cv_aarch64_pac_ret=no
> + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c'
> + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> + (eval $ac_try) 2>&5
> + ac_status=$?
> + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> + test $ac_status = 0; }; } \
> + && { ac_try='grep -q -E '\''(hint( | )+25|paciasp)'\'' conftest.s'
> + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> + (eval $ac_try) 2>&5
> + ac_status=$?
> + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> + test $ac_status = 0; }; }
> + then
> + libc_cv_aarch64_pac_ret=yes
> + fi
> + rm -rf conftest.*
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_aarch64_pac_ret" >&5
> +$as_echo "$libc_cv_aarch64_pac_ret" >&6; }
> +if test $libc_cv_aarch64_pac_ret = yes; then
> + $as_echo "#define HAVE_AARCH64_PAC_RET 1" >>confdefs.h
> +
> +fi
> diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
> index 798f494740..8248ecf2ed 100644
> --- a/sysdeps/aarch64/configure.ac
> +++ b/sysdeps/aarch64/configure.ac
> @@ -39,3 +39,24 @@ EOF
> if test $libc_cv_aarch64_bti = yes; then
> AC_DEFINE(HAVE_AARCH64_BTI)
> fi
> +
> +# Check if glibc is built with return address signing, i.e.
> +# if -mbranch-protection=pac-ret is on. We need this because
Two spaces after period.
> +# pac-ret relies on unwinder support so it's not safe to use
> +# it in assembly code unconditionally, but there is no
> +# feature test macro for it in gcc.
> +AC_CACHE_CHECK([if pac-ret is enabled], [libc_cv_aarch64_pac_ret], [dnl
> + cat > conftest.c <<EOF
> +int bar (void);
> +int foo (void) { return bar () + 1; }
> +EOF
> + libc_cv_aarch64_pac_ret=no
> + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c]) \
> + && AC_TRY_COMMAND([grep -q -E '\''(hint( | )+25|paciasp)'\'' conftest.s])
I am not sure this expression is doing what it is intended to do,
I think you are matching the gcc output because it also add an
extra comment with 'paciasp'.
I think what you need here is "(hint[[:space:]]+25|paciasp)".
> + then
> + libc_cv_aarch64_pac_ret=yes
> + fi
> + rm -rf conftest.*])
> +if test $libc_cv_aarch64_pac_ret = yes; then
> + AC_DEFINE(HAVE_AARCH64_PAC_RET)
> +fi
>
@@ -112,6 +112,9 @@
/* AArch64 BTI support enabled. */
#undef HAVE_AARCH64_BTI
+/* AArch64 PAC-RET code generation is enabled. */
+#undef HAVE_AARCH64_PAC_RET
+
/* C-SKY ABI version. */
#undef CSKYABI
@@ -214,3 +214,42 @@ if test $libc_cv_aarch64_bti = yes; then
$as_echo "#define HAVE_AARCH64_BTI 1" >>confdefs.h
fi
+
+# Check if glibc is built with return address signing, i.e.
+# if -mbranch-protection=pac-ret is on. We need this because
+# pac-ret relies on unwinder support so it's not safe to use
+# it in assembly code unconditionally, but there is no
+# feature test macro for it in gcc.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if pac-ret is enabled" >&5
+$as_echo_n "checking if pac-ret is enabled... " >&6; }
+if ${libc_cv_aarch64_pac_ret+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+int bar (void);
+int foo (void) { return bar () + 1; }
+EOF
+ libc_cv_aarch64_pac_ret=no
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } \
+ && { ac_try='grep -q -E '\''(hint( | )+25|paciasp)'\'' conftest.s'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ libc_cv_aarch64_pac_ret=yes
+ fi
+ rm -rf conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_aarch64_pac_ret" >&5
+$as_echo "$libc_cv_aarch64_pac_ret" >&6; }
+if test $libc_cv_aarch64_pac_ret = yes; then
+ $as_echo "#define HAVE_AARCH64_PAC_RET 1" >>confdefs.h
+
+fi
@@ -39,3 +39,24 @@ EOF
if test $libc_cv_aarch64_bti = yes; then
AC_DEFINE(HAVE_AARCH64_BTI)
fi
+
+# Check if glibc is built with return address signing, i.e.
+# if -mbranch-protection=pac-ret is on. We need this because
+# pac-ret relies on unwinder support so it's not safe to use
+# it in assembly code unconditionally, but there is no
+# feature test macro for it in gcc.
+AC_CACHE_CHECK([if pac-ret is enabled], [libc_cv_aarch64_pac_ret], [dnl
+ cat > conftest.c <<EOF
+int bar (void);
+int foo (void) { return bar () + 1; }
+EOF
+ libc_cv_aarch64_pac_ret=no
+ if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c]) \
+ && AC_TRY_COMMAND([grep -q -E '\''(hint( | )+25|paciasp)'\'' conftest.s])
+ then
+ libc_cv_aarch64_pac_ret=yes
+ fi
+ rm -rf conftest.*])
+if test $libc_cv_aarch64_pac_ret = yes; then
+ AC_DEFINE(HAVE_AARCH64_PAC_RET)
+fi