aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/dl-sysdep.c32
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h6
-rw-r--r--sysdeps/unix/sysv/linux/ldsodefs.h6
3 files changed, 24 insertions, 20 deletions
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index 0f5f0fc..17e8f4d 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -79,9 +79,7 @@ _dl_sysdep_start (void **start_argptr,
ElfW(Addr) user_entry;
ElfW(auxv_t) *av;
uid_t uid = 0;
- uid_t euid = 0;
gid_t gid = 0;
- gid_t egid = 0;
#ifdef HAVE_AUX_XID
# define set_seen(tag) (tag) /* Evaluate for the side effects. */
#else
@@ -117,16 +115,12 @@ _dl_sysdep_start (void **start_argptr,
break;
#endif
case AT_UID:
- uid = av->a_un.a_val;
- break;
- case AT_GID:
- gid = av->a_un.a_val;
- break;
case AT_EUID:
- euid = av->a_un.a_val;
+ uid ^= av->a_un.a_val;
break;
+ case AT_GID:
case AT_EGID:
- egid = av->a_un.a_val;
+ gid ^= av->a_un.a_val;
break;
case AT_PLATFORM:
GL(dl_platform) = av->a_un.a_ptr;
@@ -146,18 +140,20 @@ _dl_sysdep_start (void **start_argptr,
DL_SYSDEP_OSCHECK (dl_fatal);
#endif
- /* Linux doesn't provide us with any of these values on the stack
- when the dynamic linker is run directly as a program. */
-
+ /* Fill in the values we have not gotten from the kernel through the
+ auxiliary vector. */
#ifndef HAVE_AUX_XID
-# define SEE(UID, uid) if ((seen & M (AT_##UID)) == 0) uid = __get##uid ()
- SEE (UID, uid);
- SEE (GID, gid);
- SEE (EUID, euid);
- SEE (EGID, egid);
+# define SEE(UID, var, uid) \
+ if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
+ SEE (UID, uid, uid);
+ SEE (EUID, uid, euid);
+ SEE (GID, gid, gid);
+ SEE (EGID, gid, egid);
#endif
- INTUSE(__libc_enable_secure) = uid != euid || gid != egid;
+ /* If one of the two pairs of IDs does not mattch this is a setuid
+ or setgid run. */
+ INTUSE(__libc_enable_secure) = uid | gid;
#ifndef HAVE_AUX_PAGESIZE
if (GL(dl_pagesize) == 0)
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 562a6c7..927701a 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -171,6 +171,12 @@
# define __ASSUME_AT_PAGESIZE 1
#endif
+/* Starting with at least 2.4.0 the kernel passes the uid/gid unconditionally
+ up to the child. */
+#if __LINUX_KERNEL_VERSION >= 132097
+# define __ASSUME_AT_XID 1
+#endif
+
/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way
and the mmap2 syscall made it into the official kernel. */
#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__
diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h
index 8e37f4d..a3c97c4 100644
--- a/sysdeps/unix/sysv/linux/ldsodefs.h
+++ b/sysdeps/unix/sysv/linux/ldsodefs.h
@@ -36,8 +36,10 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function;
extern void _dl_non_dynamic_init (void) internal_function;
/* We can assume that the kernel always provides the AT_UID, AT_EUID,
- AT_GID, and AT_EGID values in the auxiliary vector. */
-#define HAVE_AUX_XID
+ AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */
+#if __ASSUME_AT_XID
+# define HAVE_AUX_XID
+#endif
/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes
up the page size information. */