Linux: Why LD_LIBRARY_PATH is empty?

More precisely, what resets LD_LIBRARY_PATH that is exported with a value from a user's .profile?

The Short Answer

A parent process of the current shell which, at the same moment, is a child process of the user's login shell (which interprets .profile) has either the SUID or SGID bit set.

The manual page of dlopen(3) clearly states (regarding LD_LIBRARY_PATH):

As a security measure, this variable is ignored for set-user-ID and set-group-ID programs.

The Longer Answer

The common symptom of the problem is libraries failing to load dynamically under an X Window session from a location specified with an exported LD_LIBRARY_PATH in the user's .profile. This does happen on recent versions of Debian and Ubuntu and may happen on other distributions as well.

On Debian, the culprit is the code found in /etc/X11/Xsession.d/90x11-common_ssh-agent. This script determines if ssh-agent(1) is installed and, if true, executes the startup command of the X session as a child of ssh-agent(1)—thus making SSH keys available to all processes running in this session.

Since ssh-agent(1) has the SGID bit set, it ignores LD_LIBRARY_PATH and does not propagate the variable to its children.

The Workaround

There are several ways to solve this problem. The solution that I propose does not require administrative privileges.

In the user's .profile, export a temporary variable that holds the (future) value of LD_LIBRARY_PATH:

(the above assumes that libraries are located in the lib sub-directory of the user's home directory; change that to suit the needs of the user).

Create the script .xsession for the user:


exec x-session-manager
and make this script executable:
chmod u+x "${HOME}/.xsession"

Vadim Penzin, September 29th, 2015

I hereby place this article into the public domain.
I publish this information in the hope that it will be useful, but without ANY WARRANTY.
You are responsible for any and all consequences that may arise as the result of using this information.