Intro

I ran into an issue the other day with an executable not finding a library it depended on. I found where the library was and attempted to set LD_LIBRARY_PATH to get it on path for the executable. This had no effect. A little more digging led me to RPATH which I hadn’t heard of til this point. It turn’s out that RPATH takes precedence and can’t be overridden by LD_LIBRARY_PATH. Here’s how it factors into things and some tips that helped me in the process.

Library Resolution

Here’s loosely how it works, library resolution occurs in this order of precedence:

  1. RPATH: variable encoded directly in the binary/library at compile time, or modified after
    • note — RPATH is deprecated because it’s hardcoded in the executable and can’t be overridden by the user short of modifying the executable itself
  2. LD_LIBRARY_PATH: environment variable
  3. RUNPATH: variable encoded direcctly in the binary/library at compile time, or modified after
    • note — RUNPATH is now the preferred alternative to RPATH. It can be overridden by a user via LD_LIBRARY_PATH
  4. Cache File /etc/ld.so.cache
  5. In the default path /lib , /lib64 and then /usr/lib , /usr/lib64.

SETUID

When you use setuid to modify the user and/or group that an executable is run as (often this is done to give priviledged access via root), certain environment variables also don’t carry across this threshold due to security concerns. They are as follows:

  • LD_LIBRARY_PATH
  • LD_PROFILE
  • LD_PROFILE_OUTPUT
  • LD_AUDIT
  • LD_DEBUG
  • LD_DEBUG_OUTPUT

Tips + Tricks

  • Print out the libraries a binary depends on: LD_DEBUG=libs ldd <EXE/LIB>
    • LD_DEBUG=libs adds the search paths that ldd is using to resolve the libraries.
  • Print out the tree of dependencies: lddtree <EXE/LIB>
    • Library resolution can be a recursive search, this helps understand it in a tree format
  • Overriding RPATH/RUNPATH: patchelf --set-rpath 'PATH1:PATH2' <EXE/LIB>
  • Reading RPATH/RUNPATH from a binary/library: objdump -x <EXE/LIB> | grep "R*PATH"

References

  1. ld Man Page
  2. how to find out the dynamic libraries executables loads when run