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

Message ID 20200430174550.GH29015@arm.com
State New
Headers show
Series
  • aarch64: branch protection support
Related show

Commit Message

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

Comments

Joseph Myers April 30, 2020, 7:02 p.m. | #1
New configure options should be documented in install.texi, and the 
INSTALL file regenerated.

-- 
Joseph S. Myers
joseph@codesourcery.com
Mark Brown via Libc-alpha May 8, 2020, 5:53 p.m. | #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