This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Avoid mapping past end of shared object (BZ #18685)


On Fri, Jul 17, 2015 at 12:02:43AM -0400, Carlos O'Donell wrote:
> Is this really a bug?

Yes, because it is in the dynamic linker path and is not provably
isolated to the ldd use case.  It just happens so that it is exposed
by ldd, but I don't think it has been definitely proven yet that it is
not possible to expose the bug in the dynamic linker proper.

> The cost of the checks is more than just performance, but also maintenance
> and support of that code into the future. It is about testing that code,
> making sure we exercise those weird conditional failure paths which we
> thought would be a good thing to add. Each of these checks is an additional
> complication, added branch, and conditional in already complicated code.
> I would like to see the core loader as simple as possible and to expect
> as correct as possible input.
> 
> If I ask you for a test case for bug 18685, do we have one we can checkin
> to test this code? That goes a long way to helping maintain this code.

I don't yet; I can explore H. J.'s suggestion of writing out a corrupt
binary, but I don't yet have a reproducer that will trigger the crash
without --verify.  But not checking it in because of this is a weak
reason IMO when it is very clear that the bug exists.

> If ldd should not be run on untrusted input... then why are we looking
> at this patch? I think the fact on the ground is that ldd *is* run on

Like I said, because it is not specific to ldd; it just happens to be
exposed by ldd.

> untrusted input and eu-ldd isn't ready, and we face the grim specter of
> security issues. However, if we're talking security issues, there are
> a million ways I could craft relocs to overwrite and assemble ROP
> widgets to execute a custom program that would run crafty exploits.

Then we add those million checks as we find them if they affect ld.so
proper, i.e. not only the --verify path.  Although I suspect the
number will be much less than a million :)

> Running ldd is equivalent to ./app.

Not really, but it is not related to the argument I'm making, so I'll
let it go.

> See: "DEFCON 20: Programming Weird Machines with ELF Metadata"
> https://www.youtube.com/watch?v=YgtxxLCVD-o
> 
> So again, we can never support real ld.so running or processing untrusted
> input? The real fix becomes: Don't use ld.so, don't process relocs,
> don't run anything, just analyze.

If that is what we want to do, then we should remove ld.so --verify
and --list immediately and encourage use of other tools.  That is
still not related to this fix, which is directly in the ld.so path.

> I disagree that eu-ldd and ld.so should both be equally robust against
> bad input. Just consider the myriad of problems the binary could have,
> the fuzzing we put libelf through, all of that is costly verification
> that ld.so should not do.

We don't know the cost of verification yet.  We fear that it will be
too much, but we have no idea how much that 'too much' is.  If it is a
5% penalty on load time, IMO it is fine for the hardening it provides.
Maybe we could provide a build or runtime flag to bypass those checks,
but that is an added complication that is not worth the 5% IMO.

> How does python reduce the attack surface? I've already started eu-ldd
> in C because it needs to know quite a bit about the low-level pieces
> and it was easiest for me to do this in C (headers, constants etc).
> However, from a "independent implementation" perspective, writing it
> in python would make it truly orthogonal from the C version.
> 
> Any other benefits to python?

The biggest benefit is what happens in case of bugs in the program.
If the C bits are limited to just the core elfutils library, the worst
bug that the tools can have is a python error due to a missing
validation, which will just result in a crash.  With C, the worst
error is a buffer overrun or an arbitrary pointer dereference, which
may be exploitable.

So what is needed is a python wrapper around libelfutils, which eu-ldd
can then use.  I remember someone talking about such a project, but I
don't know if anyone actually got around to doing it.

Siddhesh


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]