1 |
On Sat, 6 Jan 2007, Kevin F. Quinn wrote: |
2 |
|
3 |
> On Sat, 6 Jan 2007 20:56:22 +0100 (CET) |
4 |
> "Peter S. Mazinger" <ps.m@×××.net> wrote: |
5 |
> |
6 |
> > On Mon, 18 Dec 2006, Kevin F. Quinn wrote: |
7 |
> > |
8 |
> > > On Mon, 18 Dec 2006 11:55:31 +0100 (CET) |
9 |
> > > "Peter S. Mazinger" <ps.m@×××.net> wrote: |
10 |
> > > |
11 |
> > > > On Tue, 12 Dec 2006, Alexander Gabert wrote: |
12 |
> > > > |
13 |
> > > > > Kevin: this is the build failures, i would have made them end up |
14 |
> > > > > adding into bugzilla but one of us both wasn't awake. |
15 |
> > > > > |
16 |
> > > > > PSM: if you're reading up: i don't have a clue. |
17 |
> > > > > |
18 |
> > > > > In the meantime, working with bugs.g.o. it's getting a real |
19 |
> > > > > hassle, so can someone please kick that pos in the shins so we |
20 |
> > > > > can work on bugs again? TIA |
21 |
> > > > > |
22 |
> > > > > I think we should have a talk or two and maybe a test case for |
23 |
> > > > > building that libiberty on all arches with either PIC or PIE |
24 |
> > > > > code. I honestly don't care howe we build it, i just want it to |
25 |
> > > > > work on all Gentoo supported arches for hardened. |
26 |
> > > > > |
27 |
> > > > > For those of you having issues with the file: here is the log |
28 |
> > > > > for pitr and miranda: |
29 |
> > > > > |
30 |
> > > > > http://dev.gentoo.org/~pappy/tmp/amd64-pie-libiberty-failure.txt |
31 |
> > > > |
32 |
> > > > It seems some of you are mixing up PIC and PIE. For the record, |
33 |
> > > > there are no PIE libraries and if you want to run a hardened box |
34 |
> > > > where each file is text relocation free, then you have to compile |
35 |
> > > > all code that goes to libraries (even into lib*.a) with |
36 |
> > > > -fPIC|-fpic. To quickly check this statement, compile some object |
37 |
> > > > with -fPIE, put into libx.a and compile a shared lib with -fPIC |
38 |
> > > > using code from libx.a. readelf -d shared_lib | grep TEXTREL. |
39 |
> > > |
40 |
> > > Agreed - however lib*.a are not generally used to build shared |
41 |
> > > libraries; they're mostly for building static binaries. Gcc deals |
42 |
> > > with libiberty (normally) by building a pic version |
43 |
> > > (libiberty_pic.a) for linking to shared libraries when it needs |
44 |
> > > to. We do mess that up, I think - I'm still looking into that. |
45 |
> > |
46 |
> > we do not mess it up, libiberty_pic.a is not used to compile the |
47 |
> > intermediate gen* binaries and if the build specs defaults to PIE |
48 |
> > binaries and then these binaries have text relocations, thus failing |
49 |
> > on a PaX box if the text relocations are blocked (or it is an uClibc |
50 |
> > hardened box, where libc blocks text relocations as well) |
51 |
> |
52 |
> What we mess up, is that gcc's configure thinks that the compiler |
53 |
> always generates PIC code (which it doesn't, quite) and thus doesn't do |
54 |
> -fPIC -DPIC in places where it normally would do (it just does -DPIC). |
55 |
> This means that some objects that should be built PIC, get built PIE |
56 |
> with the hardened compiler. Historically there was a -D_IN_GCC_ (or |
57 |
> something like that) filter in the specs which meant that sometimes gcc |
58 |
> generated PIE code and sometimes not, depending on what part of gcc is |
59 |
> being built. |
60 |
> |
61 |
> In order to have gcc build all its intermediate executables PIE (and to |
62 |
> be honest, I don't see any point in doing so), in a way that works on |
63 |
> all architectures, we would have to modify the build process a lot more |
64 |
> than we already do. |
65 |
|
66 |
If we want to have gcc's final binaries "hardened", then we can't probably |
67 |
avoid compiling the intermediate files "hardened" too, else we have to |
68 |
tweak too many parts of the build-system. Some will probably say that gcc |
69 |
is not needed hardened itself, because it is not used for runtime |
70 |
(exceptions being libgcc.a/libgcc_s.so/libsupc++.a/libstdc++.* and the |
71 |
crt files that go into each binary), I personally think that it is a good |
72 |
test for hardened to see if gcc fails somewhere, thus warning us about |
73 |
expected problems. |
74 |
|
75 |
> > > > The pie patches compile everything with -fPIE unless -fPIC was |
76 |
> > > > used, the app itself has to take care (and most apps using |
77 |
> > > > libtool do it by using -fPIC -DPIC) that code that goes into libs |
78 |
> > > > is -fPIC compiled. libtool fails only in cases where configure |
79 |
> > > > does not recognize correctly the target (thats why |
80 |
> > > > gnuconfig_update/libtoolize are needed). |
81 |
> > > > |
82 |
> > > > Some will argue, that it does not make sense to compile code in |
83 |
> > > > lib*.a with -fPIC. Those shouldn't use hardened, because they end |
84 |
> > > > up with text relocations and a hardened box should block text |
85 |
> > > > relocations either in kernel (PaX feature) or libc (possible with |
86 |
> > > > uClibc, but not glibc) |
87 |
> > > |
88 |
> > > I think it's more complicated than that. What should go into a |
89 |
> > > lib*.a archive depends on how it's going to be used. If it's going |
90 |
> > > to be used to build a shared library, then as you say the code |
91 |
> > > needs to be PIC - however this is rare (examples are |
92 |
> > > libc_*nonshared.a). If it's being used to build a non-PIE |
93 |
> > > executable - which usually means building a static executable - |
94 |
> > > then the code needs to be normal (non-PIC). If it's going to be |
95 |
> > > used to build a (PIE) executable, the code needs to be PIE - in |
96 |
> > > practice this is very rare, since linking to lib*.a instead of |
97 |
> > > lib*.so means building static binaries, and that's not sensible |
98 |
> > > when building PIEs as by definition they need the dynamic loader. |
99 |
> > |
100 |
> > No, the code needs to be PIC, else the generated PIE binary has text |
101 |
> > relocation (PIE binary is more like a shared library needing though |
102 |
> > an interpreter/dynamic loader). |
103 |
> |
104 |
> The only time this is an issue is when lib*.a archives are being used |
105 |
> to link executables. This is rather rare - indeed the only places I've |
106 |
> seen it done are in gcc and glibc. |
107 |
> |
108 |
> |
109 |
> ok; maybe I wasn't clear: |
110 |
> |
111 |
> 1) Objects to be linked into shared libraries must be PIC |
112 |
> |
113 |
> 2) Objects to be linked into position-independent executables should be |
114 |
> PIE (but PIC objects are work too, they just put more through the PLT |
115 |
> than necessary) |
116 |
> |
117 |
> 3) Objects to be linked into normal executables (i.e. not PIEs) should |
118 |
> be normal - neither PIC nor PIE. |
119 |
> |
120 |
> I think you'll agree those statements are true. |
121 |
|
122 |
not with 2) |
123 |
if that would be true, then the intermediate files would not have text |
124 |
relocations, libiberty.a's objects are compiled -fPIE instead of -fPIC |
125 |
(-DPIC does not influence the result) |
126 |
|
127 |
> |
128 |
> So, to lib*.a archives. These are collections of object files - how |
129 |
> they should be built depends on what they're going to be used for, and |
130 |
> the above rules apply in the same way. In the vast majority of cases, |
131 |
> whenever someone is linking lib*.a archives into something, it's into |
132 |
> static binaries as the lib*.a is the static equivalent of lib*.so. For |
133 |
> these cases, we should have normal (no-PIE) objects. |
134 |
> |
135 |
> The cases internal to gcc/glibc are exceptions, in that the archives are |
136 |
> used to build shared libraries (which use the lib*_nonshared.a archives |
137 |
> which should always be PIC anyway) and those executables - which if we |
138 |
> want them to be PIE of course need PIE objects. I think a better way |
139 |
> to approach this sort of case is to modify the build process explicitly |
140 |
> to build PIE objects where needed, rather than using the altered |
141 |
> defaults. |
142 |
|
143 |
there are many exceptions, but you do not see them with a glibc/gnu |
144 |
system. On an uClibc hardened system, if configure fails to detect |
145 |
correctly the system (needing gnuconfig-update/libtoolize), it will |
146 |
probably build only lib*.a instead of both lib*.so/lib*.a, and the next |
147 |
app compiled against lib*.a will have text relocations. |
148 |
|
149 |
> > > Strictly speaking, on a hardened system, the -vanilla and |
150 |
> > > -hardenednopie compiler cannot be guaranteed to generate working |
151 |
> > > executables - indeed it creates garbage on sparc (x86 seems to be |
152 |
> > > more forgiving; you can mix PIE objects into a non-PIE executable |
153 |
> > > and they appear to work). |
154 |
> > |
155 |
> > because lib*.a has to be PIC. |
156 |
> |
157 |
> Like I say, whether they should be normal, PIC or PIE depends on what |
158 |
> they're used for - and in general you just don't know. The most common |
159 |
> use for lib*.a files from the system (/usr/lib etc) is to build static |
160 |
> binaries. |
161 |
> |
162 |
> Consider also the state of the crt*.o objects - on existing hardened |
163 |
> systems crtbegin.o and friends are built -fPIE. This makes the |
164 |
|
165 |
no, crt*S.o are compiled -fPIC at least on linux, see gcc/config/t-linux |
166 |
CRTSTUFF_T_CFLAGS_S, only those without S are compiled -fPIE (if gcc |
167 |
defaults to hardened and ... and ..., depending on the version of the |
168 |
piepatches) |
169 |
|
170 |
> switching of startfile/endfile in the specs achieve almost nothing - on |
171 |
> x86, crtend.o and crtendS.o are identical, and crtbegin.o/crtbeginS.o |
172 |
> are almost the same. Have we really analysed the source for those |
173 |
> objects, to verify that building them -fPIE gives sensible results? I |
174 |
> suspect not. |
175 |
|
176 |
maybe we should add -fno-PIE to crtbegin.o/crtend.o/crtbeginT.o to guard |
177 |
against the above case. |
178 |
|
179 |
> > > I'm working on a sane solution to this problem using ABIs, but it's |
180 |
> > > quite involved, and it's quite a departure from what we currently |
181 |
> > > do. Once I have my thoughts clear, I'll post a proposal. |
182 |
> > > |
183 |
> > > For the moment, however, we can continue as we did before, but |
184 |
> > > highlight that -vanilla and -hardenednopie may not generate working |
185 |
> > > executables. Mostly this affects bootloaders, and things like |
186 |
> > > static busybox. |
187 |
> > |
188 |
> > Wondering why you mention static binaries, |
189 |
> |
190 |
> Static binaries should not be PIE - the two concepts don't mix. It |
191 |
> doesn't make sense to build an ET_EXEC executable (which is what static |
192 |
> executables are) with PIE code. |
193 |
|
194 |
sadly, when compiling we do not know if the object will go into |
195 |
static/ET_EXEC/ET_DYN, else we could handle that (we handle only the case |
196 |
if the final binary is compiled and linked in one step) |
197 |
|
198 |
> > I have no problem on a |
199 |
> > clean hardened box with static binaries, |
200 |
> |
201 |
> What you have aren't really static binaries - they're ET_EXECs with PIE |
202 |
> objects inside. This kinda works on x86, but on sparc it just segfaults |
203 |
> on startup (due to the contents of crt*.o). |
204 |
|
205 |
I know ppc/arm does not have any problem with it (mips is out of question |
206 |
because it is always PIC except the kernel) |
207 |
|
208 |
give fno-PIE a try for those, maybe it solves the issue. |
209 |
|
210 |
> > even if the lib*.a are PIC |
211 |
> > compiled (mine are for sure, and most of you have it too, if an app |
212 |
> > is using autotools and running ./configure shows that the system |
213 |
> > supports shared libraries and for "dependant libraries" it says |
214 |
> > "pass_all"), I though agree that it is overkill for static binaries |
215 |
> > to use libraries that were PIC compiled. |
216 |
> |
217 |
> The problem with static binaries is that they're not correct on all |
218 |
> platforms, when built with PIE objects. sparc in particular |
219 |
> segfaults. It does create executables that run on x86, but they're a |
220 |
> bizarre PIE/ET_EXEC hybrid that makes little sense. |
221 |
|
222 |
sparc or sparc64 or both? have you compared assembler output? does it make |
223 |
a difference if you provide -K PIC to the assembler or not? |
224 |
|
225 |
Peter |
226 |
|
227 |
> What I've done for now, and am proposing we enter into the tree, is to |
228 |
> build gcc itself (and glibc) non-PIE. This means the crt files are |
229 |
> built correctly, also libc.a and the gcc lib*.a's are non-PIE and |
230 |
> suitable for properly static binaries. |
231 |
> |
232 |
> This is still not entirely satisfactory; in a perfect world we'd have |
233 |
> lib*.a available both ET_EXEC and PIE. The only half-sensible way I |
234 |
> can think of to do that, would be to set things up like a multilib |
235 |
> system. However until portage supports multilib |
236 |
> (http://dev.gentoo.org/~kanaka/auto-multilib/ would be my preferred |
237 |
> approach) I don't think it's worth the trouble. |
238 |
> |
239 |
> |
240 |
|
241 |
-- |
242 |
Peter S. Mazinger <ps dot m at gmx dot net> ID: 0xA5F059F2 |
243 |
Key fingerprint = 92A4 31E1 56BC 3D5A 2D08 BB6E C389 975E A5F0 59F2 |
244 |
|
245 |
-- |
246 |
gentoo-hardened@g.o mailing list |