Gentoo Archives: gentoo-hardened

From: "Kevin F. Quinn" <kevquinn@g.o>
To: gentoo-hardened@l.g.o
Subject: Re: [gentoo-hardened] TESTING kevquinn_overlays: amd64 hardened gcc - (bugzilla is down, i hope the mails are not)
Date: Mon, 08 Jan 2007 17:55:52
Message-Id: 20070108184839.28425ee6@c1358217.kevquinn.com
In Reply to: Re: [gentoo-hardened] TESTING kevquinn_overlays: amd64 hardened gcc - (bugzilla is down, i hope the mails are not) by "Peter S. Mazinger"
1 On Mon, 8 Jan 2007 13:46:51 +0100 (CET)
2 "Peter S. Mazinger" <ps.m@×××.net> wrote:
3
4 > On Sat, 6 Jan 2007, Kevin F. Quinn wrote:
5 >
6 > > [...]
7 > > What we mess up, is that gcc's configure thinks that the compiler
8 > > always generates PIC code (which it doesn't, quite) and thus
9 > > doesn't do -fPIC -DPIC in places where it normally would do (it
10 > > just does -DPIC). This means that some objects that should be built
11 > > PIC, get built PIE with the hardened compiler. Historically there
12 > > was a -D_IN_GCC_ (or something like that) filter in the specs which
13 > > meant that sometimes gcc generated PIE code and sometimes not,
14 > > depending on what part of gcc is being built.
15 > >
16 > > In order to have gcc build all its intermediate executables PIE
17 > > (and to be honest, I don't see any point in doing so), in a way
18 > > that works on all architectures, we would have to modify the build
19 > > process a lot more than we already do.
20 >
21 > If we want to have gcc's final binaries "hardened", then we can't
22 > probably avoid compiling the intermediate files "hardened" too, else
23 > we have to tweak too many parts of the build-system. Some will
24 > probably say that gcc is not needed hardened itself, because it is
25 > not used for runtime (exceptions being
26 > libgcc.a/libgcc_s.so/libsupc++.a/libstdc++.* and the crt files that
27 > go into each binary), I personally think that it is a good test for
28 > hardened to see if gcc fails somewhere, thus warning us about
29 > expected problems.
30
31 Well, building PIE doesn't find anything as such. My preference at the
32 moment is to build gcc itself with SSP, NOW and RELRO (which don't
33 have any conflict from one stage to the next), but not PIE. glibc I'm
34 building with both SSP and PIE switched off.
35
36 The crt files should definitely never be built -fPIE. For the lib*.a
37 provided by gcc and libc, it may be worth building them both PIE and
38 no-PIE. How they would be selected on use is another problem...
39
40 > > > [...]
41 > > > No, the code needs to be PIC, else the generated PIE binary has
42 > > > text relocation (PIE binary is more like a shared library needing
43 > > > though an interpreter/dynamic loader).
44 > >
45 > > The only time this is an issue is when lib*.a archives are being
46 > > used to link executables. This is rather rare - indeed the only
47 > > places I've seen it done are in gcc and glibc.
48 > >
49 > >
50 > > ok; maybe I wasn't clear:
51 > >
52 > > 1) Objects to be linked into shared libraries must be PIC
53 > >
54 > > 2) Objects to be linked into position-independent executables
55 > > should be PIE (but PIC objects are work too, they just put more
56 > > through the PLT than necessary)
57 > >
58 > > 3) Objects to be linked into normal executables (i.e. not PIEs)
59 > > should be normal - neither PIC nor PIE.
60 > >
61 > > I think you'll agree those statements are true.
62 >
63 > not with 2)
64 > if that would be true, then the intermediate files would not have
65 > text relocations, libiberty.a's objects are compiled -fPIE instead of
66 > -fPIC (-DPIC does not influence the result)
67
68
69 If it's false, then we're in trouble - because PIEs would always have
70 textrels.
71
72 The way to build a PIE, as I understand it, is to:
73
74 (1) compile all objects -fPIE
75 (2) link with -fPIE -pie
76
77 If that creates executables with textrels, then we're in trouble
78 everywhere. However I don't think that's the case - I understand we
79 get textrels when:
80
81 a) linking normal or -fPIE objects into shared libraries
82 b) linking normal objects in to PIE executables
83
84 and I think the textrels in the intermediate files occur when starting
85 from a vanilla compiler, where libiberty.a is built normally (i.e. not
86 PIE or PIC) in the first pass. Possibly it's also affected by
87 configure thinking the compiler generates PIC by default.
88
89
90 > > So, to lib*.a archives. These are collections of object files - how
91 > > they should be built depends on what they're going to be used for,
92 > > and the above rules apply in the same way. In the vast majority of
93 > > cases, whenever someone is linking lib*.a archives into something,
94 > > it's into static binaries as the lib*.a is the static equivalent of
95 > > lib*.so. For these cases, we should have normal (no-PIE) objects.
96 > >
97 > > The cases internal to gcc/glibc are exceptions, in that the
98 > > archives are used to build shared libraries (which use the
99 > > lib*_nonshared.a archives which should always be PIC anyway) and
100 > > those executables - which if we want them to be PIE of course need
101 > > PIE objects. I think a better way to approach this sort of case is
102 > > to modify the build process explicitly to build PIE objects where
103 > > needed, rather than using the altered defaults.
104 >
105 > there are many exceptions, but you do not see them with a glibc/gnu
106 > system. On an uClibc hardened system, if configure fails to detect
107 > correctly the system (needing gnuconfig-update/libtoolize), it will
108 > probably build only lib*.a instead of both lib*.so/lib*.a, and the
109 > next app compiled against lib*.a will have text relocations.
110
111 I was not aware of that. I would have expected embedded systems to be
112 keen on shared libraries, as they reduce physical memory requirements.
113 Would it be better to have autotools working properly with uclibc? How
114 many packages are we talking about? Would it be reasonable to suggest
115 they be modified to build shared libraries properly (perhaps by
116 directing configure explicitly)?
117
118 > > > > Strictly speaking, on a hardened system, the -vanilla and
119 > > > > -hardenednopie compiler cannot be guaranteed to generate working
120 > > > > executables - indeed it creates garbage on sparc (x86 seems to
121 > > > > be more forgiving; you can mix PIE objects into a non-PIE
122 > > > > executable and they appear to work).
123 > > >
124 > > > because lib*.a has to be PIC.
125 > >
126 > > Like I say, whether they should be normal, PIC or PIE depends on
127 > > what they're used for - and in general you just don't know. The
128 > > most common use for lib*.a files from the system (/usr/lib etc) is
129 > > to build static binaries.
130 > >
131 > > Consider also the state of the crt*.o objects - on existing hardened
132 > > systems crtbegin.o and friends are built -fPIE. This makes the
133 >
134 > no, crt*S.o are compiled -fPIC at least on linux, see
135 > gcc/config/t-linux CRTSTUFF_T_CFLAGS_S, only those without S are
136 > compiled -fPIE (if gcc defaults to hardened and ... and ...,
137 > depending on the version of the piepatches)
138
139 Yes. It was just the non-S versions I was talking about (crtbegin.o,
140 crtend.o and friends, crt1.o from libc).
141
142 > > switching of startfile/endfile in the specs achieve almost nothing
143 > > - on x86, crtend.o and crtendS.o are identical, and
144 > > crtbegin.o/crtbeginS.o are almost the same. Have we really
145 > > analysed the source for those objects, to verify that building them
146 > > -fPIE gives sensible results? I suspect not.
147 >
148 > maybe we should add -fno-PIE to crtbegin.o/crtend.o/crtbeginT.o to
149 > guard against the above case.
150
151 I did try that, also building crt1.o (libc) with -fno-PIE. The
152 modifications to the toolchain build files got more and more involved,
153 which I really want to avoid. In addition, I suspect that will break
154 your "PIE/static" binaries; where perhaps it would be better to use
155 crt*S.o/Scrt1.o.
156
157 > > > > I'm working on a sane solution to this problem using ABIs, but
158 > > > > it's quite involved, and it's quite a departure from what we
159 > > > > currently do. Once I have my thoughts clear, I'll post a
160 > > > > proposal.
161 > > > >
162 > > > > For the moment, however, we can continue as we did before, but
163 > > > > highlight that -vanilla and -hardenednopie may not generate
164 > > > > working executables. Mostly this affects bootloaders, and
165 > > > > things like static busybox.
166 > > >
167 > > > Wondering why you mention static binaries,
168 > >
169 > > Static binaries should not be PIE - the two concepts don't mix. It
170 > > doesn't make sense to build an ET_EXEC executable (which is what
171 > > static executables are) with PIE code.
172 >
173 > sadly, when compiling we do not know if the object will go into
174 > static/ET_EXEC/ET_DYN, else we could handle that (we handle only the
175 > case if the final binary is compiled and linked in one step)
176
177 Yep. The only way I can think of to deal with that would be a
178 normal/PIE multilib setup. For glibc systems it is probably not worth
179 the trouble (since we rarely use the lib*.a archives anyway). For
180 uclibc, it would depend how much breakage there is in building shared
181 libraries.
182
183 > > > I have no problem on a
184 > > > clean hardened box with static binaries,
185 > >
186 > > What you have aren't really static binaries - they're ET_EXECs with
187 > > PIE objects inside. This kinda works on x86, but on sparc it just
188 > > segfaults on startup (due to the contents of crt*.o).
189 >
190 > I know ppc/arm does not have any problem with it (mips is out of
191 > question because it is always PIC except the kernel)
192 >
193 > give fno-PIE a try for those, maybe it solves the issue.
194
195 I did try that, I think, but without any success.
196
197
198 > > > even if the lib*.a are PIC
199 > > > compiled (mine are for sure, and most of you have it too, if an
200 > > > app is using autotools and running ./configure shows that the
201 > > > system supports shared libraries and for "dependant libraries" it
202 > > > says "pass_all"), I though agree that it is overkill for static
203 > > > binaries to use libraries that were PIC compiled.
204 > >
205 > > The problem with static binaries is that they're not correct on all
206 > > platforms, when built with PIE objects. sparc in particular
207 > > segfaults. It does create executables that run on x86, but they're
208 > > a bizarre PIE/ET_EXEC hybrid that makes little sense.
209 >
210 > sparc or sparc64 or both? have you compared assembler output? does it
211 > make a difference if you provide -K PIC to the assembler or not?
212
213 sparc64 (sparcv9). The problem was symbols not being resolved
214 properly, iirc. I don't remember exactly what I tried, now - I tried
215 many things, although not -K PIC (I would assume that would be passed
216 to the assembler when building -fPIE or -fPIC).
217
218 >
219 > Peter
220 >
221 > > What I've done for now, and am proposing we enter into the tree, is
222 > > to build gcc itself (and glibc) non-PIE. This means the crt files
223 > > are built correctly, also libc.a and the gcc lib*.a's are non-PIE
224 > > and suitable for properly static binaries.
225 > >
226 > > This is still not entirely satisfactory; in a perfect world we'd
227 > > have lib*.a available both ET_EXEC and PIE. The only half-sensible
228 > > way I can think of to do that, would be to set things up like a
229 > > multilib system. However until portage supports multilib
230 > > (http://dev.gentoo.org/~kanaka/auto-multilib/ would be my preferred
231 > > approach) I don't think it's worth the trouble.
232 > >
233 > >
234 >
235
236
237 --
238 Kevin F. Quinn

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies