Cleanup: __libc_init_AT_SECURE, auxv, sysinfo
__sanitize_environment_variables is only called when getauxval(AT_SECURE)
is true.
Instead of scanning __libc_auxv, reuse getauxval. If the entry is missing,
getauxval will set errno to ENOENT.
Reduce the number of times that __libc_sysinfo and __libc_auxv are
initialized. (Previously, __libc_sysinfo was initialized 3 times for the
linker's copy). The two variables are initialized in these places:
- __libc_init_main_thread for libc.a (including the linker copy)
- __libc_preinit_impl for libc.so
- __linker_init: the linker's copy of __libc_sysinfo is still initialized
twice, because __libc_init_main_thread runs after relocation. A later
CL consolidates the linker's two initializations.
Bug: none
Test: bionic unit tests
Change-Id: I196f4c9011b0d803ee85c07afb415fcb146f4d65
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index f943402..a860b98 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -62,13 +62,9 @@
const char* __progname;
void __libc_init_globals(KernelArgumentBlock& args) {
-#if defined(__i386__)
- __libc_init_sysinfo(args);
-#endif
// Initialize libc globals that are needed in both the linker and in libc.
// In dynamic binaries, this is run at least twice for different copies of the
// globals, once for the linker's copy and once for the one in libc.so.
- __libc_auxv = args.auxv;
__libc_globals.initialize();
__libc_globals.mutate([&args](libc_globals* globals) {
__libc_init_vdso(globals, args);
@@ -275,7 +271,6 @@
}
static void __sanitize_environment_variables(char** env) {
- bool is_AT_SECURE = getauxval(AT_SECURE);
char** src = env;
char** dst = env;
for (; src[0] != nullptr; ++src) {
@@ -283,7 +278,7 @@
continue;
}
// Remove various unsafe environment variables if we're loading a setuid program.
- if (is_AT_SECURE && __is_unsafe_environment_variable(src[0])) {
+ if (__is_unsafe_environment_variable(src[0])) {
continue;
}
dst[0] = src[0];
@@ -306,20 +301,14 @@
}
void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
- __libc_auxv = args.auxv;
__abort_message_ptr = args.abort_message_ptr;
// Check that the kernel provided a value for AT_SECURE.
- bool found_AT_SECURE = false;
- for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
- if (v->a_type == AT_SECURE) {
- found_AT_SECURE = true;
- break;
- }
- }
- if (!found_AT_SECURE) __early_abort(__LINE__);
+ errno = 0;
+ unsigned long is_AT_SECURE = getauxval(AT_SECURE);
+ if (errno != 0) __early_abort(__LINE__);
- if (getauxval(AT_SECURE)) {
+ if (is_AT_SECURE) {
// If this is a setuid/setgid program, close the security hole described in
// https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
__nullify_closed_stdio();
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index fc68b8a..08d3df4 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -51,6 +51,7 @@
#include <elf.h>
#include "libc_init_common.h"
+#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_macros.h"
#include "private/bionic_ssp.h"
@@ -78,8 +79,12 @@
// protector.
__attribute__((noinline))
static void __libc_preinit_impl(KernelArgumentBlock& args) {
- __libc_shared_globals = args.shared_globals;
+ __libc_auxv = args.auxv;
+#if defined(__i386__)
+ __libc_init_sysinfo(args);
+#endif
+ __libc_shared_globals = args.shared_globals;
__libc_init_globals(args);
__libc_init_common(args);
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f7c496a..66766fe 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -28,6 +28,9 @@
#include "linker_main.h"
+#include <link.h>
+#include <sys/auxv.h>
+
#include "linker_debug.h"
#include "linker_cfi.h"
#include "linker_gdb_support.h"
@@ -35,7 +38,6 @@
#include "linker_phdr.h"
#include "linker_utils.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
#include "private/KernelArgumentBlock.h"
@@ -48,12 +50,10 @@
#endif
#include <async_safe/log.h>
+#include <bionic/libc_init_common.h>
#include <vector>
-extern void __libc_init_globals(KernelArgumentBlock&);
-extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
-
__LIBC_HIDDEN__ extern "C" void _start();
static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);