Gentoo Logo

Disclaimer : This document is a work in progress and should not be considered official yet.

GCC-4/GLIBC-2.5 Hardened Toolchain Overview and Upgrade Guide (EARLY DRAFT)


1.  Introduction

Rationale for re-working the hardened toolchain.

The gcc-3/glibc-2.3 toolchain has been working reasonably well for Hardened Gentoo for a few years now. However while it has gained in maturity, there are a number of known issues that have proven unresolvable so far. Most issues are relatively minor and only show up in rare circumstances, however it has become increasingly clear that the Stack Smash Protector (SSP) implementation in gcc-3 that was developed at IBM has some serious issues most especially with code constructs of C++ (and also C, where gcc permits some C++ idioms to be used also in C).

In gcc-4, Richard Henderson and others at RedHat completely re-implemented the stack smash protector, making a number of improvements in the process. Internally to GCC, the implementation is significantly different, although the end result and the behaviour of the generated object code is much the same. Unfortunately, the re-implementation did not retain binary compatibility with the implementation we used previously, so we could not just simply bump our patches to support the newer toolchain without doing some work.

It was also clear that migrating to gcc-4 was not going to be trivial for the standard Gentoo product, let alone Hardened Gentoo. Other changes to gcc (the reason it gained a major version number increment) highlighted much code that worked on gcc-3 often for the wrong reasons, but failed with gcc-4. Thus it seemed like the ideal opportunity to re-examine the hardened toolchain modifications to see if it could be done better and more consistently, since it was apparent it would be some time before gcc-4 could be considered practical. While the overall concepts for the hardened toolchain are largely the same, a significant amount of work has gone into this task leading to hopefully a more reliable and maintainable product. Hopefully it was worth it!

Overview of the gcc-4/glibc-2.5/binutils-2.17 toolchain for Hardened Gentoo

As mentioned above, the SSP implementation has changed substantially. Changes to the interfaces used by gcc to handle stack overflows, and changes to the semantics of the stack-protector compiler switches, have lead to modifications of glibc so that it can support both the old and new interfaces, and modifications to the way the SSP compiler switches are managed to avoid having to modify ebuilds.

The other major plank of the hardened toolchain with respect to gcc, Position Independent Executables (PIEs) has not changed; the support in gcc-4 is no different from the support in gcc-3 which has been maintained upstram. However, in order to support the default-PIE some changes have been made which should mean that building executables will always use a consistent set of startfiles and libraries. Previously there were occasions where odd results were observed; particularly when building "-static". Static builds now result in a static/PIE hybrid executable that should be stable on all architectures.

The other two elements of the hardened toolchain, RELRO and BIND_NOW, are effectively no different than they were before.

In addition to the support changes necessary for SSP and the PIE cleanup, the way compiler "specs" are handled ("specs" are configuration text used by the compiler driver to control how the various components; the C compiler, C++ compiler, linker, assembler etc are invoked) has been reworked. Previously we patched the compiler driver code significantly to inject our altered default specs, and did so repeatedly in various combinations to get us the several variants of the hardened compiler that are provided. The new approach still patches the compiler driver, but once only and much, much less intrusively, adding "call-outs" to "mini-specs" that are by default defined to behave as the vanilla compiler does, but can be easily overridden to achieve the hardened toolchain behaviour we desire. The altered specs are managed by appending re-definitions of these "mini-specs" to the standard specs, overriding the defaults in a much less architecture-dependent way.

A detailed description of the new toolchain modifications can be found in the Technical Description of the Gentoo Hardened Toolchain.

2.  Upgrade Guide


There are a number of build and run-time dependencies between the various toolchain elements. A brief elaboration of these will make it clear why the recommended upgrade path is as it is.

  • Hardened gcc-4 requires glibc-2.5 for ssp support functions
  • The new reliable "static PIE" support means hardened glibc-2.5 must be built with hardened gcc-4
  • "static PIE" support requires binutils-2.17

Of particular note, is the circular dependency between hardened gcc-4 and hardened glibc-2.5. Note that these dependencies are only relevant when hardened.

Upgrade Sequence

The upgrade path is quite simple really. Upgrade to binutils-2.17 if necessary, and ensure it is selected. Then, using the vanilla compiler, build both glibc and gcc non-hardened - this installs all the support necessary to build them hardened. Next, switch to the new compiler -hardened variant, rebuild glibc and gcc. Ensure the hardened compiler is selected (reselect to be sure).

Switch off distcc and ccache if you're using them, to be sure you don't get mixed results from previous compilations (especially if you have tried earlier versions of the toolchain upgrade from overlays).

In detail, the steps are:

Ensure sys-devel/binutils-2.17 is installed:

Code Listing 2.1: Check binutils version

binutils-config -l

If the version selected (highlighted with '*') is 2.17, that's enough. If 2.17 is installed but not selected, select it with binutils-config - otherwise merge it:

Code Listing 2.2: Merge binutils-2.17

emerge --oneshot =sys-devel/binutils-2.17

and switch to it if necessary using binutils-config. Next, switch to the vanilla gcc:

Code Listing 2.3: Select vanilla gcc

gcc-config -l
gcc-config <current gcc>-vanilla
source /etc/profile

replacing <current gcc> with the current compiler name (or just choose the right number from the list).

Merge vanilla glibc-2.5 and gcc-4:

Code Listing 2.4: Merging vanilla toolchain

USE="-hardened" emerge --oneshot =sys-libs/glibc-2.5
USE="-hardened" emerge --oneshot =sys-devel/gcc-4.1.2

There are a number of known test failures with both glibc and gcc on a hardened system. The glibc build will stop after the test failures. Complete the glibc build either using ebuild (if you know what you're doing) or do the build again with FEATURES="-test". The gcc build will carry on regardless, it'll install and merge despite the failures. Once both are installed, switch to the hardened gcc:

Code Listing 2.5: Select hardened gcc

gcc-config -l
gcc-config <new gcc>-hardened
source /etc/profile

replacing <new gcc> with the new compiler name.

Merge hardened glibc-2.5 and gcc-4:

Code Listing 2.6: 5: Merging hardened toolchain

emerge --oneshot =sys-libs/glibc-2.5
emerge --oneshot =sys-devel/gcc-4.1.2

Rebuild world with the new toochain:

Code Listing 2.7: 6: Rebuilding world

emerge -e world

That last - rebuilding world - does not have to be done immediately; existing binaries should continue to run correctly against the upgraded glibc, and portage should have left your previous compile in place since it's a major revision change. It is probably a good idea to rebuild binutils with the new toolchain (repeat 2.2) at least. See also the standard Gentoo GCC Upgrade Guide advice on common GCC upgrade pitfalls.

3.  References

Other Gentoo Documentation


Page updated February 22, 2007

Summary: Guide for upgrading from hardened gcc-3/glibc-2.3/binutils-2.16 to gcc-4/glibc-2.5/binutils-2.17.

Kevin F. Quinn

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.