diff options
| -rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 070a2d96cd40..e2fc44460dcd 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -253,13 +253,36 @@ static void DropCapabilitiesBoundingSet(JNIEnv* env) { ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify " "your kernel is compiled with file capabilities support"); } else { + ALOGE("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno)); RuntimeAbort(env, __LINE__, "prctl(PR_CAPBSET_DROP) failed"); } } } } -static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) { +static void SetInheritable(JNIEnv* env, uint64_t inheritable) { + __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"); + } + + capdata[0].inheritable = inheritable; + capdata[1].inheritable = inheritable >> 32; + + if (capset(&capheader, &capdata[0]) == -1) { + ALOGE("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno)); + RuntimeAbort(env, __LINE__, "capset failed"); + } +} + +static void SetCapabilities(JNIEnv* env, uint64_t permitted, uint64_t effective, + uint64_t inheritable) { __user_cap_header_struct capheader; memset(&capheader, 0, sizeof(capheader)); capheader.version = _LINUX_CAPABILITY_VERSION_3; @@ -271,9 +294,12 @@ static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) { capdata[1].effective = effective >> 32; capdata[0].permitted = permitted; capdata[1].permitted = permitted >> 32; + capdata[0].inheritable = inheritable; + capdata[1].inheritable = inheritable >> 32; if (capset(&capheader, &capdata[0]) == -1) { - ALOGE("capset(%" PRId64 ", %" PRId64 ") failed", permitted, effective); + ALOGE("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") failed: %s", permitted, + effective, inheritable, strerror(errno)); RuntimeAbort(env, __LINE__, "capset failed"); } } @@ -527,6 +553,7 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra EnableKeepCapabilities(env); } + SetInheritable(env, permittedCapabilities); DropCapabilitiesBoundingSet(env); bool use_native_bridge = !is_system_server && (instructionSet != NULL) @@ -599,7 +626,7 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra } } - SetCapabilities(env, permittedCapabilities, effectiveCapabilities); + SetCapabilities(env, permittedCapabilities, effectiveCapabilities, permittedCapabilities); SetSchedulerPolicy(env); |