Improve container capability bounding in containers

This change stops relying on the ro.boot.container property for dropping
a subset of capabilities and instead relies on the effective capability
mask of the Zygote process, prior to forking.

When Android is running in a pid/mount/net/user namespace, even if a
particular capability is present, some operations that require that
capability check whether it is allowed in the init namespace (instead of
in the current namespace), so they would fail even with the capability
granted within the namespace. So, explicitly dropping the capabilities
from the beginning allows for clearer signalling of which operations can
be expected to work instead of failing silently for mysterious reasons.

Bug: 63579953
Test: aosp_bullhead-eng still boots
Test: Running Zygote without CAP_SYS_MODULE makes it such that
      system_server does not request it.

Change-Id: I1d18d13341bcc04e701fd14092e7e94961728620
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index cb53106..d438490 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -678,6 +678,22 @@
   }
   return pid;
 }
+
+static uint64_t GetEffectiveCapabilityMask(JNIEnv* env) {
+    __user_cap_header_struct capheader;
+    memset(&capheader, 0, sizeof(capheader));
+    capheader.version = _LINUX_CAPABILITY_VERSION_3;
+    capheader.pid = 0;
+
+    __user_cap_data_struct capdata[2];
+    if (capget(&capheader, &capdata[0]) == -1) {
+        ALOGE("capget failed: %s", strerror(errno));
+        RuntimeAbort(env, __LINE__, "capget failed");
+    }
+
+    return capdata[0].effective |
+           (static_cast<uint64_t>(capdata[1].effective) << 32);
+}
 }  // anonymous namespace
 
 namespace android {
@@ -728,6 +744,10 @@
       capabilities |= (1LL << CAP_BLOCK_SUSPEND);
     }
 
+    // Containers run without some capabilities, so drop any caps that are not
+    // available.
+    capabilities &= GetEffectiveCapabilityMask(env);
+
     return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
             rlimits, capabilities, capabilities, mount_external, se_info,
             se_name, false, fdsToClose, fdsToIgnore, instructionSet, appDataDir);