In computer science, rpath designates the run-time search path hard-coded in an executable file or library. Dynamic linking loaders use the rpath to find required libraries.
Specifically, it encodes a path to shared libraries into the header of an executable (or another shared library). This RPATH header value (so named in the Executable and Linkable Format header standards) may either override or supplement the system default dynamic linking search paths.
The rpath of an executable or shared library is an optional entry in the <code>.dynamic</code> section of the ELF executable or shared libraries, with the type <code>DT_RPATH</code>, called the <code>DT_RPATH</code> attribute. It can be stored there at link time by the linker. Tools such as <code>chrpath</code> and <code>patchelf</code> can create or modify the entry later.
Modern computer executables use dynamic libraries, which are separate loadable files, to reduce the duplication of code. When such an executable is run, the dynamic linker <code>ld.so</code> goes through the dynamic library entries and loads them for use by the executable program. Because libraries can be located in many possible locations, the ELF format has the <code>DT_RPATH</code> entry to specify to <code>ld.so</code> where to find the libraries.
The different dynamic linkers for ELF implement the use of the <code>DT_RPATH</code> attribute in different ways. The main divergence lies in:
The dynamic linker of the GNU C Library searches for shared libraries in the following locations in order:
Failing to find the shared library in all these locations will raise the "cannot open shared object file: No such file or directory" error.
Notes:
Relative paths are supported by the special token <code>$ORIGIN</code>, which expands to the directory of the executable at runtime. For example, <code>-Wl,-rpath,$ORIGIN</code> would add the directory the executable is in to the rpath. This allows for building binaries that can be freely moved across different folders.
The GNU Linker (GNU ld) implements a feature which it calls "new-dtags", which can be used to insert an rpath that has lower precedence than the <code>LD_LIBRARY_PATH</code> environment variable.
If the new-dtags feature is enabled in the linker (<code>--enable-new-dtags</code>), GNU <code>ld</code>, besides setting the <code>DT_RPATH</code> attribute, also sets the <code>DT_RUNPATH</code> attribute to the same string. At run time, if the dynamic linker finds a <code>DT_RUNPATH</code> attribute, it ignores the value of the <code>DT_RPATH</code> attribute, with the effect that <code>LD_LIBRARY_PATH</code> is checked first and the paths in the <code>DT_RUNPATH</code> attribute are only searched afterwards.
The ld dynamic linker does not search <code>DT_RUNPATH</code> locations for transitive dependencies, unlike <code>DT_RPATH</code>.
Instead of specifying the <code>-rpath</code> to the linker, the environment variable <code>LD_RUN_PATH</code> can be set to the same effect.
The dynamic linker of Solaris, specifically <code>/lib/ld.so</code> of SunOS 5.8 and similar systems looks for libraries in the directories specified in the <code>LD_LIBRARY_PATH</code> variable before looking at the <code>DT_RPATH</code> attribute. Sun Microsystems was the first to introduce dynamic library loading. Sun later added the rpath option to ld and used it in essential libraries as an added security feature. GNU ld did the same to support Sun-style dynamic libraries.
<code>$ORIGIN</code> is supported.
ELF format:
Non-ELF formats:
The use of rpath and also runpath can present security risks where the value applied includes directories under an attacker's control. This can include cases where the value defined explicitly references an attacker writable location but also instances where a relative path is used via <code>$ORIGIN</code>, or where a directory statement is left unpopulated. This can be leveraged to trick the binary into loading malicious libraries from one or other of the directories under an attacker's control. This is especially dangerous with setUID binaries, as these binaries run as a different (usually higher-permission-level, often root) user.