Revert "stack protector: use AT_RANDOM"

The AT_RANDOM changes broke setuid / setgid executables
such as "ping". When the linker executes a setuid program,
it cleans the environment, removing any invalid environment
entries, and adding "NULL"s to the end of the environment
array for each removed variable. Later on, we try to determine
the location of the aux environment variable, and get tripped
up by these extra NULLs.

Reverting this patch will get setuid executables working again,
but getauxval() is still broken for setuid programs because of
this bug.

This reverts commit e3a49a8661125f24aec8a1453e54b3b78005e21e.

Change-Id: I05c58a896b1fe32cfb5d95d43b096045cda0aa4a
diff --git a/libc/bionic/libc_init_common.c b/libc/bionic/libc_init_common.c
index e4ad2ee..86e1eb5 100644
--- a/libc/bionic/libc_init_common.c
+++ b/libc/bionic/libc_init_common.c
@@ -53,22 +53,6 @@
 
 int __system_properties_init(void);
 
-static Elf32_auxv_t* get_aux_from_elfdata(uintptr_t* elf_data) {
-  int argc = *elf_data;
-  char** argv = (char**) (elf_data + 1);
-  char** envp = argv + argc + 1;
-
-  // The auxiliary vector is at the end of the environment block
-  while(*envp != NULL) {
-    envp++;
-  }
-  /* The end of the environment block is marked by two NULL pointers */
-  envp++;
-
-  return (Elf32_auxv_t*) envp;
-}
-
-
 /* Init TLS for the initial thread. Called by the linker _before_ libc is mapped
  * in memory. Beware: all writes to libc globals from this function will
  * apply to linker-private copies and will not be visible from libc later on.
@@ -80,7 +64,7 @@
  * This function also stores the elf_data argument in a specific TLS slot to be later
  * picked up by the libc constructor.
  */
-void __libc_init_tls(uintptr_t* elf_data) {
+void __libc_init_tls(unsigned** elf_data) {
   unsigned stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
   unsigned stack_size = 128 * 1024;
   unsigned stack_bottom = stack_top - stack_size;
@@ -93,7 +77,6 @@
   _init_thread(&thread, gettid(), &thread_attr, (void*) stack_bottom, false);
 
   static void* tls_area[BIONIC_TLS_SLOTS];
-  __libc_auxv = get_aux_from_elfdata(elf_data);
   __init_tls(tls_area, &thread);
   tls_area[TLS_SLOT_BIONIC_PREINIT] = elf_data;
 }
@@ -113,7 +96,14 @@
   __progname = argv[0] ? argv[0] : "<unknown>";
   environ = envp;
 
-  __libc_auxv = get_aux_from_elfdata(elf_data);
+  // The auxiliary vector is at the end of the environment block
+  while(*envp != NULL) {
+    envp++;
+  }
+  /* The end of the environment block is marked by two NULL pointers */
+  envp++;
+
+  __libc_auxv = (Elf32_auxv_t*) envp;
 
   __system_properties_init(); // Requires 'environ'.
 }
diff --git a/libc/bionic/libc_init_static.c b/libc/bionic/libc_init_static.c
index 1cef632..24a4397 100644
--- a/libc/bionic/libc_init_static.c
+++ b/libc/bionic/libc_init_static.c
@@ -96,7 +96,7 @@
     int  argc;
     char **argv, **envp;
 
-    __libc_init_tls(elfdata);
+    __libc_init_tls(NULL);
 
     /* Initialize the C runtime environment */
     __libc_init_common(elfdata);
diff --git a/libc/private/bionic_ssp.h b/libc/private/bionic_ssp.h
index 14ced64..697216c 100644
--- a/libc/private/bionic_ssp.h
+++ b/libc/private/bionic_ssp.h
@@ -29,8 +29,8 @@
 #ifndef _PRIVATE_SSP_H
 #define _PRIVATE_SSP_H
 
-#include <string.h>
-#include <sys/auxv.h>
+#include <errno.h>
+#include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
@@ -48,11 +48,27 @@
 extern void __stack_chk_fail();
 
 __inline__ static void* __attribute__((always_inline)) __generate_stack_chk_guard(void) {
+  union {
+    uintptr_t value;
+    char bytes[sizeof(uintptr_t)];
+  } u;
 
-  void* src = (void*) getauxval(AT_RANDOM);
-  void* result;
-  memcpy(&result, src, sizeof(result));
-  return result;
+  /* Try pulling random bytes from /dev/urandom. */
+  int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY));
+  if (fd != -1) {
+    ssize_t byte_count = TEMP_FAILURE_RETRY(read(fd, &u.bytes, sizeof(u)));
+    close(fd);
+    if (byte_count == sizeof(u)) {
+      return (void*) u.value;
+    }
+  }
+
+  /* If that failed, switch to 'terminator canary'. */
+  u.bytes[0] = 0;
+  u.bytes[1] = 0;
+  u.bytes[2] = '\n';
+  u.bytes[3] = 255;
+  return (void*) u.value;
 }
 
 __END_DECLS
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index b33e53e..f661ccf 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -29,7 +29,6 @@
 #define _SYS_TLS_H
 
 #include <sys/cdefs.h>
-#include <stdint.h>
 
 __BEGIN_DECLS
 
@@ -135,7 +134,7 @@
 extern void*  __get_stack_base(int  *p_stack_size);
 
 /* Initialize the TLS. */
-extern void __libc_init_tls(uintptr_t* elfdata);
+extern void __libc_init_tls(unsigned** elfdata);
 
 __END_DECLS