The gnu libc documentation makes no mention of ld.so pruning the environment of
variables such as TMPDIR when running setuid/setgid programs. This makes can
make determining the cause of some missing environment values much more
confusing in some cases.
Still in glibc 2.15
This behavior is also non-conformant. The library should *ignore* such environment variables when the program was invoked as suid, but it should not prune them. A conforming application can expect to be able to inspect them (e.g. to validate them itself and use them for its own purposes if they're deemed safe) or have them successfully passed on to a new process or process image. This latter usage is safe if the program has dropped privileges before doing so, and if a program running with elevated privileges is going to exec or spawn child processes without dropping privileges, it MUST clear the whole environment or at least all but a small whitelisted set of variables to be secure.
glibc's behavior of pruning the environment actually makes things a lot LESS secure in the latter case, because programmers may forget (or assume they don't need) to do this whitelist-based pruning themselves. This is not safe, because glibc only knows about the variables which it uses, not other third-party-library-specific or application-specific variables that could be equally dangerous.
(In reply to comment #2)
> This behavior is also non-conformant. The library should *ignore* such
> environment variables when the program was invoked as suid, but it should not
> prune them.
FWIW, I recently had to implement a "setuid(); execve();" wrapper entirely in assembly, just so I could avoid this unsetting of LD_DEBUG, etc. by glibc.