FS#18864 - Consider enabling GCC's stack-smashing protection (ProPolice, SSP) for all packages
Attached to Project:
Arch Linux
Opened by Pawel Stolowski (stolowski) - Sunday, 28 March 2010, 12:06 GMT
Last edited by Allan McRae (Allan) - Saturday, 20 August 2011, 09:10 GMT
Opened by Pawel Stolowski (stolowski) - Sunday, 28 March 2010, 12:06 GMT
Last edited by Allan McRae (Allan) - Saturday, 20 August 2011, 09:10 GMT
|
Details
Description:
Please consider enabling stack smashing protection (aka ProPolice) for all Arch packages. It adds only little overhead, but users will benefit from increased security of the default Arch installation and will be protected against a range of common software bugs and their exploitation. Additional info: Stack smashing protector is a GCC extension for protecting applications from stack-smashing attacks. It is available in stock GCC. It can be enabled by -fstack-protector or -fstack-protector-all compile flags. More information here: http://www.research.ibm.com/trl/projects/security/ssp/ |
This task depends upon
https://wiki.ubuntu.com/GccSsp
They implemented it in 2006 and the wiki lists some problems they encountered.
Also, -fstack-protector-all includes adding protection to functions whose buffer would normally be below the size limit for stack smashing protection.
1) add -fstack-protector (undecided about -all) and -D_FORTIFY_SOURCE=2 to our C{,XX}FLAGS in makepkg.conf. I will not take the approach of some other distros and patch these to be the default in our gcc build as that is not following upstream. (I know the gcc package currently does patch for hash-style but that will change in the future...)
2) consider adding -fPIE to our C{,XX}FLAGS on x86_64 only. Definitely not on i686...
3) consider adding -Wl,-z,now -Wl,-z,relro to our LDFLAGS
4) do a complete rebuild of the toolchain (and maybe some other "core" packages) with those flags and test. There still appears to be some areas of gcc that should not be built with these options (specifically -fstack-protector), so this will need to be done in a time where the toolchain is not expecting updates so it can receive some decent testing. Perhaps between binutils-2.21/glibc-2.13 and gcc-4.6 will be a good time.
edit: should -pie be added to LDFLAGS as well (for x86_64)?
Probably -Wl,-pie should of wiht -fPIE on x86_64.
http://www.chromium.org/chromium-os/chromiumos-design-docs/system-hardening
They have recommended this for hardening the toolchain:
Ensure that we don't optimize out NULL pointer checks as mmap(0) tricks are the current trend in kernel exploitation.
-fno-delete-null-pointer-checks
So their final list looks like this:
The userland toolchain should enforce a number of requirements (which will need benchmarking):
-fno-delete-null-pointer-checks
-fstack-protector: stack canary
-pie: relocatable executables (and marked ET_DYN)
-Wl,-z,relro: read-only relocations
FORTIFY_SOURCE
This is pretty important from a security perspective. NX and partial ASLR do not protect against stack overflows, even on x86_64.
Any update here? Anything I can do to help?
-fstack-protector -Wl,-z,relro -D_FORTIFY_SOURCE=2 in my makepkg.conf. I haven't seen any builds break because of this. Full RELRO ie. with -Wl,-z,now,-z,relro is known to cause slowdown since it disables the lazy loading used by the linker. Coming to PIE, this would require changes to both cflags and ldflags and can break builds which use inline assembly among others, and also library only builds which require fPIC. I also recommending using
checksec.sh from http://www.trapkit.de/tools/checksec.html to audit the system before and after. Speaking of kernel, stack protection must be enabled already as stated before and sysctl kernel.randomize_va_space should be 2 if set otherwise.
Using -D_FORTIFY_SOURCE=2 -fstack-protector (Afaik Debian adds --param ssp-buffer-size=4 too?)
globally seems to be pretty easy to pull off and should probably be enabled as soon as possible. Only a few builds will break, that will be an easy clean up though.
Wl,-z,relro should probably be global. Wl,-z,now could suck for startup times of big programs, so enable only for critical and/or small stuff.
(I also propose the usage of -Wl,-O1, while irrelevant to the security aspect, it seem's to provide enough benefits that it's used by default on Gentoo.)
Here's a >small< shell script that can be used to verify success on individual files - taken from one of the Debian hardening packages: http://sprunge.us/FZGK?sh
For reference, here's the output of the script mentioned by Raghavendra from someone running Ubuntu (Maverick): http://pastie.org/private/ptexeq8zfyyo16vh0q
After this is done, nominate candidates for "advanced" flags such as -fPIE. (I.e ssh, postfix etc.)
Given that I tend to have a lot of beefy hardware around me implementing this for my own was rather easy. Sticking it in makepkg.conf is not as good as patching the toolchain due to packages that ignore the environment etc. but it's a very good start.
Right now, going from pretty much any major distribution to Arch Linux comes with a real loss of security - not even considering the lack of package signing which saw some good progress in the past weeks for which I'm very glad :)
I hope the Arch Linux developers can find a away to get this into the packaging process soon.
Want: -D_FORTIFY_SOURCE=2 -fstack-protector (--param ssp-buffer-size=4 seems to be popular across distributions.) and -Wl,-z,relro.
Thanks for reading.
CFLAGS="-march=XXX -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,--hash-style=gnu"
The glibc-2.14 toolchain has only been out of [testing] for a week or two. I'd like to wait another couple of weeks before I adjust the toolchain PKGBUILDs to deal with these flags. There seems to be no big glibc/binutils/gcc updates for a while so this is probably a good window to do this.
There will be no patching of the toolchain to make these the default. If upstream considered that an option, it would be done there (like how configuring --hash-style has been done for gcc-4.7...). Packages that ignore CFLAGS/LDFLAGS are either broken upstream, broken in packaging, or deliberately ignoring them and should be dealt with on an individual basis. (FYI, around 5% of [core] ignores CFLAGS and 10% LDFLAGS)