[v3,7/9] Enable memory sealing automatically

Message ID 20240930200831.1669010-8-adhemerval.zanella@linaro.org
State New
Headers
Series Add support for memory sealing |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Adhemerval Zanella Netto Sept. 30, 2024, 8:08 p.m. UTC
  All libraries, programs, and the testsuite in glibc are now build with
memory sealing by default if the toochain supports it.  A new configure
option, --disable-default-memory-seal, disables it.

Checked on aarch64-linux-gnu.
---
 INSTALL             |  5 ++++
 Makeconfig          | 17 ++++++++++++++
 Makerules           |  2 ++
 NEWS                |  4 ++++
 configure           | 57 +++++++++++++++++++++++++++++++++++++++++++++
 configure.ac        | 19 +++++++++++++++
 elf/Makefile        |  1 +
 manual/install.texi |  5 ++++
 8 files changed, 110 insertions(+)
  

Patch

diff --git a/INSTALL b/INSTALL
index 24e3c8d25b..2a340514c2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -245,6 +245,11 @@  if 'CFLAGS' is specified it must enable optimization.  For example:
      Disable using 'scv' instruction for syscalls.  All syscalls will
      use 'sc' instead, even if the kernel supports 'scv'.  PowerPC only.
 
+'--disable-default-memory-seal'
+     Don't build glibc libraries, programs, and the testsuite with
+     memory sealing support (GNU_PROPERTY_MEMORY_SEAL).  By default,
+     memory sealing is enabled if toolchain suports the linker option.
+
 '--build=BUILD-SYSTEM'
 '--host=HOST-SYSTEM'
      These options are for cross-compiling.  If you specify both options
diff --git a/Makeconfig b/Makeconfig
index a87ff7b1d3..953a8b1d1f 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -389,6 +389,21 @@  dt-relr-ldflag =
 no-dt-relr-ldflag =
 endif
 
+# Linker options to enable and disable memory sealing (GNU_PROPERTY_MEMORY_SEAL),
+# if --disable-default-memory-sealing is used explicit disable memory sealing for
+# the case linker defaults to it.
+ifeq ($(have-z-memory-seal),yes)
+no-memory-seal-ldflag = -Wl,-z,nomemory-seal
+ifeq ($(default-memory-seal),yes)
+memory-seal-ldflag = -Wl,-z,memory-seal
+else
+memory-seal-ldflag = $(no-memory-seal-ldflag)
+endif
+else
+memory-seal-ldflag =
+no-memory-seal-ldflag =
+endif
+
 ifeq (no,$(build-pie-default))
 pie-default = $(no-pie-ccflag)
 else # build-pie-default
@@ -433,6 +448,7 @@  link-extra-libs-tests = $(libsupport)
 ifndef +link-pie
 +link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
 	     $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \
+	     $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \
 	     -Wl,-O1 -nostdlib -nostartfiles \
 	     $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
 	     $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
@@ -466,6 +482,7 @@  ifndef +link-static
 +link-static-before-inputs = -nostdlib -nostartfiles -static \
 	      $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \
 	      $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(static-pie-dt-relr-ldflag)) \
+	      $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
 	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
 	      $(+preinit) $(+prectorT)
diff --git a/Makerules b/Makerules
index 275110dda8..f2240ed2df 100644
--- a/Makerules
+++ b/Makerules
@@ -539,6 +539,7 @@  define build-shlib-helper
 $(LINK.o) -shared -static-libgcc -Wl,-O1 $(sysdep-LDFLAGS) \
 	  $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) $(rtld-LDFLAGS) \
 	  $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \
+	  $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \
 	  $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
 	  $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
 	  -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
@@ -555,6 +556,7 @@  define build-module-helper
 $(LINK.o) -shared -static-libgcc $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \
 	  $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) \
 	  $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(dt-relr-ldflag)) \
+	  $(if $($(@F)-no-memory-seal),$(no-memory-seal-ldflag),$(memory-seal-ldflag)) \
 	  -B$(csu-objpfx) $(load-map-file) \
 	  $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
 	  $(link-test-modules-rpath-link) \
diff --git a/NEWS b/NEWS
index f103b4995b..ad1b05e015 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,10 @@  Major new features:
   the binary, any preload and audit modules, and aby library loaded with
   RTLD_NODELETE.
 
+* All libraries, progras, and the testsuite in glibc are now build with
+  memory sealing by default if the toochain supports it.  A new configure
+  option, --disable-default-memory-seal, disables it.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The big-endian ARC port (arceb-linux-gnu) has been removed.
diff --git a/configure b/configure
index ec0b62db36..74b56afbbf 100755
--- a/configure
+++ b/configure
@@ -808,6 +808,7 @@  enable_mathvec
 enable_cet
 enable_scv
 enable_fortify_source
+enable_default_memory_sealing
 with_cpu
 '
       ac_precious_vars='build_alias
@@ -1491,6 +1492,9 @@  Optional Features:
                           Use -D_FORTIFY_SOURCE=[1|2|3] to control code
                           hardening, defaults to highest possible value
                           supported by the build compiler.
