Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Sat, 10 Jun 2017 19:00:40 +0200
From: u-uy74@...ey.se
To: musl@...ts.openwall.com
Subject: Re: a possible need for MAP_FIXED in ldso/dynlink.c ?

On Sat, Jun 10, 2017 at 11:01:18AM -0400, Rich Felker wrote:
> On Sat, Jun 10, 2017 at 04:32:25PM +0200, u-uy74@...ey.se wrote:
> > On Sat, Jun 10, 2017 at 08:26:10AM -0400, Rich Felker wrote:
> > > Use of MAP_FIXED with a memory range you don't already own is an
> > > invalid and unsafe operation. You may end up mapping over top of
> > > yourself, even.
> > 
> > But the latter should be possible to avoid as long as we know where
> > ourself is located (?) Or do we?
> 
> Not easily. And you don't know that something else isn't mapped there,
> like perhaps a data page needed by the vdso or some other
> kernel-mapped code (perhaps sigreturn trampolines). The only way to
> know that would be nasty hacks like parsing /proc/self/maps. And the
> code that does the mapping is not restricted to running before program
> startup. At any later time, any check is subject to TOCTOU races. Use

I see. Thanks for explaining this.

> > "When MAP_FIXED is not set, the implementation uses addr in an
> > implementation-defined manner to arrive at pa."
> 
> Indeed, not all implementations will define this in a way that admits
> mapping programs at a hard-coded address, but then they're not
> suitable for dynamic loading of non-PIE programs.

Ok.

> BTW one reason the standard can't really formally define loading at a
> requested address is that pointers that don't point to an existing
> object or null are not even a valid concept in the C language.

Interesting. This thought did not strike me before.

> > Does this mean that musl can not implement the explicit dynamic loader
> > with mere Posix mmap(), only with the "more tightly specified Linux mmap()"?
> 
> Yes, I think that's accurate.

Sigh.

> Of course you can use PIE binaries and
> then you don't have to care about it, since they can be loaded at any
> address.

This does not sound too bad in the end.

I'll see if I can convince everything to be built as PIE. Thanks for
the clarifications!

By the way, even though I do not like adding the extra bytes,
what about something like

--- ldso/dynlink.c.orig   2017-06-10 18:33:45.114169773 +0200
+++ ldso/dynlink.c        2017-06-10 18:36:10.592548594 +0200
@@ -1428,7 +1428,7 @@
                runtime = 1;
                Ehdr *ehdr = (void *)map_library(fd, &app);
                if (!ehdr) {
-                       dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]);
+                       dprintf(2, "%s: %s: Failed to map the dynamic program\n", ldname, argv[0]);
                        _exit(1);
                }
                runtime = 0;

(The dynamic program is not necessarily at fault, it is the kernel
who for unknown reasons decides not to grant the address request,
it may even decide differently at the next try, who knows.)

Regards,
Rune

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.