summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java19
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp20
2 files changed, 34 insertions, 5 deletions
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index b7dff963abe8..7d61349ed4c1 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,6 +41,8 @@ import android.security.keystore.AndroidKeyStoreProvider;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.text.Hyphenator;
import android.util.EventLog;
import android.util.Log;
@@ -80,7 +82,6 @@ public class ZygoteInit {
private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
- private static final String PROPERTY_RUNNING_IN_CONTAINER = "ro.boot.container";
private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
@@ -567,12 +568,20 @@ public class ZygoteInit {
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
- OsConstants.CAP_WAKE_ALARM
+ OsConstants.CAP_WAKE_ALARM,
+ OsConstants.CAP_BLOCK_SUSPEND
);
- /* Containers run without this capability, so avoid setting it in that case */
- if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
- capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
+ /* Containers run without some capabilities, so drop any caps that are not available. */
+ StructCapUserHeader header = new StructCapUserHeader(
+ OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
+ StructCapUserData[] data;
+ try {
+ data = Os.capget(header);
+ } catch (ErrnoException ex) {
+ throw new RuntimeException("Failed to capget()", ex);
}
+ capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
+
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index cb53106dbf28..d43849087a99 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -678,6 +678,22 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
}
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 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
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);