aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elf/dl-support.c5
-rw-r--r--elf/elf.h4
-rw-r--r--sysdeps/generic/dl-sysdep.c49
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h6
-rw-r--r--sysdeps/unix/sysv/linux/ldsodefs.h8
5 files changed, 53 insertions, 19 deletions
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 0d6ce6a12b..6d83da3328 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -188,6 +188,11 @@ _dl_aux_init (ElfW(auxv_t) *av)
gid ^= av->a_un.a_val;
seen |= 8;
break;
+ case AT_SECURE:
+ seen = -1;
+ __libc_enable_secure = av->a_un.a_val;
+ __libc_enable_secure_decided = 1;
+ break;
}
if (seen == 0xf)
{
diff --git a/elf/elf.h b/elf/elf.h
index 982ce2ca20..a5ac9dbd00 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -945,7 +945,9 @@ typedef struct
/* A special ignored value for PPC, used by the kernel to control the
interpretation of the AUXV. Must be > 16. */
-#define AT_IGNOREPPC 22 /* Entry should be ignored */
+#define AT_IGNOREPPC 22 /* Entry should be ignored. */
+
+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
/* Pointer to the global system page used for system calls and other
nice things. */
diff --git a/sysdeps/generic/dl-sysdep.c b/sysdeps/generic/dl-sysdep.c
index 278289e827..7990f31fdc 100644
--- a/sysdeps/generic/dl-sysdep.c
+++ b/sysdeps/generic/dl-sysdep.c
@@ -79,14 +79,19 @@ _dl_sysdep_start (void **start_argptr,
ElfW(Word) phnum = 0;
ElfW(Addr) user_entry;
ElfW(auxv_t) *av;
+#ifdef HAVE_AUX_SECURE
+# define set_seen_secure() ((void) 0)
+#else
uid_t uid = 0;
gid_t gid = 0;
-#ifdef HAVE_AUX_XID
-# define set_seen(tag) (tag) /* Evaluate for the side effects. */
-#else
unsigned int seen = 0;
-# define M(type) (1 << (type))
-# define set_seen(tag) seen |= M ((tag)->a_type)
+# define set_seen_secure() (seen = -1)
+# ifdef HAVE_AUX_XID
+# define set_seen(tag) (tag) /* Evaluate for the side effects. */
+# else
+# define M(type) (1 << (type))
+# define set_seen(tag) seen |= M ((tag)->a_type)
+# endif
#endif
DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, INTUSE(_dl_argv), _environ,
@@ -123,6 +128,10 @@ _dl_sysdep_start (void **start_argptr,
case AT_EGID:
gid ^= av->a_un.a_val;
break;
+ case AT_SECURE:
+ seen = -1;
+ INTUSE(__libc_enable_secure) = av->a_un.a_val;
+ break;
case AT_PLATFORM:
GL(dl_platform) = av->a_un.a_ptr;
break;
@@ -152,21 +161,26 @@ _dl_sysdep_start (void **start_argptr,
DL_SYSDEP_OSCHECK (dl_fatal);
#endif
- /* Fill in the values we have not gotten from the kernel through the
- auxiliary vector. */
-#ifndef HAVE_AUX_XID
+#ifndef HAVE_AUX_SECURE
+ if (seen != -1)
+ {
+ /* Fill in the values we have not gotten from the kernel through the
+ auxiliary vector. */
+# ifndef HAVE_AUX_XID
# 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);
+ SEE (UID, uid, uid);
+ SEE (EUID, uid, euid);
+ SEE (GID, gid, gid);
+ SEE (EGID, gid, egid);
+# endif
+
+ /* If one of the two pairs of IDs does not match this is a setuid
+ or setgid run. */
+ INTUSE(__libc_enable_secure) = uid | gid;
+ }
#endif
- /* If one of the two pairs of IDs does not match this is a setuid
- or setgid run. */
- INTUSE(__libc_enable_secure) = uid | gid;
-
#ifndef HAVE_AUX_PAGESIZE
if (GL(dl_pagesize) == 0)
GL(dl_pagesize) = __getpagesize ();
@@ -253,8 +267,9 @@ _dl_show_auxv (void)
[AT_UCACHEBSIZE - 2] = { "AT_UCACHEBSIZE: 0x", hex },
#ifdef NEED_DL_SYSINFO
[AT_SYSINFO - 2] = { "AT_SYSINFO: 0x", hex },
- [AT_SYSINFO_EHDR - 2] = { "AT_SYSINFO_EHDR: 0x", hex }
+ [AT_SYSINFO_EHDR - 2] = { "AT_SYSINFO_EHDR: 0x", hex },
#endif
+ [AT_SECURE - 2] = { "AT_SECURE: ", dec },
};
unsigned int idx = (unsigned int) (av->a_type - 2);
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 408352590a..d26930bce6 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -321,3 +321,9 @@
#if __LINUX_KERNEL_VERSION >= 132426
# define __ASSUME_STATFS64 1
#endif
+
+/* Starting with at least 2.5.74 the kernel passes the setuid-like exec
+ flag unconditionally up to the child. */
+#if __LINUX_KERNEL_VERSION >= 132426
+# define __ASSUME_AT_SECURE 1
+#endif
diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h
index a3c97c4731..c5fd854d70 100644
--- a/sysdeps/unix/sysv/linux/ldsodefs.h
+++ b/sysdeps/unix/sysv/linux/ldsodefs.h
@@ -1,5 +1,5 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -41,6 +41,12 @@ extern void _dl_non_dynamic_init (void) internal_function;
# define HAVE_AUX_XID
#endif
+/* We can assume that the kernel always provides the AT_SECURE value
+ in the auxiliary vector from 2.5.74 or so on. */
+#if __ASSUME_AT_SECURE
+# define HAVE_AUX_SECURE
+#endif
+
/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes
up the page size information. */
#if __ASSUME_AT_PAGESIZE