Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20151016041832.GG8645@brightrain.aerifal.cx>
Date: Fri, 16 Oct 2015 00:18:32 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: handling dlopen("/.../libc.so", ...) etc.

On Fri, Oct 16, 2015 at 11:00:11AM +0700, Рысь wrote:
> On Thu, 15 Oct 2015 23:46:42 -0400
> Rich Felker <dalias@...c.org> wrote:
> 
> > Presently, attempting to load "libc.so" (without pathname) or a number
> > of other standard library names via dlopen suppresses the actual
> > loading and returns a reference to the existing libc dso object.
> > However, loading it via a pathname or alternate name/symlink will
> > actually cause another copy to be loaded into memory (since we can't
> > check the dev/ino against the existing one, because the kernel didn't
> > give those to us) and bad things will happen. I've been thinking some
> > about ways to prevent that.
> > 
> > The most obvious way is to link libc.so with -Wl,-z,nodlopen and make
> > the dynamic linker enforce DF_1_NOOPEN, but this would cause the load
> > to fail when we probably want it to succeed but return a reference to
> > the existing libc.
> > 
> > Another option would be to somehow encode musl's identity in libc.so
> > so that the loader code can check "is the dso we've just loaded
> > actually musl?" In that case it can abort the load and use the
> > existing libc instead. Options for how to do this might include a
> > special reserved-namespace symbol. If an approach like this is taken,
> > it would be ideal to be able to detect existing/previous versions of
> > libc.so (to avoid loading them too), and the approach should be
> > future-proof so that the current libc.so can avoid loading future
> > versions of itself, and so that future versions can avoid loading the
> > current version.
> > 
> > I'd like to hear any further ideas on how to achieve this.
> 
> Who would even want to load "libc.so"? I mean, does not it already
> being loaded in every libc implementations with dynamic linking support
> already today?
> 
> And what are use cases? Who does this today? I am confused.

It could be a program calling dlopen on the pathname of each library
it knows is loaded (e.g. obtained from dl_iterate_phdr or
/proc/self/maps) to obtain handles for them -- the intent then is
_not_ to load anything new, but to get module handles for stuff that's
already loaded. In that case RTLD_NOLOAD should be used, but it might
not be, and even if it is used you want success rather than failure.
Similar situations could arise from programmatically reading DT_NEEDED
records to manually load dependencies before loading a library, e.g.
to try to control order ctors run or something.

In any case, the main concern is to _prevent_ wrongful loading of
multiple copies of libc.so that could read to serious issues like
memory corruption. The -Wl,-z,nodlopen approach solves this, but it
would be nicer if attempting to open a full pathname to libc.so
behaved just like opening the string "libc.so".

Does that answer your questions?

Rich

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.