Port prctl(PR_CAPBSET_DROP) patches dalvik-dev

A combination of the following two dalvik commits:

* https://android-review.googlesource.com/51731
* https://android-review.googlesource.com/51697

Commit message from c0ecb5bdbf465ef05ed3379c13ff9a4245412ce7

Zygote: limit the bounding capability set to CAP_NET_RAW

Prevent a zygote spawned application from acquiring
capabilities other than CAP_NET_RAW.  The only Zygote
accessible program on Android which grants capabilities
is /system/bin/ping (CAP_NET_RAW), so we don't need to
keep the other capabilities in our bounding set.
If the kernel doesn't support file capabilities, we
end up printing approx 30 lines of warning messages. Hopefully
this will encourage kernel developers to upgrade. In a future
change, we can turn a prctl(PR_CAPBSET_DROP) failure into
a fatal error.

Commit message from daa97a125fc2caa5faa44a31a768f318a26c7b65

Zygote: address comments from previous review.

Previous review at https://android-review.googlesource.com/51731

Change-Id: If43d049767a9128d73f51076a674f8b87351396d
diff --git a/src/native/dalvik_system_Zygote.cc b/src/native/dalvik_system_Zygote.cc
index 3daec75..1c4c986 100644
--- a/src/native/dalvik_system_Zygote.cc
+++ b/src/native/dalvik_system_Zygote.cc
@@ -41,6 +41,7 @@
 #if defined(__linux__)
 #include <sys/personality.h>
 #include <sys/utsname.h>
+#include <linux/capability.h>
 #endif
 
 namespace art {
@@ -203,6 +204,24 @@
   }
 }
 
+static void DropCapabilitiesBoundingSet() {
+  for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
+    if (i == CAP_NET_RAW) {
+      // Don't break /system/bin/ping
+      continue;
+    }
+    int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
+    if (rc == -1) {
+      if (errno == EINVAL) {
+        PLOG(ERROR) << "prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
+                    << "your kernel is compiled with file capabilities support";
+      } else {
+        PLOG(FATAL) << "prctl(PR_CAPBSET_DROP) failed";
+      }
+    }
+  }
+}
+
 static void SetCapabilities(int64_t permitted, int64_t effective) {
   __user_cap_header_struct capheader;
   __user_cap_data_struct capdata;
@@ -234,6 +253,7 @@
 
 static void EnableDebugger() {}
 static void EnableKeepCapabilities() {}
+static void DropCapabilitiesBoundingSet() {};
 static void SetCapabilities(int64_t, int64_t) {}
 static void SetSchedulerPolicy() {}
 
@@ -375,6 +395,8 @@
       EnableKeepCapabilities();
     }
 
+    DropCapabilitiesBoundingSet();
+
     MountExternalStorage(uid, mount_external);
 
     SetGids(env, javaGids);