Port 138b7a2e54923d99ed817f9a890c6fcd7c23c335 to art

Disable ADDR_NO_RANDOMIZE for 3.4 or greater kernels

Early kernels had memory fragmentation bugs on ARM when
ASLR was enabled. The ADDR_NO_RANDOMIZE flag was added
to work around this bug until the appropriate kernel fix
could be made.

Linux kernel 3.4 seems to have this fix, making this workaround
unnecessary.  Remove the workaround if we detect we're running
an up-to-date kernel.

(I believe the kernel patch is also in 3.3, but haven't explicitly
tested it).

Bug: 5817320
Change-Id: Ife1e511355c62c16fc90ba22811face7b573b312
diff --git a/src/native/dalvik_system_Zygote.cc b/src/native/dalvik_system_Zygote.cc
index fbd0d10..68ae7db 100644
--- a/src/native/dalvik_system_Zygote.cc
+++ b/src/native/dalvik_system_Zygote.cc
@@ -42,6 +42,7 @@
 
 #if defined(__linux__)
 #include <sys/personality.h>
+#include <sys/utsname.h>
 #endif
 
 namespace art {
@@ -337,6 +338,24 @@
 #endif
 }
 
+#if defined(__linux__)
+static bool NeedsNoRandomizeWorkaround() {
+    int major;
+    int minor;
+    struct utsname uts;
+    if (uname(&uts) == -1) {
+        return false;
+    }
+
+    if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
+        return false;
+    }
+
+    // Kernels before 3.4.* need the workaround.
+    return (major < 3) || ((major == 3) && (minor < 4));
+}
+#endif
+
 // Utility routine to fork zygote and specialize the child process.
 static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                      jint debug_flags, jobjectArray javaRlimits,
@@ -383,11 +402,13 @@
     }
 
 #if defined(__linux__)
-    // Work around ARM kernel ASLR lossage (http://b/5817320).
-    int old_personality = personality(0xffffffff);
-    int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
-    if (new_personality == -1) {
-      PLOG(WARNING) << "personality(" << new_personality << ") failed";
+    if (NeedsNoRandomizeWorkaround()) {
+        // Work around ARM kernel ASLR lossage (http://b/5817320).
+        int old_personality = personality(0xffffffff);
+        int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
+        if (new_personality == -1) {
+            PLOG(WARNING) << "personality(" << new_personality << ") failed";
+        }
     }
 #endif