Recently I've been working on the Comedi ebuild in my Gentoo overlay, wrestling with the following error:
* QA Notice: The following files contain insecure RUNPATHs
* Please file a bug about this at http://bugs.gentoo.org/
* with the maintaining herd of the package.
* /usr/lib:/var/tmp/portage/sci-libs/comedilib-9999/work/comedilib-9999/lib/.libs usr/lib/ruby/site_ruby/1.8/i686-linux/comedi.so
While tracking this down the source of this error, I learned a lot about dynamic linking on Linux, so here's the condensed version.
RPATH
, RUNPATH
, and LD_LIBRARY_PATH
. The current state of
affairs is well summarized on the Debian wiki, which lists
the library search path:
- the
RPATH
binary header (set at build-time) of the library causing the lookup (if any) - the
RPATH
binary header (set at build-time) of the executable - the
LD_LIBRARY_PATH
environment variable (set at run-time) - the
RUNPATH
binary header (set at build-time) of the executable /etc/ld.so.cache
- base library directories (
/lib
and/usr/lib
)
There was a big dust-up between Debian and libtool back in 1999 when
libtool-generated RPATH
s caused problems during the libc5 to libc6
transition. The mailing list discussion makes for amusing and
informative reading, if you've got a spare hour or two ;). If not,
you should at least read the opening post, the description of
competing contracts, and Buddha Buck's description of how
linking works, although I imagine things might have changed
since then. The Debian / libtool compromise (don't set RPATH by
default for directories in the dynamic linker search path) was
implemented in libtool 1.5.2 (released in 2004, see the Debian
wiki), so this is not as big an issue as it once was.
By the way, it looks like RUNPATH
was added since 1999 as a version
of RPATH
that did not override LD_LIBRARY_PATH
, which is good,
since LD_LIBARY_PATH
gives you a way to link against libraries in,
say,
/var/tmp/portage/sci-libs/comedilib-9999/work/comedilib-9999/lib/.libs
to test your executable before installation.
Anyhow, issues with rpaths persist. Since it both hard to
predict all installation configurations at compile time, and tools to
change rpaths later on (i.e. chrpath
) aren't able to increase the
size of the rpath string on Linux (they can on Solaris,
because Solaris leaves a bit of padding at the end of the dynamic
string table in the compiled ELF file). This means you will have
trouble moving a library out of the standard library path into some
out-of-the-way location. However, in the more common case of
installing a library into the standard library path, chrpath
is
the tool you need, and it solved my comedilib QA issue.
Along the way, I ran across two other interesting posts by Diego Pettenò about not bundling libraries.