From 4c05f3cfa21b984db3d0a0c36253a6ac84cbc0f6 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 14 Dec 2022 11:28:14 -0500 Subject: [PATCH] Enable _FORTIFY_SOURCE=3 by default Make the _FORTIFY_SOURCE flags configurable so that the command line is not cluttered with _FORTIFY_SOURCE definitions and undefines. Introduce a %_fortify_level variable that a package may override by either undefining or defining to a specific value. Also bump the default value to 3, to implement the systemwide proposal for Fedora 38: https://fedoraproject.org/wiki/Changes/Add_FORTIFY_SOURCE%3D3_to_distribution_build_flags --- buildflags.md | 37 +++++++++++++++++++++++++++---------- macros | 8 +++++++- redhat-rpm-config.spec | 5 ++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/buildflags.md b/buildflags.md index 47b79f9..46e8401 100644 --- a/buildflags.md +++ b/buildflags.md @@ -172,6 +172,30 @@ This turns off certain hardening features, as described in detail below. The main difference is that executables will be position-dependent (no full ASLR) and use lazy binding. +### Source Fortification + +By default, the build flags include `-Wp,-D_FORTIFY_SOURCE=3`: Source +fortification activates various hardening features in glibc: + +* String functions such as `memcpy` attempt to detect buffer lengths + and terminate the process if a buffer overflow is detected. +* `printf` format strings may only contain the `%n` format specifier + if the format string resides in read-only memory. +* `open` and `openat` flags are checked for consistency with the + presence of a *mode* argument. +* Plus other minor hardening changes. + +These changes can, on rare occasions, break valid programs. The source +fortification level can be overridden by adding this in the RPM spec file: + + %define _fortify_level 2 + +to reduce source fortification level to 2 or: + + %undefine _fortify_level + +to disable fortification altogether. + ### Annotated builds/watermarking By default, the build flags cause a special output section to be @@ -377,16 +401,9 @@ The general (architecture-independent) build flags are: This can occasionally result in compilation errors. In that case, the best option is to rewrite the source code so that only constant format strings (string literals) are used. -* `-Wp,-D_FORTIFY_SOURCE=2`: Source fortification activates various - hardening features in glibc: - * String functions such as `memcpy` attempt to detect buffer lengths - and terminate the process if a buffer overflow is detected. - * `printf` format strings may only contain the `%n` format specifier - if the format string resides in read-only memory. - * `open` and `openat` flags are checked for consistency with the - presence of a *mode* argument. - * Plus other minor hardening changes. - (These changes can occasionally break valid programs.) +* `-U_FORTIFY_SOURCE, -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=3`: + See the Source Fortification section above and the `%_fortify_level` + override. * `-fexceptions`: Provide exception unwinding support for C programs. See the [`-fexceptions` option in the GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fexceptions) diff --git a/macros b/macros index 938f9eb..3b51ba0 100644 --- a/macros +++ b/macros @@ -362,13 +362,19 @@ print(result) %_clang_lto_cflags -flto %_lto_cflags %{expand:%%{_%{toolchain}_lto_cflags}} +# Default fortification level. +# "%define _fortify_level 2" to downgrade and +# "%define _fortify_level 0" or "%undefine _fortify_level" to disable +%_fortify_level 3 +%_fortify_level_flags %[ 0%{?_fortify_level} > 0 ? "-U_FORTIFY_SOURCE -Wp,-U_FORTIFY_SOURCE -Wp,-D_FORTIFY_SOURCE=%{_fortify_level}" : "" ] + # Some linkers default to a build-id algoritim that is not supported by rpmbuild, # so we need to specify the right algorithm to use. %_build_id_flags -Wl,--build-id=sha1 %_general_options -O2 %{?_lto_cflags} -fexceptions -g -grecord-gcc-switches -pipe %_warning_options -Wall -Werror=format-security -%_preprocessor_defines -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS +%_preprocessor_defines %{_fortify_level_flags} -Wp,-D_GLIBCXX_ASSERTIONS # Common variables are no longer generated by default by gcc and clang # If they are needed then add "%define _legacy_common_support 1" to the spec file. diff --git a/redhat-rpm-config.spec b/redhat-rpm-config.spec index bd8bf57..08bcb07 100644 --- a/redhat-rpm-config.spec +++ b/redhat-rpm-config.spec @@ -4,7 +4,7 @@ # 2) When making changes, increment the version (in baserelease) by 1. # rpmdev-bumpspec and other tools update the macro below, which is used # in Version: to get the desired effect. -%global baserelease 236 +%global baserelease 237 Summary: Red Hat specific rpm configuration files Name: redhat-rpm-config @@ -221,6 +221,9 @@ install -p -m 644 -t %{buildroot}%{_rpmluadir}/fedora/srpm forge.lua %doc buildflags.md %changelog +* Tue Jan 3 2023 Siddhesh Poyarekar - 237-1 +- Make _FORTIFY_SOURCE configurable and bump default to 3. + * Wed Dec 28 2022 Davide Cavalca - 236-1 - Add conditional support for always including frame pointers