Perhaps this is a trivial question, but how accessible are environment variables in Linux between different users?

e.g. if Alice executes

export FAVORITE_FOOD=`cat /home/alice/fav_food.txt`


Can Eve tell what's Alice's favourite food? (Assuming both Alice and Eve are normal users, and Eve doesn't have read access to /home/alice/fav_food.txt)

Let's trace the flow of the confidential data. In this analysis, it is understood that anything Alice can do, root can also do. Also an external observer “one level up” (e.g. with physical access to snoop on the disk bus, or in the hypervisor if the code is running in the virtual machine) might be able to access the data.

First, the data is loaded from a file. Assuming that only Alice has read permission on the file and the file is not otherwise leaked, only Alice can call cat /home/alice/fav_food.txt successfully. The data is then in the memory of the cat process, where only that process can access it. The data is transmitted over a pipe from the cat command to the calling shell; only the two processes involved can see the data on the pipe. The data is then in the memory of the shell process, again private to that process.

At some point, the data will end up in the shell's environment. Depending on the shell, this may happen when the export statement is executed, or only when the shell executes an external program. At this point, the data will be an argument of an execve system call. After that call, the data will be in the environment of the child process.

The environment of a process is just as private as the rest of that process's memory (from mm->env_start to mm->env_end in the process's memory map). It's contiguous with the initial thread's stack. However, there is a special mechanism that allows other processes to view a copy of the environment: the environ file in the process's /proc directory (/proc/$pid/environ). This file is only readable by its owner, who is the user running the process (for a privileged process, that's the effective UID). (Note that the command line arguments in /proc/$pid/cmdline, on the other hand, are readable by all.) You can audit the kernel source to verify that this is the only way to leak the environment of a process.

There is another potential source for leaking the environment: during the execve call. The execve system call does not directly leak the environment. However, there is a generic audit mechanism that can log the arguments of every system call, including execve. So if auditing is enabled, the environment can be sent through the audit mechanism and end up in a log file. On a decently configured system, only the administrator has access to the log file (on my default Debian installation, it's /var/log/audit/audit.log, only readable by root, and written to by the auditd daemon running as root).

I lied above: I wrote that the memory of a process cannot be read by another process. This is in fact not true: like all unices, Linux implements the ptrace system call. This system call allows a process to inspect the memory and even execute code in the context of another process. It's what allows debuggers to exist. Only Alice can trace Alice's processes. Furthermore, if a process is privileged (setuid or setgid), only root can trace it.

Conclusion: the environment of a process is only available to the user (euid) running the process.

Note that I assume that there is no other process that might leak the data. There is no setuid root program on a normal Linux installation that might expose a process's environment. (On some older unices, ps was a setuid root program that parsed some kernel memory; some variants would happily display a process's environment to any and all. On Linux, ps is unprivileged and gets its data from /proc like everyone else.).

(Note that this applies to reasonably current versions of Linux. A very long time ago, I think in the 1.x kernel days, the environment was world-readable.)