+  --disable-default-memory-sealing
+                          Do not build glibc libraries, programs, and the
+                          testsuite with memory sealing [default=no]
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -4855,6 +4859,16 @@  case "$enable_fortify_source" in
 *) as_fn_error $? "Not a valid argument for --enable-fortify-source: \"$enable_fortify_source\"" "$LINENO" 5;;
 esac
 
+# Check whether --enable-default-memory-sealing was given.
+if test ${enable_default_memory_sealing+y}
+then :
+  enableval=$enable_default_memory_sealing; default_memory_sealing=$enableval
+else case e in #(
+  e) default_memory_sealing=yes ;;
+esac
+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.
@@ -7102,6 +7116,49 @@  printf "%s\n" "$libc_linker_feature" >&6; }
 config_vars="$config_vars
 have-no-dynamic-linker = $libc_cv_no_dynamic_linker"
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z memory-seal" >&5
+printf %s "checking for linker that supports -z memory-seal... " >&6; }
+libc_linker_feature=no
+cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+		  -Wl,-z,memory-seal -nostdlib -nostartfiles
+		  -fPIC -shared -o conftest.so conftest.c
+		  1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then
+  if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,memory-seal -nostdlib \
+      -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \
+      | grep "warning: -z memory-seal ignored" > /dev/null 2>&1; then
+    true
+  else
+    libc_linker_feature=yes
+  fi
+fi
+rm -f conftest*
+if test $libc_linker_feature = yes; then
+  libc_cv_z_memory_seal=yes
+else
+  libc_cv_z_memory_seal=no
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+printf "%s\n" "$libc_linker_feature" >&6; }
+
+# Enable memory-sealing iff it is available and glibc is not configured
+# with --disable-defautl-memory-sealing
+if test "$libc_cv_z_memory_seal" = no; then
+  default_memory_sealing=no
+fi
+config_vars="$config_vars
+have-z-memory-seal = $libc_cv_z_memory_seal"
+config_vars="$config_vars
+default-memory-seal = $default_memory_sealing"
+
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -static-pie" >&5
 printf %s "checking for -static-pie... " >&6; }
 if test ${libc_cv_static_pie+y}
diff --git a/configure.ac b/configure.ac
index 7c9b57789e..0a7776a7bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -426,6 +426,12 @@  case "$enable_fortify_source" in
 *) AC_MSG_ERROR([Not a valid argument for --enable-fortify-source: "$enable_fortify_source"]);;
 esac
 
+AC_ARG_ENABLE([default-memory-sealing],
+	      AS_HELP_STRING([--disable-default-memory-sealing],
+			     [Do not build glibc libraries, programs, and the testsuite with memory sealing @<:@default=no@:>@]),
+	      [default_memory_sealing=$enableval],
+	      [default_memory_sealing=yes])
+
 # 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.
@@ -1278,6 +1284,19 @@  LIBC_LINKER_FEATURE([--no-dynamic-linker],
 		    [libc_cv_no_dynamic_linker=no])
 LIBC_CONFIG_VAR([have-no-dynamic-linker], [$libc_cv_no_dynamic_linker])
 
+LIBC_LINKER_FEATURE([-z memory-seal],
+		    [-Wl,-z,memory-seal],
+		    [libc_cv_z_memory_seal=yes],
+		    [libc_cv_z_memory_seal=no])
+
+# Enable memory-sealing iff it is available and glibc is not configured
+# with --disable-defautl-memory-sealing
+if test "$libc_cv_z_memory_seal" = no; then
+  default_memory_sealing=no
+fi
+LIBC_CONFIG_VAR([have-z-memory-seal], [$libc_cv_z_memory_seal])
+LIBC_CONFIG_VAR([default-memory-seal], [$default_memory_sealing])
+
 AC_CACHE_CHECK(for -static-pie, libc_cv_static_pie, [dnl
 LIBC_TRY_CC_OPTION([-static-pie],
 		   [libc_cv_static_pie=yes],
diff --git a/elf/Makefile b/elf/Makefile
index 09d77093a7..942761d9c6 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1392,6 +1392,7 @@  $(objpfx)ld.so: $(objpfx)librtld.os $(ld-map)
 	$(LINK.o) -nostdlib -nostartfiles -shared -o $@.new		\
 		  $(LDFLAGS-rtld) -Wl,-z,defs $(z-now-$(bind-now))	\
 		  $(dt-relr-ldflag) \
+		  $(memory-seal-ldflag) \
 		  $(filter-out $(map-file),$^) $(load-map-file)		\
 		  -Wl,-soname=$(rtld-installed-name)
 	$(call after-link,$@.new)
diff --git a/manual/install.texi b/manual/install.texi
index 3e68a3d823..58363e8a9c 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -272,6 +272,11 @@  C++ libraries.
 Disable using @code{scv} instruction for syscalls. All syscalls will use
 @code{sc} instead, even if the kernel supports @code{scv}. PowerPC only.
 
+@item --disable-default-memory-seal
+Don't build glibc libraries, programs, and the testsuite with
+memory sealing support (@code{GNU_PROPERTY_MEMORY_SEAL}).  By default,
+memory sealing is enabled if toolchain suports the linker option.
+
 @item --build=@var{build-system}
 @itemx --host=@var{host-system}
 These options are for cross-compiling.  If you specify both options and