Merge changes I7f32dc9f,I9d88ddb1

* changes:
  Revert "Revert "Attempt to use arc4random where getauxval(AT_RANDOM) is used.""
  Revert "Revert "Update getentropy_linux.c from upstream.""
diff --git a/libc/Android.bp b/libc/Android.bp
index 62ca943..00932de 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1209,6 +1209,7 @@
         "bionic/arpa_inet.cpp",
         "bionic/assert.cpp",
         "bionic/atof.cpp",
+        "bionic/bionic_arc4random.cpp",
         "bionic/bionic_netlink.cpp",
         "bionic/bionic_systrace.cpp",
         "bionic/bionic_time_conversions.cpp",
diff --git a/libc/NOTICE b/libc/NOTICE
index a2f2b0a..cdf29e3 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -5503,7 +5503,7 @@
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 Emulation of getentropy(2) as documented at:
-http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+http://man.openbsd.org/getentropy.2
 
 -------------------------------------------------------------------
 
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index b5a83f4..f3dbfa5 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -29,6 +29,7 @@
 #include "libc_init_common.h"
 
 #include "private/KernelArgumentBlock.h"
+#include "private/bionic_arc4random.h"
 #include "private/bionic_auxv.h"
 #include "private/bionic_globals.h"
 #include "private/bionic_ssp.h"
@@ -41,9 +42,7 @@
 uintptr_t __stack_chk_guard = 0;
 
 void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
-  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
-  // Take the first 4/8 for the -fstack-protector implementation.
-  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(args.getauxval(AT_RANDOM));
+  __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard), args);
 }
 
 // Setup for the main thread. For dynamic executables, this is called by the
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
new file mode 100644
index 0000000..d20cb68
--- /dev/null
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "private/bionic_arc4random.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/auxv.h>
+#include <syscall.h>
+#include <unistd.h>
+
+#include "private/KernelArgumentBlock.h"
+#include "private/libc_logging.h"
+
+void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args) {
+  static bool have_getrandom = syscall(SYS_getrandom, nullptr, 0, 0) == -1 && errno != ENOSYS;
+  static bool have_urandom = access("/dev/urandom", R_OK) == 0;
+  static size_t at_random_bytes_consumed = 0;
+
+  if (have_getrandom || have_urandom) {
+    arc4random_buf(buf, n);
+    return;
+  }
+
+  if (at_random_bytes_consumed + n > 16) {
+    __libc_fatal("ran out of AT_RANDOM bytes, have %zu, requested %zu",
+                 16 - at_random_bytes_consumed, n);
+  }
+
+  memcpy(buf, reinterpret_cast<char*>(args.getauxval(AT_RANDOM)) + at_random_bytes_consumed, n);
+  at_random_bytes_consumed += n;
+  return;
+}
diff --git a/libc/bionic/getentropy_linux.c b/libc/bionic/getentropy_linux.c
index 409bd7d..98fb6fb 100644
--- a/libc/bionic/getentropy_linux.c
+++ b/libc/bionic/getentropy_linux.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getentropy_linux.c,v 1.28 2014/07/20 03:24:10 deraadt Exp $	*/
+/*	$OpenBSD: getentropy_linux.c,v 1.42 2016/04/19 20:20:24 tj Exp $	*/
 
 /*
  * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -17,7 +17,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * Emulation of getentropy(2) as documented at:
- * http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
+ * http://man.openbsd.org/getentropy.2
  */
 
 #define	_POSIX_C_SOURCE	199309L
@@ -27,8 +27,8 @@
 #include <sys/ioctl.h>
 #include <sys/resource.h>
 #include <sys/syscall.h>
-#ifdef HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h>
+#ifdef SYS__sysctl
+#include <linux/sysctl.h>
 #endif
 #include <sys/statvfs.h>
 #include <sys/socket.h>
@@ -51,8 +51,8 @@
 #include <openssl/sha.h>
 #endif
 
+#include <linux/types.h>
 #include <linux/random.h>
-#include <linux/sysctl.h>
 #ifdef HAVE_GETAUXVAL
 #include <sys/auxv.h>
 #endif
@@ -76,9 +76,7 @@
 int	getentropy(void *buf, size_t len);
 
 static int gotdata(char *buf, size_t len);
-#ifdef SYS__getrandom
 static int getentropy_getrandom(void *buf, size_t len);
-#endif
 static int getentropy_urandom(void *buf, size_t len);
 #ifdef SYS__sysctl
 static int getentropy_sysctl(void *buf, size_t len);
@@ -95,17 +93,17 @@
 
 	if (len > 256) {
 		errno = EIO;
-		return -1;
+		return (-1);
 	}
 
-#ifdef SYS__getrandom
 	/*
 	 * Try descriptor-less getrandom()
 	 */
 	ret = getentropy_getrandom(buf, len);
 	if (ret != -1)
 		return (ret);
