Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 28 Mar 2014 15:46:38 -0400
From: Rich Felker <dalias@...ifal.cx>
To: musl@...ts.openwall.com
Subject: Re: be able to break inheritance of LD_LIBRARY_PATH

On Fri, Mar 28, 2014 at 10:42:08AM +0000, u-igbb@...ey.se wrote:
> Hello,
> 
> I was aware of musl for some time and now consider deploying it as
> a default library for new software builds, due to its very appealing
> virtues.
> 
> Yet there is a small but important issue.
> 
> For our software setup it is crucial (quite useful otherwise in general)
> to be able to specify the location of the dynamic libraries per binary/run
> _without_ the unconditional inheritance imposed by LD_LIBRARY_PATH.

Why aren't you using RPATH, possibly with a $ORIGIN base? This is a
lot cleaner/saner than environment variables or invoking the dynamic
linker explicitly with arguments.

> A very nice solution would be the ability to explicitely run a standalone
> dynamic loader, as implemented in both glibc and uclibc. We are heavily
> relying on this functionality.

As others have said, this is already possible, and it's already setup
to be able to handle option arguments before the command (if you're
not sure the command name won't begin with a "-", you're supposed to
put "--" before the command). So it's just a matter of adding the
options. I haven't checked your patch yet, but the big things to
consider are:

- not breaking the current handling of "--"

- whether --library-path and --preload should override/replace the
  values obtained from the environment or supplement them, and if the
  latter, whether they should have higher or lower priority

> I do not know how hard it would be to teach the musl loader
> to be runnable standalone and which corner cases this might create.
> 
> As a simpler approach I might suggest simply being able to drop
> LD_LIBRARY_PATH as soon as it has been read. An extra environment
> variable as a flag would do.
> 
> Compared to a standalone loader this lacks the ability to run
> a binary with a different version of the loader/musl but at least
> makes it straightforward and safe to freely specify where to find other
> libraries.
> 
> A naïve implementation might look as follows:
> ...
> +               else if (!memcmp(argv[i], "FORGET_LD_LIBRARY_PATH=", 23))
> +                       forget_ld_library_path = 1;

Adding new environment variables that are processed by libc outside of
those specified by the standard and/or overwhelming real-world
practice is not acceptable. If nothing else, this would be a security
bug because there's no way applications can know they would need to
unset this variable to keep it from taking effect.

>         auxv = (void *)(argv+i+1);
>  
> +       /* one _may_ wish to break the inheritance of LD_LIBRARY_PATH,
> +        * the hack below only works if the corresponding memory is writable
> +        * -- rl */
> +       if (forget_ld_library_path)
> +               for (i=argc+1; argv[i]; i++)
> +                       if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16) ||
> +                           !memcmp(argv[i], "FORGET_LD_LIBRARY_PATH=", 23))
> +                               argv[i][0] = 'X';

As written this possibly corrupts the environment (e.g. leading to TWO
definitions of XD_LIBRARY_PATH in the environment). In any case this
is the wrong approach. If you _really_ want to remove these vars once
they're processed, you can use the LD_PRELOAD approach that calls
unsetenv on them, but I think that's one of the worst solutions to the
problem you're trying to solve (and RPATH/$ORIGIN is the best
solution).

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.