From 041f016971710bbae871e3162fc6e13cfab77f17 Mon Sep 17 00:00:00 2001 From: Lev Rumyantsev Date: Fri, 13 Dec 2019 15:57:18 -0800 Subject: [PATCH 1/2] AppZygote: start with the correct instruction set This allows triggering native-bridge initialization if needed. Test: CtsExternalServiceTestCases android.externalservice.cts.ExternalServiceTest testBindExternalServiceWithZygote for Q.sdk_gphone_x86_arm.armeabi-v7a Bug: 143143718 Change-Id: If105c4283879407c4fcee33fa6086772d43609a3 --- core/java/android/os/AppZygote.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/java/android/os/AppZygote.java b/core/java/android/os/AppZygote.java index 6daa5b4dc6d8b..92574968e9658 100644 --- a/core/java/android/os/AppZygote.java +++ b/core/java/android/os/AppZygote.java @@ -21,6 +21,8 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; +import dalvik.system.VMRuntime; + /** * AppZygote is responsible for interfacing with an application-specific zygote. * @@ -113,7 +115,7 @@ public class AppZygote { "app_zygote", // seInfo abi, // abi abi, // acceptedAbiList - null, // instructionSet + VMRuntime.getInstructionSet(abi), // instructionSet mZygoteUidGidMin, mZygoteUidGidMax); From 2b7a5ea3bac8cc985bcffb703e623b781cc86b44 Mon Sep 17 00:00:00 2001 From: Lev Rumyantsev Date: Fri, 13 Dec 2019 16:03:30 -0800 Subject: [PATCH 2/2] Zygote: support native-bridge for app-zygote 1. Disable PreInitializeNativeBridge if native bridge is already initialized. This happens in apps forked from app-zygote. 2. Pass nullptr app data directory to PreInitializeNativeBridge if app doesn't have any private storage, which is the case for isolated app-zygote processes. Test: CtsExternalServiceTestCases android.externalservice.cts.ExternalServiceTest testBindExternalServiceWithZygote Test: CtsSeccompHostTestCases android.seccomp.cts.SeccompHostJUnit4DeviceTest testAppZygoteSyscalls both for Q.sdk_gphone_x86_arm.armeabi-v7a Bug: 143143718 Bug: 146904103 Change-Id: I652bb604f30a34826a90b04eb72dde59fb56ae90 --- core/jni/com_android_internal_os_Zygote.cpp | 35 +++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 58fd9c0ab85e8..85752ab25e4be 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -987,22 +987,16 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, DropCapabilitiesBoundingSet(fail_fn); - bool use_native_bridge = !is_system_server && - instruction_set.has_value() && - android::NativeBridgeAvailable() && - android::NeedsNativeBridge(instruction_set.value().c_str()); + bool need_pre_initialize_native_bridge = + !is_system_server && + instruction_set.has_value() && + android::NativeBridgeAvailable() && + // Native bridge may be already initialized if this + // is an app forked from app-zygote. + !android::NativeBridgeInitialized() && + android::NeedsNativeBridge(instruction_set.value().c_str()); - if (use_native_bridge && !app_data_dir.has_value()) { - // The app_data_dir variable should never be empty if we need to use a - // native bridge. In general, app_data_dir will never be empty for normal - // applications. It can only happen in special cases (for isolated - // processes which are not associated with any app). These are launched by - // the framework and should not be emulated anyway. - use_native_bridge = false; - ALOGW("Native bridge will not be used because managed_app_data_dir == nullptr."); - } - - MountEmulatedStorage(uid, mount_external, use_native_bridge, fail_fn); + MountEmulatedStorage(uid, mount_external, need_pre_initialize_native_bridge, fail_fn); // If this zygote isn't root, it won't be able to create a process group, // since the directory is owned by root. @@ -1018,11 +1012,12 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, SetGids(env, gids, fail_fn); SetRLimits(env, rlimits, fail_fn); - if (use_native_bridge) { - // Due to the logic behind use_native_bridge we know that both app_data_dir - // and instruction_set contain values. - android::PreInitializeNativeBridge(app_data_dir.value().c_str(), - instruction_set.value().c_str()); + if (need_pre_initialize_native_bridge) { + // Due to the logic behind need_pre_initialize_native_bridge we know that + // instruction_set contains a value. + android::PreInitializeNativeBridge( + app_data_dir.has_value() ? app_data_dir.value().c_str() : nullptr, + instruction_set.value().c_str()); } if (setresgid(gid, gid, gid) == -1) {