Message ID | 20230704165554.239581-2-fberat@redhat.com |
---|---|
State | New |
Headers | show |
Series | Allow glibc to be built with _FORTIFY_SOURCE | expand |
On 2023-07-04 12:55, Frédéric Bérat wrote: > Glibc can now be built with _FORTIFY_SOURCE. > Since the feature needs some of the routines provided by Glibc, these > can be excluded from the fortification using the newly created > $(no_fortify_source) variable. > > A dedicated patch will follow to make use of this variable in Makefiles > when necessary. > > Update NEWS. > --- If it's not too much, please merge 15/15 with this, there's no reason to keep them separate given that there's consensus on direction now. > Makeconfig | 28 +++++++++++++++++++++++++--- > NEWS | 3 +++ > config.make.in | 2 +- > configure | 34 ++-------------------------------- > configure.ac | 24 ++++++------------------ > elf/rtld-Rules | 2 +- > 6 files changed, 38 insertions(+), 55 deletions(-) > > diff --git a/Makeconfig b/Makeconfig > index 2514db35f6..f6396b3e0c 100644 > --- a/Makeconfig > +++ b/Makeconfig > @@ -543,12 +543,13 @@ endif # +link > # ARM, gcc always produces different debugging symbols when invoked with > # a -O greater than 0 than when invoked with -O0, regardless of anything else > # we're using to suppress optimizations. Therefore, we need to explicitly pass > -# -O0 to it through CFLAGS. > +# -O0 to it through CFLAGS. By side effect, any fortification needs to be > +# disabled as it needs -O greater than 0. s/By side effect/As a result/ > # Additionally, the build system will try to -include $(common-objpfx)/config.h > # when compiling the tests, which will throw an error if some special macros > # (such as __OPTIMIZE__ and IS_IN_build) aren't defined. To avoid this, we > # tell gcc to define IS_IN_build. > -CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build > +CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build $(no-fortify-source) > > ifeq (yes,$(build-shared)) > # These indicate whether to link using the built ld.so or the installed one. > @@ -901,6 +902,11 @@ define elide-stack-protector > $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) > endef > > +# Some routine can't be fortified like the ones used by fortify > +define elide-fortify-source > +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-fortify-source)) > +endef > + > # The program that makes Emacs-style TAGS files. > ETAGS := etags > > @@ -961,6 +967,16 @@ endif # $(+cflags) == "" > $(+stack-protector) -fno-common > +gcc-nowarn := -w > > +# We must filter out elf because the early bootstrap of the dynamic loader > +# cannot be fortified. Likewise we exclude dlfcn because it is entangled > +# with the loader. We must filter out csu because early startup, like the > +# loader, cannot be fortified. Lastly debug is the fortification routines > +# themselves and they cannot be fortified. > +do-fortify = $(filter-out elf dlfcn csu debug,$(subdir)) > +ifneq ($(do-fortify),$(subdir)) > ++cflags += $(no-fortify-source) > +endif > + > # Each sysdeps directory can contain header files that both will be > # used to compile and will be installed. Each can also contain an > # include/ subdirectory, whose header files will be used to compile > @@ -1010,7 +1026,7 @@ module-cppflags = $(if $(filter %.mk.i %.v.i,$(@F)),,$(module-cppflags-real)) > # Note that we can't use -std=* in CPPFLAGS, because it overrides > # the implicit -lang-asm and breaks cpp behavior for .S files--notably > # it causes cpp to stop predefining __ASSEMBLER__. > -CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \ > +CPPFLAGS = $(config-extra-cppflags) $(CPPFLAGS-config) \ > $($(subdir)-CPPFLAGS) \ > $(+includes) $(defines) $(module-cppflags) \ > -include $(..)include/libc-symbols.h $(sysdep-CPPFLAGS) \ > @@ -1049,6 +1065,8 @@ object-suffixes := > CPPFLAGS-.o = $(pic-default) > # libc.a must be compiled with -fPIE/-fpie for static PIE. > CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default) > +CFLAGS-.o += $(call elide-fortify-source,.o,$(routines_no_fortify)) > +CFLAGS-.o += $(call elide-fortify-source,_chk.o,$(routines_no_fortify)) > libtype.o := lib%.a > object-suffixes += .o > ifeq (yes,$(build-shared)) > @@ -1058,6 +1076,8 @@ object-suffixes += .os > pic-cppflags = -DPIC -DSHARED > CPPFLAGS-.os = $(pic-cppflags) > CFLAGS-.os = $(filter %frame-pointer,$(+cflags)) $(pic-ccflag) > +CFLAGS-.os += $(call elide-fortify-source,.os,$(routines_no_fortify)) > +CFLAGS-.os += $(call elide-fortify-source,_chk.os,$(routines_no_fortify)) > libtype.os := lib%_pic.a > # This can be changed by a sysdep makefile > pic-ccflag = -fPIC > @@ -1077,6 +1097,8 @@ object-suffixes += .op > CPPFLAGS-.op = -DPROF $(pic-default) > # libc_p.a must be compiled with -fPIE/-fpie for static PIE. > CFLAGS-.op = -pg $(pie-default) > +CFLAGS-.op += $(call elide-fortify-source,.op,$(routines_no_fortify)) > +CFLAGS-.op += $(call elide-fortify-source,_chk.op,$(routines_no_fortify)) > libtype.op = lib%_p.a > endif > > diff --git a/NEWS b/NEWS > index 709ee40e50..2ec05cfe0f 100644 > --- a/NEWS > +++ b/NEWS > @@ -48,6 +48,9 @@ Major new features: > * The strlcpy and strlcat functions have been added. They are derived > from OpenBSD, and are expected to be added to a future POSIX version. > > +* Glibc now supports to be built with _FORTIFY_SOURCE. The value is undefined > + for parts of the library that can't be built with it. > + s/Glibc now supports to be built/The GNU C Library can now be built/ Also, s/The value is undefined/The macro is undefined/ > Deprecated and removed features, and other changes affecting compatibility: > > * In the Linux kernel for the hppa/parisc architecture some of the > diff --git a/config.make.in b/config.make.in > index 4afd37feaf..75ad9765aa 100644 > --- a/config.make.in > +++ b/config.make.in > @@ -64,6 +64,7 @@ have-fpie = @libc_cv_fpie@ > have-ssp = @libc_cv_ssp@ > stack-protector = @stack_protector@ > no-stack-protector = @no_stack_protector@ > +no-fortify-source = @no_fortify_source@ > have-selinux = @have_selinux@ > have-libaudit = @have_libaudit@ > have-libcap = @have_libcap@ > @@ -101,7 +102,6 @@ CXX = @CXX@ > BUILD_CC = @BUILD_CC@ > CFLAGS = @CFLAGS@ > CPPFLAGS-config = @CPPFLAGS@ > -CPPUNDEFS = @CPPUNDEFS@ > extra-nonshared-cflags = @extra_nonshared_cflags@ > rtld-early-cflags = @rtld_early_cflags@ > ASFLAGS-config = @ASFLAGS_config@ > diff --git a/configure b/configure > index f84040644b..7a15f8d3e6 100755 > --- a/configure > +++ b/configure > @@ -611,7 +611,7 @@ libc_cv_gcc_unwind_find_fde > libc_extra_cppflags > libc_extra_cflags > libc_cv_cxx_thread_local > -CPPUNDEFS > +no_fortify_source > have_selinux > have_libcap > have_libaudit > @@ -6353,38 +6353,8 @@ $as_echo "#define HAVE_LIBCAP 1" >>confdefs.h > fi > > > -CPPUNDEFS= > -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FORTIFY_SOURCE predefine" >&5 > -$as_echo_n "checking for _FORTIFY_SOURCE predefine... " >&6; } > -if ${libc_cv_predef_fortify_source+:} false; then : > - $as_echo_n "(cached) " >&6 > -else > - cat confdefs.h - <<_ACEOF >conftest.$ac_ext > -/* end confdefs.h. */ > - > -int > -main () > -{ > +no_fortify_source="-Wp,-U_FORTIFY_SOURCE" > > -#ifdef _FORTIFY_SOURCE > -# error bogon > -#endif > - ; > - return 0; > -} > -_ACEOF > -if ac_fn_c_try_compile "$LINENO"; then : > - libc_cv_predef_fortify_source=no > -else > - libc_cv_predef_fortify_source=yes > -fi > -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext > -fi > -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_predef_fortify_source" >&5 > -$as_echo "$libc_cv_predef_fortify_source" >&6; } > -if test $libc_cv_predef_fortify_source = yes; then > - CPPUNDEFS="${CPPUNDEFS:+$CPPUNDEFS }-U_FORTIFY_SOURCE" > -fi > > > { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler requires one version per symbol" >&5 > diff --git a/configure.ac b/configure.ac > index 21879c933c..ebc04d49e6 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -1559,24 +1559,12 @@ if test "x$have_selinux" = xyes; then > fi > AC_SUBST(have_selinux) > > -CPPUNDEFS= > -dnl Check for silly hacked compilers predefining _FORTIFY_SOURCE. > -dnl Since we are building the implementations of the fortified functions here, > -dnl having the macro defined interacts very badly. > -dnl _FORTIFY_SOURCE requires compiler optimization level 1 (gcc -O1) > -dnl and above (see "man FEATURE_TEST_MACROS"). > -dnl So do NOT replace AC_COMPILE_IFELSE with AC_PREPROC_IFELSE. > -AC_CACHE_CHECK([for _FORTIFY_SOURCE predefine], libc_cv_predef_fortify_source, > -[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ > -#ifdef _FORTIFY_SOURCE > -# error bogon > -#endif]])], > - [libc_cv_predef_fortify_source=no], > - [libc_cv_predef_fortify_source=yes])]) > -if test $libc_cv_predef_fortify_source = yes; then > - CPPUNDEFS="${CPPUNDEFS:+$CPPUNDEFS }-U_FORTIFY_SOURCE" > -fi > -AC_SUBST(CPPUNDEFS) > +dnl Create a variable that can be used to control were _FORTIFY_SOURCE is set. > +dnl This will allow users to enable fortification through FLAGS or compiler > +dnl defaults macro definitions. > +no_fortify_source="-Wp,-U_FORTIFY_SOURCE" > + > +AC_SUBST(no_fortify_source) > > dnl Starting with binutils 2.35, GAS can attach multiple symbol versions > dnl to one symbol (PR 23840). > diff --git a/elf/rtld-Rules b/elf/rtld-Rules > index 56bc4543de..365a3408f3 100644 > --- a/elf/rtld-Rules > +++ b/elf/rtld-Rules > @@ -144,6 +144,6 @@ cpp-srcs-left := $(rtld-modules:%.os=%) > lib := rtld > include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) > > -rtld-CFLAGS += $(no-stack-protector) > +rtld-CFLAGS += $(no-stack-protector) $(no-fortify-source) > > endif
diff --git a/Makeconfig b/Makeconfig index 2514db35f6..f6396b3e0c 100644 --- a/Makeconfig +++ b/Makeconfig @@ -543,12 +543,13 @@ endif # +link # ARM, gcc always produces different debugging symbols when invoked with # a -O greater than 0 than when invoked with -O0, regardless of anything else # we're using to suppress optimizations. Therefore, we need to explicitly pass -# -O0 to it through CFLAGS. +# -O0 to it through CFLAGS. By side effect, any fortification needs to be +# disabled as it needs -O greater than 0. # Additionally, the build system will try to -include $(common-objpfx)/config.h # when compiling the tests, which will throw an error if some special macros # (such as __OPTIMIZE__ and IS_IN_build) aren't defined. To avoid this, we # tell gcc to define IS_IN_build. -CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build +CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build $(no-fortify-source) ifeq (yes,$(build-shared)) # These indicate whether to link using the built ld.so or the installed one. @@ -901,6 +902,11 @@ define elide-stack-protector $(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector)) endef +# Some routine can't be fortified like the ones used by fortify +define elide-fortify-source +$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-fortify-source)) +endef + # The program that makes Emacs-style TAGS files. ETAGS := etags @@ -961,6 +967,16 @@ endif # $(+cflags) == "" $(+stack-protector) -fno-common +gcc-nowarn := -w +# We must filter out elf because the early bootstrap of the dynamic loader +# cannot be fortified. Likewise we exclude dlfcn because it is entangled +# with the loader. We must filter out csu because early startup, like the +# loader, cannot be fortified. Lastly debug is the fortification routines +# themselves and they cannot be fortified. +do-fortify = $(filter-out elf dlfcn csu debug,$(subdir)) +ifneq ($(do-fortify),$(subdir)) ++cflags += $(no-fortify-source) +endif + # Each sysdeps directory can contain header files that both will be # used to compile and will be installed. Each can also contain an # include/ subdirectory, whose header files will be used to compile @@ -1010,7 +1026,7 @@ module-cppflags = $(if $(filter %.mk.i %.v.i,$(@F)),,$(module-cppflags-real)) # Note that we can't use -std=* in CPPFLAGS, because it overrides # the implicit -lang-asm and breaks cpp behavior for .S files--notably # it causes cpp to stop predefining __ASSEMBLER__. -CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \ +CPPFLAGS = $(config-extra-cppflags) $(CPPFLAGS-config) \ $($(subdir)-CPPFLAGS) \ $(+includes) $(defines) $(module-cppflags) \ -include $(..)include/libc-symbols.h $(sysdep-CPPFLAGS) \ @@ -1049,6 +1065,8 @@ object-suffixes := CPPFLAGS-.o = $(pic-default) # libc.a must be compiled with -fPIE/-fpie for static PIE. CFLAGS-.o = $(filter %frame-pointer,$(+cflags)) $(pie-default) +CFLAGS-.o += $(call elide-fortify-source,.o,$(routines_no_fortify)) +CFLAGS-.o += $(call elide-fortify-source,_chk.o,$(routines_no_fortify)) libtype.o := lib%.a object-suffixes += .o ifeq (yes,$(build-shared)) @@ -1058,6 +1076,8 @@ object-suffixes += .os pic-cppflags = -DPIC -DSHARED CPPFLAGS-.os = $(pic-cppflags) CFLAGS-.os = $(filter %frame-pointer,$(+cflags)) $(pic-ccflag) +CFLAGS-.os += $(call elide-fortify-source,.os,$(routines_no_fortify)) +CFLAGS-.os += $(call elide-fortify-source,_chk.os,$(routines_no_fortify)) libtype.os := lib%_pic.a # This can be changed by a sysdep makefile pic-ccflag = -fPIC @@ -1077,6 +1097,8 @@ object-suffixes += .op CPPFLAGS-.op = -DPROF $(pic-default) # libc_p.a must be compiled with -fPIE/-fpie for static PIE. CFLAGS-.op = -pg $(pie-default) +CFLAGS-.op += $(call elide-fortify-source,.op,$(routines_no_fortify)) +CFLAGS-.op += $(call elide-fortify-source,_chk.op,$(routines_no_fortify)) libtype.op = lib%_p.a endif diff --git a/NEWS b/NEWS index 709ee40e50..2ec05cfe0f 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,9 @@ Major new features: * The strlcpy and strlcat functions have been added. They are derived from OpenBSD, and are expected to be added to a future POSIX version. +* Glibc now supports to be built with _FORTIFY_SOURCE. The value is undefined + for parts of the library that can't be built with it. + Deprecated and removed features, and other changes affecting compatibility: * In the Linux kernel for the hppa/parisc architecture some of the diff --git a/config.make.in b/config.make.in index 4afd37feaf..75ad9765aa 100644 --- a/config.make.in +++ b/config.make.in @@ -64,6 +64,7 @@ have-fpie = @libc_cv_fpie@ have-ssp = @libc_cv_ssp@ stack-protector = @stack_protector@ no-stack-protector = @no_stack_protector@ +no-fortify-source = @no_fortify_source@ have-selinux = @have_selinux@ have-libaudit = @have_libaudit@ have-libcap = @have_libcap@ @@ -101,7 +102,6 @@ CXX = @CXX@ BUILD_CC = @BUILD_CC@ CFLAGS = @CFLAGS@ CPPFLAGS-config = @CPPFLAGS@ -CPPUNDEFS = @CPPUNDEFS@ extra-nonshared-cflags = @extra_nonshared_cflags@ rtld-early-cflags = @rtld_early_cflags@ ASFLAGS-config = @ASFLAGS_config@ diff --git a/configure b/configure index f84040644b..7a15f8d3e6 100755 --- a/configure +++ b/configure @@ -611,7 +611,7 @@ libc_cv_gcc_unwind_find_fde libc_extra_cppflags libc_extra_cflags libc_cv_cxx_thread_local -CPPUNDEFS +no_fortify_source have_selinux have_libcap have_libaudit @@ -6353,38 +6353,8 @@ $as_echo "#define HAVE_LIBCAP 1" >>confdefs.h fi -CPPUNDEFS= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FORTIFY_SOURCE predefine" >&5 -$as_echo_n "checking for _FORTIFY_SOURCE predefine... " >&6; } -if ${libc_cv_predef_fortify_source+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ +no_fortify_source="-Wp,-U_FORTIFY_SOURCE" -#ifdef _FORTIFY_SOURCE -# error bogon -#endif - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - libc_cv_predef_fortify_source=no -else - libc_cv_predef_fortify_source=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_predef_fortify_source" >&5 -$as_echo "$libc_cv_predef_fortify_source" >&6; } -if test $libc_cv_predef_fortify_source = yes; then - CPPUNDEFS="${CPPUNDEFS:+$CPPUNDEFS }-U_FORTIFY_SOURCE" -fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler requires one version per symbol" >&5 diff --git a/configure.ac b/configure.ac index 21879c933c..ebc04d49e6 100644 --- a/configure.ac +++ b/configure.ac @@ -1559,24 +1559,12 @@ if test "x$have_selinux" = xyes; then fi AC_SUBST(have_selinux) -CPPUNDEFS= -dnl Check for silly hacked compilers predefining _FORTIFY_SOURCE. -dnl Since we are building the implementations of the fortified functions here, -dnl having the macro defined interacts very badly. -dnl _FORTIFY_SOURCE requires compiler optimization level 1 (gcc -O1) -dnl and above (see "man FEATURE_TEST_MACROS"). -dnl So do NOT replace AC_COMPILE_IFELSE with AC_PREPROC_IFELSE. -AC_CACHE_CHECK([for _FORTIFY_SOURCE predefine], libc_cv_predef_fortify_source, -[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ -#ifdef _FORTIFY_SOURCE -# error bogon -#endif]])], - [libc_cv_predef_fortify_source=no], - [libc_cv_predef_fortify_source=yes])]) -if test $libc_cv_predef_fortify_source = yes; then - CPPUNDEFS="${CPPUNDEFS:+$CPPUNDEFS }-U_FORTIFY_SOURCE" -fi -AC_SUBST(CPPUNDEFS) +dnl Create a variable that can be used to control were _FORTIFY_SOURCE is set. +dnl This will allow users to enable fortification through FLAGS or compiler +dnl defaults macro definitions. +no_fortify_source="-Wp,-U_FORTIFY_SOURCE" + +AC_SUBST(no_fortify_source) dnl Starting with binutils 2.35, GAS can attach multiple symbol versions dnl to one symbol (PR 23840). diff --git a/elf/rtld-Rules b/elf/rtld-Rules index 56bc4543de..365a3408f3 100644 --- a/elf/rtld-Rules +++ b/elf/rtld-Rules @@ -144,6 +144,6 @@ cpp-srcs-left := $(rtld-modules:%.os=%) lib := rtld include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) -rtld-CFLAGS += $(no-stack-protector) +rtld-CFLAGS += $(no-stack-protector) $(no-fortify-source) endif