LinuxCommandLibrary

ldd

List shared library dependencies of executables

TLDR

Display shared library dependencies of a binary

$ ldd [path/to/binary]
copy

Display all information about dependencies
$ ldd [[-v|--verbose]] [path/to/binary]
copy

Display unused direct dependencies
$ ldd [[-u|--unused]] [path/to/binary]
copy

Report missing data objects and perform data relocations
$ ldd [[-d|--data-relocs]] [path/to/binary]
copy

Report missing data objects and functions, and perform relocations for both
$ ldd [[-r|--function-relocs]] [path/to/binary]
copy

SYNOPSIS

ldd [OPTION...] FILE...

PARAMETERS

-v, --verbose
    Print all information, including symbol versioning and unused direct dependencies.

-u, --unused
    Print unused direct dependencies (dependencies that are not referenced by any symbol in the object).

-r, --reloc-info
    Print relocation information. Performs relocations and reports any missing objects or functions. This implies -v.

-d, --data-relocs
    Perform data relocations and report missing objects. This implies -r and -v.

-p, --audit
    Use the auditing interface.

-f, --format FORMAT
    Specify the output format string. This is typically used for scripting and advanced parsing.

--help
    Display a help message and exit.

--version
    Output version information and exit.

--depth N
    Limit the maximum depth of dependency search to N levels.

--root PATH
    Search for dependencies within the specified root directory.

DESCRIPTION

ldd (list dynamic dependencies) is a command-line utility in Unix-like operating systems that displays the shared libraries required by each program or shared library specified on its command line. It's an invaluable tool for diagnosing issues related to missing or incompatible shared libraries.

When you run ldd against an executable, it effectively executes the program under a special environment where the dynamic linker (ld.so or ld-linux.so) is instructed to trace and report all library dependencies, rather than actually running the program's main logic. The output typically lists each required library, its resolved path on the system, and its memory address offset if loaded. If a library cannot be found, ldd reports "not found".

While highly useful for debugging and system administration, it's crucial to understand its underlying mechanism for security reasons, as it involves executing the target binary.

CAVEATS

ldd works by setting a special environment variable (LD_TRACE_LOADED_OBJECTS) and executing the program. Because of this, it is highly inadvisable to run ldd on untrusted executables, as arbitrary code could be executed with the permissions of the user running ldd. For untrusted binaries, safer alternatives like objdump -p or readelf -d should be used. ldd also cannot be used for statically linked executables, as they do not rely on shared libraries.

SECURITY CONSIDERATIONS

The primary concern with ldd is its execution model. When you run ldd <program>, it essentially executes <program> with the LD_TRACE_LOADED_OBJECTS environment variable set. If <program> is a malicious or untrusted binary, it can exploit this execution to perform arbitrary actions, potentially using specially crafted constructors or other ELF file features. This means a malicious program could execute code, create files, or modify system settings with the permissions of the user who ran ldd. Always use ldd only on trusted binaries. For untrusted binaries, use tools like objdump -p or readelf -d to inspect dependencies safely, as these tools parse the binary file directly without executing it.

HISTORY

ldd has been a staple utility in Unix-like operating systems for many years, evolving as part of the GNU C Library (glibc) project. Its core functionality has remained consistent, providing a crucial insight into dynamic linking. Over time, particularly with increasing awareness of supply chain security, the security implications of its execution model have become more widely highlighted, leading to stronger recommendations against its use on untrusted binaries.

SEE ALSO

ld.so(8), objdump(1), readelf(1), strace(1), dlopen(3)

Copied to clipboard