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