This is the mail archive of the glibc-bugs@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]

[Bug dynamic-link/19884] New: Discrepancy between documented and actual search path for shared libraries


https://sourceware.org/bugzilla/show_bug.cgi?id=19884

            Bug ID: 19884
           Summary: Discrepancy between documented and actual search path
                    for shared libraries
           Product: glibc
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dynamic-link
          Assignee: unassigned at sourceware dot org
          Reporter: njs at pobox dot com
  Target Milestone: ---

I was surprised recently to discover that if you have the following situation:

Files:

  a.out
  A/A.so
  A/libncurses.so.5
  B/B.so

A/A.so has RUNPATH=$ORIGIN
A/A.so is linked against (DT_NEEDED) libncurses.so.5

B/B.so has no RUNPATH set
B/B.so is linked against (DT_NEEDED) libncurses.so.5

Execution flow:

run program a.out, which
1) dlopen A/A.so with RTLD_LOCAL
2) dlopen B/B.so with RTLD_LOCAL

Then: B/B.so will get loaded linked against A/libncurses.so.5, rather than the
system libncurses.

OTOH, if a.out is modified to swap the order, so that it instead does:
1) dlopen B/B.so with RTLD_LOCAL
2) dlopen A/A.so with RTLD_LOCAL

then both A.so and B.so will end up linked against the system version of
libncurses.so.5, and A's RUNPATH will be ignored.

Sample code to demonstrate this behavior:
https://github.com/njsmith/rpath-weirdness

I find this behavior very surprising -- I expected that A.so's RUNPATH would be
respected, so that A.so always linked to A/libncurses.so, while B.so's lack of
RUNPATH would also be respected, so that B.so always linked to the system
libncurses.so.5. The reason I expected this is that (1) AFAICT, all available
documentation says that what I expected to happen is what should have happened
(e.g. ld.so(8) clearly documents the library search order, and doesn't say
anything about this; Drepper's dsohowto.pdf AFAICT also seems to say that what
I expected to happen is what should have happened), and (2) the actual behavior
is very weird and undesireable (IMO). In every other way, A.so and B.so are
isolated from each other by being loaded with RTLD_LOCAL -- they get
independent ELF scopes, and in particular LD_DEBUG=scopes seems to indicate
that we actually end up with two different instances of libncurses.so.5 --
they're both loaded from the same file, but because they're loaded into
different ELF scopes they might act differently. (E.g., if A.so interposes some
symbol in libncurses, then when A.so calls into its copy of libncurses then
libncurses might end up calling back into A.so; but when B.so calls into its
copy of libncurses then will never call back into A.so.)

OTOH, looking at elf/dl-load.c:_dl_map_object it seems like the current
behavior might be intentional. At the very least this is a documentation bug --
Windows has somewhat similar behavior (if some DLL with a given basename has
been loaded, then attempting to load another DLL with the same basename will
short-circuit all the normal library searching and simply return the previously
loaded DLL, even if it's no longer on the search path), but on Windows at least
this is well documented.

(The actual situation that led to the discovery of this issue is that we're
trying to package up Python extensions into self-contained bundles that can run
on many different linux systems, which involves vendoring libraries like
libgfortran. And to our surprise we found that two independently distribute
Python extensions that each had their own vendored copy of libgfortran can
interfere with each other, or with locally-compiled Python extensions that
expect to use the system libgfortran. See:
https://mail.python.org/pipermail/wheel-builders/2016-March/000069.html)

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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