diff options
| -rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 19 | ||||
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 20 |
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); |