1 |
On 7 Mar 2009 at 1:46, Alex Efros wrote: |
2 |
|
3 |
> Hi! |
4 |
> |
5 |
> On Fri, Mar 06, 2009 at 03:25:16PM -0800, Ned Ludd wrote: |
6 |
> > FYI.. PaX Team maintains the PaX kernel and has little control over what |
7 |
> > fixes go into the "next" hardened-sources. Also seems to me a little |
8 |
> > strange that the PaX Team would have to put a work-around in the kernel |
9 |
> > for a bug in glibc.. Seems like glibc should be fixed vs the kernel. |
10 |
> |
11 |
> Some changes in hardened-sources trigger this bug (which exists for years |
12 |
> and don't bother anybody) and kill my servers (apache and perl are |
13 |
> critical for normal server operation). |
14 |
|
15 |
you're both correct ;). the bug is in glibc and it got 'fixed' (see below) |
16 |
and that 'fix' worked until recently when i did make a change (for security) |
17 |
that exposed how wrong that fix was. |
18 |
|
19 |
the glibc bug revolves around the well known GNU_STACK braindamage. in this |
20 |
case glibc maintains an internal variable that tracks the executable status |
21 |
(access rights, to be precise) of stacks. it has to be a dynamic property (vs. |
22 |
something decided at process creation) as under the GNU_STACK approach apps |
23 |
can load libraries at runtime that need an executable stack and glibc has to |
24 |
create future stacks with that in mind (beyond mprotecting all existing ones). |
25 |
|
26 |
now this variable happened to be put into the RELRO segment, so you can imagine |
27 |
how it would segfault if an app tried to load such a library. |
28 |
|
29 |
the 'fix' was to mprotect the variable temporarily so that it could be updated... |
30 |
except this directly contradicts the definition and purpose of RELRO of course. |
31 |
not to mention that they royally screwed up the ret2libc 'prevention' as well |
32 |
at the same time. that's two birds with one shot for the guys at Red Hat ;). |
33 |
|
34 |
here's the commit in question: |
35 |
|
36 |
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/elf/dl-load.c.diff?r1=1.270&r2=1.271&cvsroot=glibc&f=h |
37 |
|
38 |
yes, that dates back to 2005 and has been broken ever since. |
39 |
|
40 |
now what i changed recently was the result of a cleanup in textrel handling. |
41 |
in earlier versions PaX could allow text relocations (which circumvent |
42 |
MPROTECT, so it's less than ideal of course) by parsing the ELF headers and |
43 |
making decisions based on that. for reasons i forget now, i didn't put that |
44 |
code into the ELF loader so it only supported one kind of ELF, that of the |
45 |
kernel's bitness. so you'd get textrel processing for your 64 bit amd64 |
46 |
executables, but not for your 32 bit i386 userland on a 64 bit kernel. this |
47 |
is what i fixed up so now it works for any userland that the kernel's ELF |
48 |
loader gets compiled for. |
49 |
|
50 |
along the way i also i implemented a long-standing item on my todo list: |
51 |
enforcement of RELRO. what it means is that when the kernel detects the |
52 |
final mprotect(PROT_READ) from userland on a RELRO segment, the new logic |
53 |
in PaX will change the access rights so that PROT_WRITE cannot be granted |
54 |
to it ever again (that's kinda the idea behind RELRO after all, it's just |
55 |
not enforced by the normal kernel). and as you can guess, that enforcement |
56 |
directly contradicts what the above mentioned 'fix' wants to do. |
57 |
|
58 |
so there you have it, another little episode in the drama played by Red Hat |
59 |
where the left hand doesn't seem to know what the right one was doing. |