-#endif
+	if (errno != ENOSYS)
+		return (-1);
 
 	/*
 	 * Try to get entropy with /dev/urandom
@@ -122,7 +120,7 @@
 	 * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
 	 * sysctl is a failsafe API, so it guarantees a result.  This
 	 * should work inside a chroot, or when file descriptors are
-	 * exhuasted.
+	 * exhausted.
 	 *
 	 * However this can fail if the Linux kernel removes support
 	 * for sysctl.  Starting in 2007, there have been efforts to
@@ -190,39 +188,26 @@
 	for (i = 0; i < len; ++i)
 		any_set |= buf[i];
 	if (any_set == 0)
-		return -1;
-	return 0;
+		return (-1);
+	return (0);
 }
 
-#ifdef SYS__getrandom
 static int
 getentropy_getrandom(void *buf, size_t len)
 {
-#if 0
-
-/* Hand-definitions until the API becomes commonplace */
-#ifndef SYS__getrandom
-#ifdef __LP64__
-#define SYS__getrandom 317
-#else
-#define SYS__getrandom 354
-#endif
-#endif
-	struct __getrandom_args args = {
-		.buf = buf;
-		.len = len;
-		.flags = 0;
-	};
-
+	int pre_errno = errno;
+	int ret;
 	if (len > 256)
 		return (-1);
-	ret = syscall(SYS__getrandom, &args);
-	if (ret == len)
-		return (0);
-#endif
-	return -1;
+	do {
+		ret = syscall(SYS_getrandom, buf, len, 0);
+	} while (ret == -1 && errno == EINTR);
+
+	if ((size_t)ret != len)
+		return (-1);
+	errno = pre_errno;
+	return (0);
 }
-#endif
 
 static int
 getentropy_urandom(void *buf, size_t len)
@@ -275,11 +260,11 @@
 	close(fd);
 	if (gotdata(buf, len) == 0) {
 		errno = save_errno;
-		return 0;		/* satisfied */
+		return (0);		/* satisfied */
 	}
 nodevrandom:
 	errno = EIO;
-	return -1;
+	return (-1);
 }
 
 #ifdef SYS__sysctl
@@ -297,7 +282,7 @@
 		struct __sysctl_args args = {
 			.name = mib,
 			.nlen = 3,
-			.oldval = (char*) buf + i,
+			.oldval = (char *)buf + i,
 			.oldlenp = &chunk,
 		};
 		if (syscall(SYS__sysctl, &args) != 0)
@@ -310,13 +295,12 @@
 	}
 sysctlfailed:
 	errno = EIO;
-	return -1;
+	return (-1);
 }
 #endif /* SYS__sysctl */
 
 #ifdef HAVE_OPENSSL
-
-static int cl[] = {
+static const int cl[] = {
 	CLOCK_REALTIME,
 #ifdef CLOCK_MONOTONIC
 	CLOCK_MONOTONIC,
@@ -347,7 +331,7 @@
 	SHA512_CTX *ctx = data;
 
 	SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
-	return 0;
+	return (0);
 }
 
 static int
@@ -556,10 +540,9 @@
 	memset(results, 0, sizeof results);
 	if (gotdata(buf, len) == 0) {
 		errno = save_errno;
-		return 0;		/* satisfied */
+		return (0);		/* satisfied */
 	}
 	errno = EIO;
-	return -1;
+	return (-1);
 }
-
 #endif /* HAVE_OPENSSL */
diff --git a/libc/bionic/setjmp_cookie.cpp b/libc/bionic/setjmp_cookie.cpp
index 3be675a..4fa68c2 100644
--- a/libc/bionic/setjmp_cookie.cpp
+++ b/libc/bionic/setjmp_cookie.cpp
@@ -34,14 +34,14 @@
 #include <sys/auxv.h>
 #include <sys/cdefs.h>
 
+#include "private/bionic_arc4random.h"
 #include "private/bionic_globals.h"
 #include "private/libc_logging.h"
 #include "private/KernelArgumentBlock.h"
 
-void __libc_init_setjmp_cookie(libc_globals* globals,
-                               KernelArgumentBlock& args) {
-  char* random_data = reinterpret_cast<char*>(args.getauxval(AT_RANDOM));
-  long value = *reinterpret_cast<long*>(random_data + 8);
+void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args) {
+  long value;
+  __libc_safe_arc4random_buf(&value, sizeof(value), args);
 
   // Mask off the last bit to store the signal flag.
   globals->setjmp_cookie = value & ~1;
diff --git a/libc/private/bionic_arc4random.h b/libc/private/bionic_arc4random.h
new file mode 100644
index 0000000..d26a4e7
--- /dev/null
+++ b/libc/private/bionic_arc4random.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PRIVATE_BIONIC_ARC4RANDOM_H_
+#define _PRIVATE_BIONIC_ARC4RANDOM_H_
+
+#include <stddef.h>
+
+#include "private/KernelArgumentBlock.h"
+
+/*
+ * arc4random aborts if it's unable to fetch entropy, which is always the case
+ * for init on devices without getrandom(2), since /dev/random hasn't been
+ * created yet. Provide a wrapper function that falls back to AT_RANDOM if
+ * we don't have getrandom and /dev/urandom is missing.
+ */
+
+void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args);
+
+#endif