The Fedora guys have patches to implement -fstack-protector for gcc 4.0.x snapshots (latest Fedora development gcc snapshot SRPMS). Unfortunately it seems that the patch doesn't apply cleanly against Vanilla gcc. The changes between the vanilla gcc and the snapshot Fedora is using seem minimal (most patches are applied externally as usual anyway... (?)). Well, I hacked together a gcc 4.0.1.20050720 ebuild http://www2.saout.de/gentoo/gcc/ based on the Fedora SRPM (download URLs are broken, but distfiles included). It's really a hack. I only took the most necessary parts from piepatches and omitted everything that didn't seem necessary. The only architectures this currently works at the moments are x86 and x86_64. Well, in the end you'll get a gcc with the five usual profiles. Vanilla, hardened and the nopie, nossp, nopiessp. I've only really tested hardened-nopie so far, but this seems rock solid. The ssp patches are quite different from the old IBM propolice one though, a reimplementation (compatible with the upcoming vanilla gcc 4.1 one). The main differences are: - uses different symbols in glibc (or external libssp, unsupported by my ebuild): __stack_chk_fail instead of __stack_smash_handler. The stack guard symbol __guard is now called __stack_chk_guard. But only for a non-TLS build. In the case of a TLS glibc it's stored directly in the TLS so you don't need a GOT lookup in libraries. - -fno-stack-protector-all is disallowed (only -fno-stack-protector, -fstack-protector or -fstack-protector all). My ebuild currently disabled this check since the Gentoo toolchain sometimes relies on -fno-stack-protector-all - the __stack_chk_* symbols are in the latest mainline glibc snapshost along with Redhat's other new *_chk symbols which are used with the -D_FORTIFY_SOURCE buffer overflow checks. - glibc needs a bunch of -fno-stack-protector when compiling some source files (mainly csu and rtld) so nobody tries to use TLS before it's actually set up. ( http://www2.saout.de/gentoo/glibc/glibc-2.3.5-rtld-stack-protector.patch ) - on architectures that need a register to store the GOT pointer in PIC code (x86) gcc will create code that calls __stack_chk_fail_local instead of __stack_chk_fail@plt. This __stack_chk_fail_local symbol is automatically pulled in at link time via libgcc_nonshared.a (the hidden __stack_chk_fail_local then calls the __stack_chk_fail from glibc). The reason is to save a costly GOT pointer setup for functions that wouldn't need it otherwise. Anyway, the old stack protector symbols can still be compiled into glibc to support older binaries, both mechanisms can coexist. I also compiled a whole system (system + world) with -D_FORTIFY_SOURCE=1 which also works nicely. The only package that didn't like that was python. _FORTIFY_SOURCE is a compile-time only feature which is implemented at preprocess time. It uses a gcc 4.x feature that can determine the size of destination arrays. The preprocessor then calls e.g. __memcpy_chk instead of plain memcpy and also passes the size of the destination array (if known at compile time) and additional checks are added to make sure the destination array can't overflow. In /usr/include/(gentoo-multilib/*)/features.h the GNUC_PREREQ check needs to be changed from (4, 1) to (4, 0) if you want it to work with this gcc snapshot. The Fedora guys have compiled FC4 with -D_FORTIFY_SOURCE=2, I only did it with -D_FORTIFY_SOURCE=1, since I think the other one is overkill. Perhaps -D_FORTIFY_SOURCE could be turned on in a hardened gcc by default? Well, anyway. My hacked gcc and glibc ebuilds are running on an amd64 multilib 2005.0 without problems. Everything compiled with hardened-nopie and -D_FORTIFY_SOURCE=1. No libssp, non-TLS tested. Only nptlonly tested. I think the Fedory guys did a great job. Portage 2.0.51.22-r2 (default-linux/amd64/2005.1, gcc-4.0.1-20050720-hardenednopie, glibc-2.3.5.20050725-r0, 2.6.12-rc1-cs2 x86_64) ================================================================= System uname: 2.6.12-rc1-cs2 x86_64 AMD Athlon(tm) 64 Processor 3000+ Gentoo Base System version 1.12.0_pre2 distcc 2.18.3 x86_64-pc-linux-gnu (protocols 1 and 2) (default port 3632) [disabled] dev-lang/python: 2.3.5-r1, 2.4.1-r1 sys-apps/sandbox: 1.2.11 sys-devel/autoconf: 2.13, 2.59-r7 sys-devel/automake: 1.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.6 sys-devel/binutils: 2.16.1, 2.16.91.0.1 sys-devel/libtool: 1.5.18-r1 virtual/os-headers: 2.6.11-r2 ACCEPT_KEYWORDS="amd64 ~amd64" AUTOCLEAN="yes" CBUILD="x86_64-pc-linux-gnu" CFLAGS="-O2 -march=athlon64 -pipe -D_FORTIFY_SOURCE=1" CHOST="x86_64-pc-linux-gnu" [...]
How about taking advantage of the TARGET_LIBC_PROVIDES_SSP define?
The only thing I found was the _LIBC_PROVIDES_SSP_ which is set by toolchain.eclass. The old ssp patch was listening to that. The new one from Fedora is quite different. Id does this check at configure time by parsing /usr/include/features.h to find out if the glibc is recent enough. Unfortunately this fails is it is just a wrapper aroung /usr/include/gentoo-multilib/*/features.h. I could have changed the patch but I decided to leave it alone as much as possible because this is the direction vanilla gcc 4.1 is going too. So I just used sed to override this check. I know it's a hack and this ebuild is not meant for inclusion, just as a starting point. Since this stack protector patch uses other symbols too the libc_has_ssp function in toolchain.eclass will detect the symbols from the old stack protector patch and not the new ones.
Okay, you are right. The new ssp patch also uses the _LIBC_PROVIDES_SSP_ define internally, I didn't see that first. A small correction to my start post: Of course I meant libc_nonshared.a instead of libgcc_nonshared.a
The first reference I saw to redhat not totally breaking it for everybody and including a TARGET_LIBC_PROVIDES_SSP was here. http://gcc.gnu.org/ml/gcc-patches/2005-07/msg00256.html We do not wish to break our existing users ssp/hardened installs if we can help it. So this must be backwords compat with our existing installs. IE without any -lssp
My ebuild doesn't support -lssp anyway. The ssp patch in the latest Fedora snapshot uses _LIBC_PROVIDES_SSP_ just like Gentoo, not TARGET_LIBC_PROVIDES_SSP. A bit messy? Anyway, -D_LIBC_PROVIDES_SSP does not work. The stage2 gcc compile fails with genmodes.c:(.text+0x7): undefined reference to `__stack_chk_guard' This is because if xgcc is compiled without that define and will assume that the TLS based stack guard is not available and will create references to __stack_chk_guard (instead of using %fs:0x28 or %gs:0x14). So - Either pass -D_LIBC_PROVIDES_SSP to the stage1 build too - use the sed command to patch configure like in my first ebuild - fix the glibc detection itself in the configure script - Make glibc unconditionally provide __stack_chk_guard even if the TLS stack guard is used by default. What do you think? I've reuploaded my ebuild and annotated with (a lot of) FIXMEs.
http://sourceware.org/ml/libc-hacker/2005-06/msg00011.html
Ah, ok, so he doesn't want to export the guard if it shouldn't be used because it would probably create more confusion. Good. So then the toolchain.eclass should be modified to also pass that define to the stage1 compiler pass too. Also, since ssp is included with gcc 4.1 (and there isn't really a IBM propolice gcc 3.x style external patch tarball for SSP for gcc 4.0) the toolchain mechanism should also be changed to create ssp specs if the compiler already supports ssp out of the box (or using a patch in one of the standard patchsets), even if PP_VER isn't explicitly set. So, instead of hacking around in the gcc ebuilds, would it be okay for you to change the toolchain.eclass? If yes, I can try to provide patches. BTW: I've compiled two whole x86_64 and i686 systems with ssp and FORTIFY_SOURCE and they've been running without problems for over a week now. So I think we really should get forward since the stuff seems to be in pretty good shape and some devs are already thinking about getting gcc4 out of -* and into an experimental profile. I'm going to figure out the differences between the gcc-4.0-vanilla and gcc-4.0-redhat CVS trees so that the ssp patch can also be applied to the gcc releases/snapshots from gcc.gnu.org.
Chris, As of right now there is no rush from our side to see gcc-4.1 in the tree. I'm quite happy that your taking these initial porting steps on behalf of the community. I myself am not ready to make the jump to a newer glibc/kernel/compiler. I'm also personally not ready to give up linuxthreads support.. Needless to say I don't merge things I can't test. As far as toolchain changes go.. Yeah man bring them on attach them here and I'll add the right people to the CC: for review and merging considerations of all the code.
Ok, news update: I managed to get the changes between the vanilla <-> redhat gcc CVS tree into two clean patches. They're not very intrusive. The first one adds a bunch of compiler builtins (which are used by the _FORTIFY_SOURCE features in the glibc headers), and another one that mostly cleans up stack related defines in gcc internal headers. Both patches are required for the actual ssp patch. I've put these three patches into the patchset (they're the last three). They don't clash with any other patches so it's nice. Also, they make gcc compatible with 4.1 feature-wise. That's why I decided to add general ${GCCMAJOR} >= 4 handling and add checks if ssp has been patched into gcc for gcc 4.0. We know that gcc 4.1 and always are. Some people have tested the ebuild and they seem rather happy with the resulting gcc (no regressions over gcc-4.0.1.ebuild reported). Running two whole systems (x86 and amd64) with USE=hardened with this gcc here. My stuff is here now: http://www2.saout.de/gentoo/gcc/testing/
Created attachment 65779 [details, diff] toolchain.eclass modifications to make it aware of gcc-4.x style native ssp support gcc 4.x and above might have native ssp support. Also try to create ssp profiles in this case. Also, check for the gcc-4.x-ssp style stack smash handler function in glibc. And pass TARGET_LIBC_PROVIDES_SSP define to compiler.
The above toolchain.eclass patch is just a proposal, probably could be done better. With it the corresponding gcc ebuild can be cleaned up nicely. A current gcc 4.0 ebuild for testing looks like this now: http://www2.saout.de/gentoo/gcc/testing/gcc-4.0.2_beta20050804.ebuild I didn't need to omit some random architectures like last time. Every patch applies cleanly now. Only tested on x86 and amd64 so far though. Here's the corresponding patchset: http://www2.saout.de/gentoo/gcc/testing/gcc-4.0.2-patches-1.0.tar.bz2 The patchset is a combination of the gcc-4.0.1 Gentoo patches (minus some fixed PRs) and a bunch of new patches, collected by Redhat people and dirtyepic (see gcc 4.0 thread). The last three are then the security-related patches, see above. All other files are fetched automatically from the correct locations (official gcc snapshot, official Gentoo piepatches).
Created attachment 65785 [details, diff] Fixed toolchain patch Don't forget to set S back to OLDS since the change to S isn't limited to the local scope of gcc_do_make! Otherwise the ssp specs files might not be generated. Also prevent CRTSTUFF from being compiled with stack-protector (like for gcc 3.x).
I finished migrating my server running hardened to gcc4 yesterday. I used a 20051117 snapshot of gcc 4.0.2 + Christophes work and the latest ssp patches from fedora CVS (modified to allow -fno-stack-protector-all). The glibc is a 20051122 snapshot from HEAD with various fixes from suse. Everything is running stable and without problems so far. The only packages I had to use from unstable was: dhcp 3.0.3 (stable versions doesn't build with gcc4) prelink 20050610 (stable version fails testsuit with gcc4) pam-login 4.0.12 (stable version didn't like -D_FORTIDY_SOURCE) shadow 4.0.13 (depend of pam-login) The rest is from stable except gcc4 and glibc of course. The only package that couldn't be built with -D_FORTIDY_SOURCE was python. More info here: http://mail.python.org/pipermail/python-dev/2005-September/056353.html These might also be related: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=169046 https://sourceforge.net/tracker/index.php?func=detail&aid=1298813&group_id=5470&atid=305470 I vote for Christophes work being included so people can start experimenting with it! Portage 2.0.51.22-r3 (hardened/x86/2.6, gcc-4.0.2-20051117, glibc-2.3.90.20051122-r0, 2.6.14-ck6 i686) ================================================================= System uname: 2.6.14-ck6 i686 Pentium III (Katmai) Gentoo Base System version 1.6.13 dev-lang/python: 2.4.2 sys-apps/sandbox: 1.2.12 sys-devel/autoconf: 2.13, 2.59-r6 sys-devel/automake: 1.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.6-r1 sys-devel/binutils: 2.16.1 sys-devel/libtool: 1.5.20 virtual/os-headers: 2.6.11-r2 ACCEPT_KEYWORDS="x86" AUTOCLEAN="yes" CBUILD="i686-pc-linux-gnu" CFLAGS="-O2 -march=pentium3 -pipe -fomit-frame-pointer -fno-ident -D_FORTIFY_SOURCE=1" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc /usr/kde/2/share/config /usr/kde/3/share/config /usr/share/config /var/qmail/control" CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo /etc/env.d" CXXFLAGS="-O2 -march=pentium3 -pipe -fomit-frame-pointer -fno-ident -D_FORTIFY_SOURCE=1 -fvisibility-inlines-hidden" DISTDIR="/usr/portage/distfiles" FEATURES="autoconfig distlocks sandbox sfperms strict" GENTOO_MIRRORS="http://localhost/ ftp://mirror.pudas.net/gentoo/ ftp://ftp.rhnet.is/pub/gentoo/ ftp://linux.rz.ruhr-uni-bochum.de/gentoo-mirror/ http://ftp.rhnet.is/pub/gentoo/" LANG="sv_SE.UTF-8" LC_ALL="sv_SE.UTF-8" LINGUAS="sv" MAKEOPTS="-j2" PKGDIR="/usr/portage//packages/x86/" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage/" PORTDIR_OVERLAY="/usr/local/portage" SYNC="rsync://rsync.gentoo.org/gentoo-portage" USE="aalib acpi alsa apache2 apm audiofile avi berkdb bzip2 cdb ck-server crypt cups dlloader expat f77 fbcon gdbm gif glibc-omitfp gpm hardened imagemagick ipv6 ithreads jpeg libwww mad mhash mikmod mmx mmxext mng mysql ncurses nls nomalloccheck nptl nptlonly objc offensive ogg oggvorbis pam pcre pdflib perl pic png pnp print python quicktime readline real recode samba sdl slang sse ssl svga symlink tcpd threads tiff truetype-fonts type1-fonts udev usb userlocales utf8 vorbis win32codecs x86 xml2 zlib linguas_sv userland_GNU kernel_linux elibc_glibc" Unset: ASFLAGS, CTARGET, LDFLAGS [1] i686-pc-linux-gnu-4.0.2-20051117 * [2] i686-pc-linux-gnu-4.0.2-20051117-hardenednopie [3] i686-pc-linux-gnu-4.0.2-20051117-hardenednopiessp [4] i686-pc-linux-gnu-4.0.2-20051117-hardenednossp [5] i686-pc-linux-gnu-4.0.2-20051117-vanilla
We can probably close this bug as WONTFIX since we have gcc-4.1 now. I'll leave that up to you guys though.
Yeah; we just haven't had the time or inclination to get SSP into 4.0.x, and 4.1.0 has followed relatively quickly on the heels of 4.0.x. For our uses, it's simplest just to mask 4.0 and go with 4.1, once we have *libc sorted out.
Well, with the gcc patches applied gcc 4.0 behaves behaves more or less exactly like gcc 4.1 from the SSP and _FORTIFY_SOURCE point of view. The only difference is that gcc 4.0 doesn't come with a bundled libssp (so it relies on solely glibc 2.4). But actually I don't care since I'm quite happy with gcc 4.1 and there is no reason to just completely skip gcc 4.0, I agree with you on that one.