Setting Environment Variables Without ~/.bash_profile – Status

environment-variables

LWN.net – GNOME, Wayland, and environment variables

Strode, for all that he wants to move on to a "modern" solution for environment variables, is clearly feeling the pressure that comes from wider exposure of a broken system. Thus, his most recent comment on the bug, as of this writing, reads: "Yea, I'm considering caving on this." So Fedora 25 is likely to see an update that restores the login shell to the login process; a "proper fix" will wait for later.

It's now Fedora 28… where are we on the "proper fix" side of things? Is there a forward-looking way for users to set environment variables for their sessions yet?

I.e a replacement for ~/.bash_profile which works on Fedora, and hopefully elsewhere.

Best Answer

For GNOME 3.24, Strode reverted gnome-session to load environment variables by running a login shell.

In the same comment, they included a patch for gnome-session to push these session environment variables to systemd user services. These include gnome-terminal, so it's fairly important :).


The GDM session launcher was already patched in 3.22, to import the environment from systemd --user. So the systemd environment is imported into the session, then modified by the login shell, and the result is also copied back to systemd --user.

Which should work ok... except testing on Fedora 28, it doesn't work properly for e.g. PATH, because the gdm sesssion launcher doesn't allow systemd environment variables to overwrite the pre-existing environment. I've reported it on the GNOME issue tracker.

It was agreed that login (for the text console) could accept some patch to load environment configuration before starting the users shell, but there's no change so far in util-linux v2.32.

I haven't even bothered looking for ssh patches :).

The systemd environment was already configurable in user.conf. As part of this effort, systemd v233 gained an environment.d/ format, that now supports e.g. prepending an extra directory to the existing PATH or LD_LIBRARY_PATH search lists.


I thought the best place to set environment variables for user logins would be in a PAM module - we even have pam_env already. The logic being

asking login, gdm, sshd (that'll never happen), etc. to do this is really a poor solution.

Unfortunately, the configuration of pam_env is annoyingly inconsistent between distros... and it seems there might have been a good reason for that. The ~/.pam_environment feature is considered a big "footgun" for security. See also CVE-2010-4708.

Look at pam_exec for instance. You could imagine a sysadmin using it to do some postlogin configuration or something, but a user could get root by setting LD_PRELOAD. Or pam_selinux actually uses pam_getenv directly, so a user could screw with it. But my point isn't really these specific examples, it's just to illustrate there are risks from doing it as root, and we can bypass those risks entirely, eliminating a whole class of potential security bugs, by doing it just a little later in the login process. As a general rule, if you don't need code to run as root, it shouldn't run as root! Of course, I'm still torn, because logistically, it's more awkward to do it later, but there's no question in my mind that doing it as root is riskier than doing it as the user.

The pam_exec manual explicitly states: "Commands called by pam_exec need to be aware of that the user can have controll [sic] over the environment."

re. pam_env, note fedora puts it top of the pam stack and disables ~/.pam_environment by default.

Putting it at the top of the stack is a bug and violates the explicit warning not to do this: "Since setting of PAM environment variables can have side effects to other modules, this module should be the last one on the stack."

[...] Given the confusion here, this is obviously a footgun

The general idea of using the shell configuration for this also appears to work e.g. on Ubuntu Desktop 16.04 graphical login. There is one difference, however. Fedora creates ~/.bash_profile by default, which (for bash) causes ~/.profile to be ignored. Ubuntu and other Debian-based distributions create ~/.profile by default instead. (I.e. these files are provided when you create a new user, from /etc/skel).

(I have used this on Ubuntu recently. Ubuntu seems to have changed over time w.r.t running a login shell for GUI sessions. E.g. see https://superuser.com/questions/183870/difference-between-bashrc-and-bash-profile/183980#183980, https://askubuntu.com/questions/40287/etc-profile-not-being-sourced, "Why isn't gnome-terminal a login shell", and "What shell login means ('bash -l')").

Related Question