Bug 19749 - Filter duplicate environment variables
Summary: Filter duplicate environment variables
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2016-03-01 15:44 UTC by Florian Weimer
Modified: 2016-03-01 22:26 UTC (History)
2 users (show)

See Also:
Last reconfirmed:
fweimer: security+


Note You need to log in before you can comment on or make changes to this bug.
Description Florian Weimer 2016-03-01 15:44:56 UTC
The Simson & Garfinkel's “Practical UNIX & Internet Security” (2nd edition, 1996) mentions an attack against SUID/SGID binaries involving duplicate environment variables.  In essence, this is an interpretation conflict between different environment variable list parsers (getenv, setenv, putenv, iterating through environ, looking at the envp argument to main).  Some implementations will pick the first variable, some will pick the last.

We should traverse the environment very early at process startup and normalize it, removing duplicates.

Related security advisory for CVE-2016-2381:

Comment 1 Stephane Chazelas 2016-03-01 22:09:31 UTC
To add a bit of context, in:

    setenv("PATH", "sane-value", 1);

in an executable (like a setuid/setgid executable) that has been called with envp[] having both "PATH=whatever" and "PATH=evil-path", setenv() will update the first "PATH" entry, but leave the other ones untouched and system() will execute sh with both "PATH=sane-value" and "PATH=evil-path" in its envp[].

Some sh implementations like ksh93 or zsh will consider the first env entry when there are duplicates, some like bash, dash, yash, mksh will consider the last. Some will remove duplicates, some will not. perl used to get the last when filling in %ENV upon initialisation but set the first upon assigning %ENV entries (also fooling taint-mode safeguards) and has now been fixed.

When discussed privately among shell and perl maintainers (and Debian/Redhat/Suse seclists), bash, mksh and dash maintainers have declined changing their shell so they get the first env var entry, arguing that the issue should be fixed at the libc or kernel level. ksh93 and zsh are not affected.
Comment 2 Stephane Chazelas 2016-03-01 22:13:11 UTC
Also note that "sudo"'s maintainer has also agreed to filter duplicates as that could be exploited for variables that sudo lets through like LC_*. https://www.sudo.ws/repos/sudo/rev/d4dfb05db5d7 (no released yet).
Comment 3 Florian Weimer 2016-03-01 22:26:24 UTC
Good points.  The glibc normalization code should pick the first defined variable as well, for consistency's sake.