[glibc/azanella/memory-seal-v5] Enable memory sealing automatically
Adhemerval Zanella
azanella@sourceware.org
Thu Jan 30 15:01:05 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c93002979ea1cd59ced8d5705367bbac1bfd6e8b
commit c93002979ea1cd59ced8d5705367bbac1bfd6e8b
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Jan 29 14:22:41 2025 -0300
Enable memory sealing automatically
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 and x86_64-linux-gnu.
Diff:
---
INSTALL | 5 +++++
Makeconfig | 19 +++++++++++++++++-
Makerules | 2 ++
NEWS | 4 ++++
configure | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 20 ++++++++++++++++++
elf/Makefile | 19 ++++++++++++++----
manual/install.texi | 5 +++++
8 files changed, 127 insertions(+), 5 deletions(-)
diff --git a/INSTALL b/INSTALL
index a56179a9c9..3344bb0c6a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -251,6 +251,11 @@ passed to 'configure'. 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 d0108d2caa..2d783c2398 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)
@@ -542,7 +559,7 @@ endif # +link
# Command for linking test programs with crt1.o from glibc 2.0.
+link-2.0-before-inputs = -nostdlib -nostartfiles $(no-pie-ldflag) \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
+ $(relro-LDFLAGS) $(memory-seal-ldflag) $(hashstyle-LDFLAGS) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-name-2.0)) \
$(+preinit) $(+prector)
+link-2.0-before-libc = -o $@ $(+link-2.0-before-inputs) \
diff --git a/Makerules b/Makerules
index ada616891e..02ce3949cf 100644
--- a/Makerules
+++ b/Makerules
@@ -544,6 +544,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) \
@@ -560,6 +561,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 c35ac3ed28..5e0f55718c 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,10 @@ Major new features:
the binary, any preload and audit modules, and aby library loaded with
RTLD_NODELETE.
+* 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.
+
Deprecated and removed features, and other changes affecting compatibility:
[Add deprecations, removals and changes affecting compatibility here]
diff --git a/configure b/configure
index eb8abd0054..8110d57bae 100755
--- a/configure
+++ b/configure
@@ -819,6 +819,7 @@ enable_mathvec
enable_cet
enable_scv
enable_fortify_source
+enable_default_memory_sealing
with_cpu
'
ac_precious_vars='build_alias
@@ -1504,6 +1505,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]
@@ -4882,6 +4886,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.
@@ -7375,6 +7389,50 @@ printf "%s\n" "$libc_cv_fpie" >&6; }
+
+{ 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 GLOB_DAT reloc" >&5
printf %s "checking for GLOB_DAT reloc... " >&6; }
if test ${libc_cv_has_glob_dat+y}
diff --git a/configure.ac b/configure.ac
index 050bfa65e3..000b8c5a7c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -440,6 +440,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.
@@ -1356,6 +1362,20 @@ LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
AC_SUBST(libc_cv_fpie)
+
+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 GLOB_DAT reloc,
libc_cv_has_glob_dat, [dnl
cat > conftest.c <<EOF
diff --git a/elf/Makefile b/elf/Makefile
index 4b1d0d8741..cd1cb0541d 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1496,6 +1496,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)
@@ -1836,6 +1837,7 @@ $(objpfx)nodlopen2.out: $(objpfx)nodlopenmod2.so
$(objpfx)filtmod1.so: $(objpfx)filtmod1.os $(objpfx)filtmod2.so
$(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \
$(dt-relr-ldflag) \
+ $(memory-seal-ldflag) \
-L$(subst :, -L,$(rpath-link)) \
-Wl,-rpath-link=$(rpath-link) \
$< -Wl,-F,$(objpfx)filtmod2.so
@@ -2453,6 +2455,7 @@ $(objpfx)tst-audit17.out: $(objpfx)tst-auditmod17.so
# intended, so it uses an explicit link rule.
$(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os
$(CC) -nostdlib -nostartfiles -shared -o $@.new \
+ $(memory-seal-ldflag) \
$(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
@@ -2513,12 +2516,13 @@ $(objpfx)tst-audit24bmod1: $(objpfx)tst-audit24bmod2.so
# against libc.so.
$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os
$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \
- -Wl,-z,now
+ -Wl,-z,now $(memory-seal-ldflag)
$(call after-link,$@.new)
mv -f $@.new $@
CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod1)
$(objpfx)tst-audit24bmod2.so: $(objpfx)tst-audit24bmod2.os
- $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os
+ $(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod2.os \
+ $(memory-seal-ldflag)
$(call after-link,$@.new)
mv -f $@.new $@
CFLAGS-.os += $(call elide-stack-protector,.os,tst-audit24bmod2)
@@ -2678,7 +2682,7 @@ $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
# artificial, large note in tst-big-note-lib.o and invalidate the
# test.
$(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o
- $(LINK.o) -shared -o $@ $(LDFLAGS.so) $(dt-relr-ldflag) $<
+ $(LINK.o) -shared -o $@ $(LDFLAGS.so) $(dt-relr-ldflag) $(memory-seal-ldflag) $<
$(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so
@@ -2985,6 +2989,7 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
tst-ro-dynamic-mod.map
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
$(dt-relr-ldflag) \
+ $(memory-seal-ldflag) \
-Wl,--script=tst-ro-dynamic-mod.map \
$(objpfx)tst-ro-dynamic-mod.os
@@ -3075,6 +3080,7 @@ $(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
+ $(memory-seal-ldflag) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
@@ -3085,6 +3091,7 @@ $(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
+ $(memory-seal-ldflag) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
@@ -3093,6 +3100,7 @@ $(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
$(objpfx)tst-relr-mod3b.so
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) $(LDFLAGS-rpath-ORIGIN) \
+ $(memory-seal-ldflag) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
@@ -3103,6 +3111,7 @@ $(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
+ $(memory-seal-ldflag) \
-Wl,--version-script=tst-relr-mod4b.map \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
@@ -3111,6 +3120,7 @@ $(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
$(objpfx)tst-relr-mod4b.so
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
+ $(memory-seal-ldflag) \
$(LDFLAGS-soname-fname) $(LDFLAGS-rpath-ORIGIN) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
@@ -3232,7 +3242,7 @@ $(objpfx)tst-env-setuid-static.out: $(objpfx)tst-sonamemove-runmod1.so
# We do not use $(link-test-modules-rpath-link) since the object has no
# DT_NEEDED.
$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
- $(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
+ $(LINK.o) -nostartfiles -nostdlib -shared $(memory-seal-ldflag) -o $@ $^
tst-nodeps1.so-no-z-defs = yes
# Link libc.so before the test module with the IFUNC resolver reference.
LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
@@ -3384,6 +3394,7 @@ CFLAGS-tst-nolink-libc.c += $(no-stack-protector) \
-fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables
$(objpfx)tst-nolink-libc-1: $(objpfx)tst-nolink-libc.o $(objpfx)ld.so
$(LINK.o) -nostdlib -nostartfiles -o $@ $< \
+ $(memory-seal-ldflag) \
-Wl,--dynamic-linker=$(objpfx)ld.so,--no-as-needed $(objpfx)ld.so
$(objpfx)tst-nolink-libc-1.out: $(objpfx)tst-nolink-libc-1 $(objpfx)ld.so
$< > $@ 2>&1; $(evaluate-test)
diff --git a/manual/install.texi b/manual/install.texi
index d001e8220b..7056768885 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -280,6 +280,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
More information about the Glibc-cvs
mailing list