summaryrefslogtreecommitdiff
blob: 41eb5aa05c3e481c4ca978ff48da43617660c43b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
GCC-4.1/GLIBC-2.4 Hardened Gentoo
=================================

Several things are changed from the GCC-3/GLIBC-2.3 hardened toolchain.  In brief;

1) The specs management has changed, to make maintenance and management of the
   modified specs much easier.  From the user's perspective, things should operate
   in much the same way.  Under the hood, however, the built-in specs are modified
   to separate out the bits we modify into new definitions.  The built-in specs are
   functionally identical to the vanilla compiler; a full set of hardened specs
   is created in the install directory to cause the compiler to default to the
   hardened specs.  This specs file is always (unconditionally) read by the compiler.

2) The compiler itself is not built PIE.  This now means that the crt* files used
   when building vanilla or static executables are correct - previously they were
   PIE objects which is of no use, and is actually fatal on some architectures.
   The fact things seemed to work ok on x86, amd64 and (maybe) ppc was down to
   pure luck.

3) Similarly glibc is built with the PIE default switched back off again.  This
   means that the crt* files provided by glibc are correct (like gcc, they were
   previously PIE when not PIC), and libc.a and friends now contain normal objects
   instead of PIE objects.
   Glibc is also built with the stack protector switched off (as far as libc.so,
   ld.so and friends are concerned this is the same as happened previously).

4) The stack smash handler (now called '__stack_chk_fail') installed for hardened
   toolchains is different than the upstream standard one; it logs failures to
   syslog, and goes to some lengths to ensure the handler itself cannot be
   exploited.


The result of this approach is that the toolchain is actually much closer to the
standard toolchain.  The hardened toolchain can now build static binaries properly,
and the -vanilla compiler also builds code the same way it would on a non-hardened
system.  From the hardened perspective, nothing has been lost; the defaults when
the -hardened compiler is selected are just as robust as they were previously.




Upgrade path
============

To upgrade from gcc-3/glibc-2.3, it is necessary to have glibc-2.4 or higher installed
before trying to build gcc.  So, after the new gcc/gclibc have been unmasked from the
hardened profile, the sequence is simply:

emerge --oneshot sys-libs/glibc
emerge --oneshot sys-devel/gcc
emerge --oneshot sys-libs/glibc

The second re-emerge of glibc is to get glibc itself built with the gcc-4 compiler.




Toolchain mods for hardened gcc-4.x/glibc-2.4
=============================================

* glibc __stack_chk_fail implementation written so that it's ok when glibc built with SSP
  Implement stderr & syslog messaging, SIGKILL and _exit to provide a secure termination
  (the one supplied by glibc is for debug purposes only), and all via inline syscalls
  avoiding any function calls (which would potentially invoke __stack_chk_fail).
  Note; building glibc with ssp-all is causing too many problems at the moment, so for
  now it's set to build without ssp.
  Sorted out the PIE building better (replaces the filter-ldflags -pie with something
  more sensible).
  (done) Use SIG_ABRT instead of SIG_KILL - means doing the sigset stuff.
  (done) Use INTERNAL_SYSCALL (check vsyscall page isn't user modifiable)

* gcc minispecs for gcc-4.1.1 and gcc-3.4.6, from psm
  Much simplified gcc patching for hardened compiler; use of minispecs to generate
  the relevant specs files.  Involves a few changes in toolchain.eclass and
  flag-o-matic.eclass.

* Specs switching handled by the wrappers, rather than the gcc-specs-env patch
  (app-admin/eselect-compiler only).  This gives us ccache reliability, as for
  gcc itself the specs are specified on the command line as normal.
  May not be a good idea - doing it gcc itself guarantees it'll happen even if
  the wrappers aren't used (is that ever the case?).
  Further investigation ongoing to manage filtering; considering doing this by
  adjusting GCC_SPECS, although it may be better as a separate variable (perhaps
  as part of COMPILER_FEATURES - see bug #128810)

Still cooking

* Look into -DFORTIFY_SOURCE=2, -msecure-plt for ppc