Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 100689 - (highly experimental) hardened gcc 4.0.x
Summary: (highly experimental) hardened gcc 4.0.x
Status: RESOLVED WONTFIX
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Hardened (show other bugs)
Hardware: All Linux
: High enhancement
Assignee: The Gentoo Linux Hardened Team
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Whiteboard:
Keywords:
Depends on: 106222
Blocks:
  Show dependency tree
 
Reported: 2005-07-29 04:22 UTC by Christophe Saout
Modified: 2006-03-11 01:56 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
toolchain.eclass modifications to make it aware of gcc-4.x style native ssp support (toolchain.eclass.patch,3.44 KB, patch)
2005-08-12 12:21 UTC, Christophe Saout
Details | Diff
Fixed toolchain patch (toolchain.eclass.patch,3.77 KB, patch)
2005-08-12 14:29 UTC, Christophe Saout
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Christophe Saout 2005-07-29 04:22:16 UTC
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"
[...]
Comment 1 solar (RETIRED) gentoo-dev 2005-07-29 16:25:50 UTC
How about taking advantage of the TARGET_LIBC_PROVIDES_SSP define?
Comment 2 Christophe Saout 2005-07-30 02:59:15 UTC
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.
Comment 3 Christophe Saout 2005-07-30 04:58:53 UTC
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
Comment 4 solar (RETIRED) gentoo-dev 2005-07-30 05:27:10 UTC
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 
Comment 5 Christophe Saout 2005-07-30 05:54:05 UTC
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.
Comment 7 Christophe Saout 2005-08-09 05:20:12 UTC
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.
Comment 8 solar (RETIRED) gentoo-dev 2005-08-09 15:20:06 UTC
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.
Comment 9 Christophe Saout 2005-08-12 12:17:14 UTC
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/
Comment 10 Christophe Saout 2005-08-12 12:21:25 UTC
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.
Comment 11 Christophe Saout 2005-08-12 12:32:23 UTC
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).
Comment 12 Christophe Saout 2005-08-12 14:29:35 UTC
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).
Comment 13 Simon Strandman 2005-11-28 01:38:04 UTC
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
Comment 14 Mark Loeser (RETIRED) gentoo-dev 2006-03-10 17:32:17 UTC
We can probably close this bug as WONTFIX since we have gcc-4.1 now.  I'll leave that up to you guys though.
Comment 15 Kevin F. Quinn (RETIRED) gentoo-dev 2006-03-11 01:02:46 UTC
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.
Comment 16 Christophe Saout 2006-03-11 01:56:14 UTC
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.