[arch-dev-public] Adding hardening compiler/linker flags
There have been requests for some hardening of our default CFLAGS/LDFLAGS (e.g. FS#18864). I believe this was discussed on this list previously and there were no real objections. So actually doing this has been on the table for some time but has been delayed by a combination of lack of time on my behalf and inconvenient timing with toolchain updates. I think now would be a good time to look at doing this. The plan is to add "-fstack-protector-all -D_FORTIFY_SOURCE=2 --param=ssp-buffer-size=4" to our C{XX}FLAGS and "-Wl,-z,relro" to our LDFLAGS. We could also add "-Wl,-O1" and maybe "-Wl,--sort-common" to our LDFLAGS at the same time for some optimisation. I am taking the approach of adding C/CXX/LDFLAGS rather than the patching the default compiler options approach most other distros use as it is more consistent with our patching policy and will reduce my maintenance burden. It also make it easier to disable an option if necessary by just changing their values. The disadvantage being that we have to make sure software listens to our CFLAGS values... What I do not intend to add: -Wl,-z,now - has a performance hit (mainly for large programs?). -fPIE -pie - large performance hit (5-10%) on i686, almost none on x86_64 These should be enabled for individual programs as the maintainer sees fit. PIE stuff is also more difficult and would probably require patching of the gcc specs file to start dealing with properly and would still lead to a bunch of issues. So that is something that I may look at in the distant future for x86_64 only. So the plan is.... 1) Finalise the CFLAGS/LDFLAGS 2) I get the toolchain built and working with these 3) I upload a pacman package with the changed makepkg.conf 4) Consider a [core] rebuild ??? Starting with #1. Are there any comments on the proposed CFLAGS/LDFLAGS or any further additions that people think might be of use at the same time. Allan
[2011-05-05 01:29:17 +1000] Allan McRae:
The plan is to add "-fstack-protector-all -D_FORTIFY_SOURCE=2 --param=ssp-buffer-size=4" to our C{XX}FLAGS and "-Wl,-z,relro" to our LDFLAGS.
Using these flags to build random packages, they appear to increase the typical binary size by roughly 6%. That's not too bad but could you say a bit more on the pros of enabling them for me and others who weren't devs when this was first discussed? Thanks. -- Gaetan
On 05/05/11 05:26, Gaetan Bisson wrote:
[2011-05-05 01:29:17 +1000] Allan McRae:
The plan is to add "-fstack-protector-all -D_FORTIFY_SOURCE=2 --param=ssp-buffer-size=4" to our C{XX}FLAGS and "-Wl,-z,relro" to our LDFLAGS.
Using these flags to build random packages, they appear to increase the typical binary size by roughly 6%. That's not too bad but could you say a bit more on the pros of enabling them for me and others who weren't devs when this was first discussed?
What these flags do: -D_FORTIFY_SOURCE=2 Adds a very, very lightweight buffer overflow protection to some memory and string functions. As much as possible is checked at compile time. See http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html for the details. -fstack-protector More buffer overflow prevention. This uses the canary approach to detecting buffer overflows so has some minor runtime overhead but does prevent an entire class of attacks (and a common class...). See http://en.wikipedia.org/wiki/Buffer_overflow_protection#GCC_Stack-Smashing_P... . -fstack-protector does this for strings only. Note I have dropped the "-all" at the end of "-fstack-protector" after discussion with several people regarding the overhead and other potential issues. --param=ssp-buffer-size=4 The buffer size flag sets the size of the array required before stack protection is activated. The default is 8 but Fedora and Suse (and possibly Ubuntu) all adjust this to 4, as does Hardened Gentoo and HLFS. -Wl,-z,relro Puts commonly exploited ELF structures into (sort of...) read-only locations. The other LDFLAGS I suggested: -Wl,-O1 Optimisation level for ld (just like the gcc flags) -Wl,--sort-common Prevents gaps between symbols due to alignment constraints. This presumably results in increased efficiency in the layout and the associated performance gain. Both those should really have been added when we first added LDFLAGS. Allan
Am 05.05.2011 13:44, schrieb Allan McRae:
-fstack-protector More buffer overflow prevention. This uses the canary approach to detecting buffer overflows so has some minor runtime overhead but does prevent an entire class of attacks (and a common class...). See http://en.wikipedia.org/wiki/Buffer_overflow_protection#GCC_Stack-Smashing_P... . -fstack-protector does this for strings only.
This has been enabled in our kernels for years. No idea if it helps with anything, but our kernels still work.
[2011-05-05 21:44:43 +1000] Allan McRae:
What these flags do:
Thanks for explaining this, Allan. Adding these flags indeed makes a lot of sense. And I note that the space overheard of -fstack-protector is barely noticeable (much less than -fstack-protector-all which had gotten me worried a little). -- Gaetan
Le 4 mai 2011 11:29:17, Allan McRae a écrit :
There have been requests for some hardening of our default CFLAGS/LDFLAGS (e.g. FS#18864). I believe this was discussed on this list previously and there were no real objections. So actually doing this has been on the table for some time but has been delayed by a combination of lack of time on my behalf and inconvenient timing with toolchain updates. I think now would be a good time to look at doing this.
The plan is to add "-fstack-protector-all -D_FORTIFY_SOURCE=2 --param=ssp-buffer-size=4" to our C{XX}FLAGS and "-Wl,-z,relro" to our LDFLAGS. We could also add "-Wl,-O1" and maybe "-Wl,--sort-common" to our LDFLAGS at the same time for some optimisation.
I am taking the approach of adding C/CXX/LDFLAGS rather than the patching the default compiler options approach most other distros use as it is more consistent with our patching policy and will reduce my maintenance burden. It also make it easier to disable an option if necessary by just changing their values. The disadvantage being that we have to make sure software listens to our CFLAGS values...
What I do not intend to add:
-Wl,-z,now - has a performance hit (mainly for large programs?). -fPIE -pie - large performance hit (5-10%) on i686, almost none on x86_64
These should be enabled for individual programs as the maintainer sees fit. PIE stuff is also more difficult and would probably require patching of the gcc specs file to start dealing with properly and would still lead to a bunch of issues. So that is something that I may look at in the distant future for x86_64 only.
So the plan is....
1) Finalise the CFLAGS/LDFLAGS 2) I get the toolchain built and working with these 3) I upload a pacman package with the changed makepkg.conf 4) Consider a [core] rebuild ???
Starting with #1. Are there any comments on the proposed CFLAGS/LDFLAGS or any further additions that people think might be of use at the same time.
Allan
Debian has a nice "hardening-check" script [1] to verify that an ELF binary have hardening features enabled. Maybe we could include something similar in our devtools ? Stéphane [1] http://packages.debian.org/sid/hardening-includes
participants (4)
-
Allan McRae
-
Gaetan Bisson
-
Stéphane Gaudreault
-
Thomas Bächler