Until getauxval(AT_SECURE) was added, there did not appear to be a good way to detect if a process is running setuid/setgid or not. You can find various discussions about how to implement the BSD issetugid() function on Linux for reference. Checks like (uid==euid||gid==egid) can fail in various ways, e.g. it cannot detect if a process has changed its uid/gid back, it is racy in multi-threaded contexts, among other issues. I think that future glibc versions should only use AT_SECURE, removing the getuid/geteuid check. If AT_SECURE is unavailable, just assume the worst. <snip> case AT_SECURE: seen = -1; __libc_enable_secure = av->a_un.a_val; __libc_enable_secure_decided = 1; <snip> __libc_init_secure (void) { if (__libc_enable_secure_decided == 0) __libc_enable_secure = (__geteuid () != __getuid () || __getegid () != __getgid ()); } <snip> char * __libc_secure_getenv (name) const char *name; { return __libc_enable_secure ? NULL : getenv (name); }
__libc_enable_secure is computed by the libc initializer before any application code is run. No multi threading, no setuid/setgid calls.
On Sun, 29 Jun 2014, busterb at gmail dot com wrote: > contexts, among other issues. I think that future glibc versions should only > use AT_SECURE, removing the getuid/geteuid check. If AT_SECURE is unavailable, > just assume the worst. AT_SECURE is always available, since we removed support for pre-2.6 kernels.
Should we add a check which aborts if AT_SECURE is not present? Beyond that, there isn't anything libc can do here.
Thank you for the clarification. Though AT_SECURE is available in all kernels that glibc supports, is there be any way for an adversary to cause the fallback case to be triggered through external means? That there is a fallback case is a little misleading since it does not also perform the capabilities checks that the kernel does, so I don't think one would want it to inadvertently execute on any kernel that implements capabilities: http://lxr.free-electrons.com/source/security/commoncap.c#L590
(In reply to Brent Cook from comment #4) > Though AT_SECURE is available in all kernels that glibc supports, is there > be any way for an adversary to cause the fallback case to be triggered > through external means? No, the kernel prepares the aux vector as part of the execve implementation. It is possible to invoke the new process through userspace emulation, supplying a bogus aux vector, but then, no privilege transition occurs, so there is no security impact.
So at worst, the fallback case is a vestigial tail? It would seem to be ready for the chopping block if so.
elf/enbl-secure.c is used on Hurd as well as Linux, but I suppose that part of the code ought to be disabled if HAVE_AUX_SECURE.