From c801e76565467d2819ab0839804463f635d78b25 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 26 Jun 2003 19:54:29 +0000 Subject: 2003-06-26 Roland McGrath * elf/elf.h (AT_SECURE): New macro. * sysdeps/generic/dl-sysdep.c (_dl_sysdep_start): Grok it, set __libc_enable_secure. (_dl_show_auxv): Add AT_SECURE to name table. * elf/dl-support.c (_dl_aux_init): Grok AT_SECURE, set __libc_enable_secure and __libc_enable_secure_decided. * sysdeps/unix/sysv/linux/ldsodefs.h [__ASSUME_AT_SECURE] (HAVE_AUX_SECURE): Define it. * sysdeps/unix/sysv/linux/kernel-features.h [__LINUX_KERNEL_VERSION >= 132425] (__ASSUME_AT_SECURE): Define it. --- elf/dl-support.c | 5 ++++ elf/elf.h | 4 ++- sysdeps/generic/dl-sysdep.c | 49 ++++++++++++++++++++----------- sysdeps/unix/sysv/linux/kernel-features.h | 6 ++++ sysdeps/unix/sysv/linux/ldsodefs.h | 8 ++++- 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 -- cgit v1.2.3