0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

Merge bitcoin/bitcoin#27027: build: use _FORTIFY_SOURCE=3

4faa4e37a6 build: use _FORTIFY_SOURCE=3 (fanquake)

Pull request description:

  [glibc 2.33](https://sourceware.org/pipermail/libc-alpha/2021-February/122207.html) introduced a new fortification level, `_FORTIFY_SOURCE=3`. It improves the coverage of cases where `_FORTIFY_SOURCE` can use `_chk` functions.

  For example, using GCC 13 and glibc 2.36 (Fedora Rawhide), compiling master:
  ```bash
  nm -C src/bitcoind | grep _chk
                   U __fprintf_chk@GLIBC_2.17
                   U __memcpy_chk@GLIBC_2.17
                   U __snprintf_chk@GLIBC_2.17
                   U __sprintf_chk@GLIBC_2.17
                   U __stack_chk_fail@GLIBC_2.17
                   U __stack_chk_guard@GLIBC_2.17
                   U __vsnprintf_chk@GLIBC_2.17

  objdump -d src/bitcoind | grep "_chk@plt" | wc -l
  33
  ```

  vs this branch:
  ```bash
  nm -C src/bitcoind | grep _chk
                   U __fprintf_chk@GLIBC_2.17
                   U __memcpy_chk@GLIBC_2.17
                   U __memset_chk@GLIBC_2.17
                   U __snprintf_chk@GLIBC_2.17
                   U __sprintf_chk@GLIBC_2.17
                   U __stack_chk_fail@GLIBC_2.17
                   U __stack_chk_guard@GLIBC_2.17
                   U __vsnprintf_chk@GLIBC_2.17

  objdump -d src/bitcoind | grep "_chk@plt" | wc -l
  61
  ```

  Usage of level 3 requires LLVM/Clang 9+, or GCC 12+. Older compilers/glibc will still use _FORTIFY_SOURCE=2. For example, in the glibc we currently use for Linux release builds (2.24), `__USE_FORTIFY_LEVEL` is determined using the following:
  ```c
  #if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0
  # if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
  #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)
  # elif !__GNUC_PREREQ (4, 1)
  #  warning _FORTIFY_SOURCE requires GCC 4.1 or later
  # elif _FORTIFY_SOURCE > 1
  #  define __USE_FORTIFY_LEVEL 2
  # else
  #  define __USE_FORTIFY_LEVEL 1
  # endif
  #endif
  #ifndef __USE_FORTIFY_LEVEL
  # define __USE_FORTIFY_LEVEL 0
  #endif
  ```
  so any value > 1 will turn on `_FORTIFY_SOURCE=2`. This value detection logic has become slightly more complex in later versions of glibc.

  https://sourceware.org/pipermail/libc-alpha/2021-February/122207.html
  https://developers.redhat.com/blog/2021/04/16/broadening-compiler-checks-for-buffer-overflows-in-_fortify_source

ACKs for top commit:
  theuni:
    ACK 4faa4e37a6. After playing with this quite a bit I didn't observe any noticeable pitfalls.

Tree-SHA512: e84ba49e3872c29fed1e2aea237b0d6bdff0d1274fa3297e2e08317cb62004396ee97b1cd6addb7c8b582498f3fa857a6d84c8e8f5ca97791b93985b47ff7faa
This commit is contained in:
fanquake 2023-02-20 16:28:24 +00:00
commit 0561f344e0
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1

View file

@ -963,11 +963,11 @@ if test "$use_hardening" != "no"; then
dnl However, FORTIFY_SOURCE requires that there is some level of optimization, otherwise it does nothing and just creates a compiler warning.
dnl Since FORTIFY_SOURCE is a no-op without optimizations, do not enable it when enable_debug is yes.
if test "$enable_debug" != "yes"; then
AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[
AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=3],[
AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[
HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE"
])
HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2"
HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=3"
])
fi