zygote: make all capabilities inheritable.

Set CapInh to the full set of permitted capabilities, so that the crash
handler can raise ambient capabilities to allow crash_dump to ptrace
zygote-descended children without needing CAP_SYS_PTRACE. CapInh is
restricted by filesystem capabilities if the ambient capability set
hasn't been raised, so this should only have an effect when ambient
capabilities are modified.

Bug: http://b/34853272
Test: debuggerd -b `pidof system_server`
Change-Id: I27d2aa4ab4fc47a183ce2b254be178de4d58840c
This commit is contained in:
Josh Gao
2017-02-01 14:56:09 -08:00
parent 0a2d61505a
commit 45dab78e98

View File

@@ -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");
}
}
@@ -508,6 +534,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)
@@ -580,7 +607,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);