-
Notifications
You must be signed in to change notification settings - Fork 37.7k
build: use _FORTIFY_SOURCE=3 #27027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: use _FORTIFY_SOURCE=3 #27027
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. |
https://sourceware.org/pipermail/libc-alpha/2021-February/122207.html:
Any estimations of the mentioned "additional performance overhead" for our binaries? |
Hahaha, I was just poking at this myself today. FYI support has been recently proposed to mingw as well: https://sourceforge.net/p/mingw-w64/mailman/message/37772473/
This was my hesitation as well. It'd be nice to have a before/after for our benches at least. Edit: Concept ACK, btw. And ACK after a quick bench shows it doesn't tank performace. |
Concept ACK Yeah, I ran the benchmarks before and after with both a Linux (GCC) and macOS (Clang) build and couldn’t see a significant change, not that I was expecting it on macOS at least. I may try more extensive measurements soon. |
In order to test this, I decided to try out the recommended fortify metrics plugin for gcc. I spent all day tracking down a bug in the plugin (PR'd what I believe to be the fix here). Next week I'll use it to gather some statistics on It will also be usable to test how much additional fortification we'd get if we built depends that way as well. |
heh. I had just sent a doc change up to glibc before opening: bminor/glibc@1423a26.
Looks like this has gone in mirror/mingw-w64@e34c747. Note I've also opened #27038 to add a sanity check that foritification (like other haardneing) is being used in the release binaries. |
Concept ACK Ran this on Ubuntu 22.04 with glibc 2.35 and clang 14. Also did not observe a significant slowdown of the benchmarks.
This branch:
|
glibc 2.33 introduced a new fortification level, _FORTIFY_SOURCE=3. Which 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), FORTIFY_LEVEL is determined using the following: ```c ``` so any value > 1 will turn on _FORTIFY_SOURCE=2. 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
7c277d4
to
4faa4e3
Compare
4faa4e3 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 4faa4e3. After playing with this quite a bit I didn't observe any noticeable pitfalls. Tree-SHA512: e84ba49e3872c29fed1e2aea237b0d6bdff0d1274fa3297e2e08317cb62004396ee97b1cd6addb7c8b582498f3fa857a6d84c8e8f5ca97791b93985b47ff7faa
This triggered https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56529 ? |
On my Gentoo system with GCC 11.3.1 and glibc 2.36 this now gives me these warnings for each .cpp file when building Bitcoin Core:
|
What's there? |
It will have been #27118 that triggered it. I can't look at this in more detail right now, but will by next week. It's possible that this is already fixed, and there is a patch/similar we can drop into depends.
Looks like that's because you're using GCC 11.x, which doesn't support >=3 (it is supported with Clang >= 9). Somewhat annoying that glibc is going to warn like that, but they are also harmless, and fortification (level 2) is still being applied. |
Could we somehow detect this at configure stage and apply fortification 3 only if it is supported? |
glibc 2.33 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:
vs this branch:
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: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