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