[12/12] aarch64: Configure option to build glibc with branch protection

Message ID 20200430174550.GH29015@arm.com
State Superseded
Headers
Series aarch64: branch protection support |

Commit Message

Szabolcs Nagy April 30, 2020, 5:45 p.m. UTC
  
  

Comments

Joseph Myers April 30, 2020, 7:02 p.m. UTC | #1
New configure options should be documented in install.texi, and the 
INSTALL file regenerated.
  
Adhemerval Zanella Netto May 8, 2020, 5:53 p.m. UTC | #2
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])
  

Patch

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