Message ID | 20200430174550.GH29015@arm.com |
---|---|
State | New |
Headers | show |
Series | aarch64: branch protection support | expand |
New configure options should be documented in install.texi, and the INSTALL file regenerated.
On 30/04/2020 14:45, Szabolcs Nagy wrote: > If gcc is configured with --enable-standard-branch-protection then > the built glibc should have branch protection suppport too, which > includes bti and pac-ret. The new configure option is only for > additional configure checks, it does not try to add new CFLAGS > (i.e. -mbranch-protection=standard ), it expects gcc to default to > using branch protection, since likely the static linked compiler > libraries are not compatible otherwise. > > The -z force-bti linker flag is also passed with branch protection, > but this is not very useful: by default the BTI property marking > is set on the linker output if all linker inputs have it and it is > silently missing otherwise, -z force-bti at least warns if an input > is missing the property, but that's not a fatal error. > (Using --fatal-warnings ld flag does not work in the test system.) Since BTI/PAC is enabled as default with nop compatible instructions, I think it would be simpler to add a aarch64 configure check against the compiler flags used instead of adding a configure switch. It could be used to select set ENABLE_PAC_RET as well. With a configure check the BTI enablement will be transparent and controlled by the either default compiler default or the selected CC/CFLAGS (as used by others ABI selections). > > Co-authored-by: Szabolcs Nagy <szabolcs.nagy@arm.com> > --- > configure | 14 +++++++++++++- > configure.ac | 6 ++++++ > sysdeps/aarch64/Makefile | 4 ++++ > sysdeps/aarch64/configure | 31 +++++++++++++++++++++++++++++++ > sysdeps/aarch64/configure.ac | 19 +++++++++++++++++++ > 5 files changed, 73 insertions(+), 1 deletion(-) > > diff --git a/configure b/configure > index 8df47d61f8..fff5734f6d 100755 > --- a/configure > +++ b/configure > @@ -794,6 +794,7 @@ enable_pt_chown > enable_tunables > enable_mathvec > enable_cet > +enable_standard_branch_protection > with_cpu > ' > ac_precious_vars='build_alias > @@ -1471,6 +1472,9 @@ Optional Features: > depends on architecture] > --enable-cet enable Intel Control-flow Enforcement Technology > (CET), x86 only > + --enable-standard-branch-protection > + enable AArch64 Branch Target Identification and > + Return Address Signing, AArch64 only > > Optional Packages: > --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] > @@ -3785,7 +3789,7 @@ main () > { > > #ifndef __CET__ > -#error no CET compiler support > +# error no CET compiler support > #endif > ; > return 0; Spurious change. > @@ -3806,6 +3810,14 @@ else > fi > > > +# Check whether --enable-standard-branch-protection was given. > +if test "${enable_standard_branch_protection+set}" = set; then : > + enableval=$enable_standard_branch_protection; libc_cv_branch_protection=$enableval > +else > + libc_cv_branch_protection=no > +fi > + > + > # We keep the original values in `$config_*' and never modify them, so we > # can write them unchanged into config.make. Everything else uses > # $machine, $vendor, and $os, and changes them whenever convenient. > diff --git a/configure.ac b/configure.ac > index 5f229679a9..e08b0f3766 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -486,6 +486,12 @@ AC_ARG_ENABLE([cet], > [enable_cet=$enableval], > [enable_cet=$libc_cv_compiler_default_cet]) > > +AC_ARG_ENABLE([standard-branch-protection], > + AC_HELP_STRING([--enable-standard-branch-protection], > + [enable AArch64 Branch Target Identification and Return Address Signing, AArch64 only]), > + [libc_cv_branch_protection=$enableval], > + [libc_cv_branch_protection=no]) > + > # We keep the original values in `$config_*' and never modify them, so we > # can write them unchanged into config.make. Everything else uses > # $machine, $vendor, and $os, and changes them whenever convenient. > diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile > index 5ae8b082b0..313c371e72 100644 > --- a/sysdeps/aarch64/Makefile > +++ b/sysdeps/aarch64/Makefile > @@ -1,5 +1,9 @@ > long-double-fcts = yes > > +ifeq (yes,$(enable-branch-protection)) > +sysdep-LDFLAGS += -Wl,-z,force-bti > +endif > + > ifeq ($(subdir),elf) > sysdep-dl-routines += dl-bti > endif > diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure > index 5bd355a691..83a6c8c852 100644 > --- a/sysdeps/aarch64/configure > +++ b/sysdeps/aarch64/configure > @@ -172,3 +172,34 @@ else > config_vars="$config_vars > default-abi = lp64" > fi > + > +if test "$libc_cv_branch_protection" = yes; then > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for branch protection support" >&5 > +$as_echo_n "checking for branch protection support... " >&6; } > +if ${libc_cv_branch_protection_support+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + cat > conftest.c <<EOF > +void foo (void) { } > +EOF > + libc_cv_branch_protection_support=no > + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -fPIC -shared -Wl,-z,force-bti,--fatal-warnings -o conftest.so 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; }; } \ > + && LC_ALL=C $READELF -Wn conftest.so | \ > + grep -q 'NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI'; then > + libc_cv_branch_protection_support=yes > + fi > + rm -rf conftest.* > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_branch_protection_support" >&5 > +$as_echo "$libc_cv_branch_protection_support" >&6; } > + if test $libc_cv_branch_protection_support = no; then > + as_fn_error $? "branch-protection is enabled, but the toolchain does not support it." "$LINENO" 5 > + fi > +fi > +config_vars="$config_vars > +enable-branch-protection = $libc_cv_branch_protection" > diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac > index 7851dd4dac..d16ba3710a 100644 > --- a/sysdeps/aarch64/configure.ac > +++ b/sysdeps/aarch64/configure.ac > @@ -20,3 +20,22 @@ if test $libc_cv_aarch64_be = yes; then > else > LIBC_CONFIG_VAR([default-abi], [lp64]) > fi > + > +if test "$libc_cv_branch_protection" = yes; then > + AC_CACHE_CHECK([for branch protection support], > + [libc_cv_branch_protection_support], > + [cat > conftest.c <<EOF > +void foo (void) { } > +EOF > + libc_cv_branch_protection_support=no > + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -fPIC -shared -Wl,-z,force-bti,--fatal-warnings -o conftest.so conftest.c]) \ > + && LC_ALL=C $READELF -Wn conftest.so | \ > + grep -q 'NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI'; then > + libc_cv_branch_protection_support=yes > + fi > + rm -rf conftest.*]) > + if test $libc_cv_branch_protection_support = no; then > + AC_MSG_ERROR([branch-protection is enabled, but the toolchain does not support it.]) > + fi > +fi > +LIBC_CONFIG_VAR([enable-branch-protection], [$libc_cv_branch_protection])
From ec96daabd8fad129ea3660d479fa63941712c410 Mon Sep 17 00:00:00 2001 From: Sudakshina Das <sudi.das@arm.com> Date: Thu, 26 Mar 2020 11:49:48 +0000 Subject: [PATCH 12/12] aarch64: Configure option to build glibc with branch protection If gcc is configured with --enable-standard-branch-protection then the built glibc should have branch protection suppport too, which includes bti and pac-ret. The new configure option is only for additional configure checks, it does not try to add new CFLAGS (i.e. -mbranch-protection=standard ), it expects gcc to default to using branch protection, since likely the static linked compiler libraries are not compatible otherwise. The -z force-bti linker flag is also passed with branch protection, but this is not very useful: by default the BTI property marking is set on the linker output if all linker inputs have it and it is silently missing otherwise, -z force-bti at least warns if an input is missing the property, but that's not a fatal error. (Using --fatal-warnings ld flag does not work in the test system.) Co-authored-by: Szabolcs Nagy <szabolcs.nagy@arm.com> --- configure | 14 +++++++++++++- configure.ac | 6 ++++++ sysdeps/aarch64/Makefile | 4 ++++ sysdeps/aarch64/configure | 31 +++++++++++++++++++++++++++++++ sysdeps/aarch64/configure.ac | 19 +++++++++++++++++++ 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 8df47d61f8..fff5734f6d 100755 --- a/configure +++ b/configure @@ -794,6 +794,7 @@ enable_pt_chown enable_tunables enable_mathvec enable_cet +enable_standard_branch_protection with_cpu ' ac_precious_vars='build_alias @@ -1471,6 +1472,9 @@ Optional Features: depends on architecture] --enable-cet enable Intel Control-flow Enforcement Technology (CET), x86 only + --enable-standard-branch-protection + enable AArch64 Branch Target Identification and + Return Address Signing, AArch64 only Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -3785,7 +3789,7 @@ main () { #ifndef __CET__ -#error no CET compiler support +# error no CET compiler support #endif ; return 0; @@ -3806,6 +3810,14 @@ else fi +# Check whether --enable-standard-branch-protection was given. +if test "${enable_standard_branch_protection+set}" = set; then : + enableval=$enable_standard_branch_protection; libc_cv_branch_protection=$enableval +else + libc_cv_branch_protection=no +fi + + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. diff --git a/configure.ac b/configure.ac index 5f229679a9..e08b0f3766 100644 --- a/configure.ac +++ b/configure.ac @@ -486,6 +486,12 @@ AC_ARG_ENABLE([cet], [enable_cet=$enableval], [enable_cet=$libc_cv_compiler_default_cet]) +AC_ARG_ENABLE([standard-branch-protection], + AC_HELP_STRING([--enable-standard-branch-protection], + [enable AArch64 Branch Target Identification and Return Address Signing, AArch64 only]), + [libc_cv_branch_protection=$enableval], + [libc_cv_branch_protection=no]) + # We keep the original values in `$config_*' and never modify them, so we # can write them unchanged into config.make. Everything else uses # $machine, $vendor, and $os, and changes them whenever convenient. diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index 5ae8b082b0..313c371e72 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -1,5 +1,9 @@ long-double-fcts = yes +ifeq (yes,$(enable-branch-protection)) +sysdep-LDFLAGS += -Wl,-z,force-bti +endif + ifeq ($(subdir),elf) sysdep-dl-routines += dl-bti endif diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure index 5bd355a691..83a6c8c852 100644 --- a/sysdeps/aarch64/configure +++ b/sysdeps/aarch64/configure @@ -172,3 +172,34 @@ else config_vars="$config_vars default-abi = lp64" fi + +if test "$libc_cv_branch_protection" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for branch protection support" >&5 +$as_echo_n "checking for branch protection support... " >&6; } +if ${libc_cv_branch_protection_support+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <<EOF +void foo (void) { } +EOF + libc_cv_branch_protection_support=no + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -fPIC -shared -Wl,-z,force-bti,--fatal-warnings -o conftest.so 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; }; } \ + && LC_ALL=C $READELF -Wn conftest.so | \ + grep -q 'NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI'; then + libc_cv_branch_protection_support=yes + fi + rm -rf conftest.* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_branch_protection_support" >&5 +$as_echo "$libc_cv_branch_protection_support" >&6; } + if test $libc_cv_branch_protection_support = no; then + as_fn_error $? "branch-protection is enabled, but the toolchain does not support it." "$LINENO" 5 + fi +fi +config_vars="$config_vars +enable-branch-protection = $libc_cv_branch_protection" diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac index 7851dd4dac..d16ba3710a 100644 --- a/sysdeps/aarch64/configure.ac +++ b/sysdeps/aarch64/configure.ac @@ -20,3 +20,22 @@ if test $libc_cv_aarch64_be = yes; then else LIBC_CONFIG_VAR([default-abi], [lp64]) fi + +if test "$libc_cv_branch_protection" = yes; then + AC_CACHE_CHECK([for branch protection support], + [libc_cv_branch_protection_support], + [cat > conftest.c <<EOF +void foo (void) { } +EOF + libc_cv_branch_protection_support=no + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -fPIC -shared -Wl,-z,force-bti,--fatal-warnings -o conftest.so conftest.c]) \ + && LC_ALL=C $READELF -Wn conftest.so | \ + grep -q 'NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI'; then + libc_cv_branch_protection_support=yes + fi + rm -rf conftest.*]) + if test $libc_cv_branch_protection_support = no; then + AC_MSG_ERROR([branch-protection is enabled, but the toolchain does not support it.]) + fi +fi +LIBC_CONFIG_VAR([enable-branch-protection], [$libc_cv_branch_protection]) -- 2.17.1