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);