(_dl_sysdep_start): Optimize handling of AT_UID, AT_EUID, AT_GID, and AT_EGID.
[kopensolaris-gnu/glibc.git] / sysdeps / generic / dl-sysdep.c
index 0f5f0fc..17e8f4d 100644 (file)
@@ -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)