Loading core/java/android/os/AppZygote.java +9 −6 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package android.os; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.Zygote; import dalvik.system.VMRuntime; Loading @@ -45,8 +47,6 @@ public class AppZygote { // Last UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMax; private final int mZygoteRuntimeFlags; private final Object mLock = new Object(); /** Loading @@ -57,14 +57,15 @@ public class AppZygote { private ChildZygoteProcess mZygote; private final ApplicationInfo mAppInfo; private final ProcessInfo mProcessInfo; public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax, int runtimeFlags) { public AppZygote(ApplicationInfo appInfo, ProcessInfo processInfo, int zygoteUid, int uidGidMin, int uidGidMax) { mAppInfo = appInfo; mProcessInfo = processInfo; mZygoteUid = zygoteUid; mZygoteUidGidMin = uidGidMin; mZygoteUidGidMax = uidGidMax; mZygoteRuntimeFlags = runtimeFlags; } /** Loading Loading @@ -108,13 +109,15 @@ public class AppZygote { String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi : Build.SUPPORTED_ABIS[0]; try { int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote( mAppInfo, mProcessInfo); mZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.AppZygoteInit", mAppInfo.processName + "_zygote", mZygoteUid, mZygoteUid, null, // gids mZygoteRuntimeFlags, // runtimeFlags runtimeFlags, "app_zygote", // seInfo abi, // abi abi, // acceptedAbiList Loading core/java/android/webkit/WebViewZygote.java +4 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.Zygote; /** @hide */ public class WebViewZygote { Loading Loading @@ -127,13 +128,15 @@ public class WebViewZygote { try { String abi = sPackage.applicationInfo.primaryCpuAbi; int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote( sPackage.applicationInfo, null); sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "webview_zygote", Process.WEBVIEW_ZYGOTE_UID, Process.WEBVIEW_ZYGOTE_UID, null, // gids 0, // runtimeFlags runtimeFlags, "webview_zygote", // seInfo abi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), Loading core/java/com/android/internal/os/Zygote.java +259 −4 Original line number Diff line number Diff line Loading @@ -20,13 +20,21 @@ import static android.system.OsConstants.O_CLOEXEC; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledAfter; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.os.Build; import android.os.FactoryTest; import android.os.IVold; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.Trace; import android.provider.DeviceConfig; Loading @@ -34,6 +42,7 @@ import android.system.ErrnoException; import android.system.Os; import android.util.Log; import com.android.internal.compat.IPlatformCompat; import com.android.internal.net.NetworkUtilsInternal; import dalvik.annotation.optimization.CriticalNative; Loading Loading @@ -125,6 +134,7 @@ public final class Zygote { public static final int MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20); public static final int MEMORY_TAG_LEVEL_NONE = 0; /** * Enable pointer tagging in this process. * Tags are checked during memory deallocation, but not on access. Loading Loading @@ -170,10 +180,8 @@ public final class Zygote { */ public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22; /** * Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23; /** Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23; /** * Enable profiling from system services. This loads profiling related plugins in ART. Loading Loading @@ -1170,4 +1178,251 @@ public final class Zygote { * we failed to determine the level. */ public static native int nativeCurrentTaggingLevel(); /** * Native heap allocations will now have a non-zero tag in the most significant byte. * * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged * Pointers</a> */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id. /** * Native heap allocations in AppZygote process and its descendants will now have a non-zero tag * in the most significant byte. * * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged * Pointers</a> */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S) private static final long NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE = 207557677; /** * Enable asynchronous (ASYNC) memory tag checking in this process. This flag will only have an * effect on hardware supporting the ARM Memory Tagging Extension (MTE). */ @ChangeId @Disabled private static final long NATIVE_MEMTAG_ASYNC = 135772972; // This is a bug id. /** * Enable synchronous (SYNC) memory tag checking in this process. This flag will only have an * effect on hardware supporting the ARM Memory Tagging Extension (MTE). If both * NATIVE_MEMTAG_ASYNC and this option is selected, this option takes preference and MTE is * enabled in SYNC mode. */ @ChangeId @Disabled private static final long NATIVE_MEMTAG_SYNC = 177438394; // This is a bug id. /** Enable automatic zero-initialization of native heap memory allocations. */ @ChangeId @Disabled private static final long NATIVE_HEAP_ZERO_INIT = 178038272; // This is a bug id. /** * Enable sampled memory bug detection in the app. * * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>. */ @ChangeId @Disabled private static final long GWP_ASAN = 135634846; // This is a bug id. private static int memtagModeToZygoteMemtagLevel(int memtagMode) { switch (memtagMode) { case ApplicationInfo.MEMTAG_ASYNC: return MEMORY_TAG_LEVEL_ASYNC; case ApplicationInfo.MEMTAG_SYNC: return MEMORY_TAG_LEVEL_SYNC; default: return MEMORY_TAG_LEVEL_NONE; } } private static boolean isCompatChangeEnabled( long change, @NonNull ApplicationInfo info, @Nullable IPlatformCompat platformCompat, int enabledAfter) { try { if (platformCompat != null) return platformCompat.isChangeEnabled(change, info); } catch (RemoteException ignore) { } return enabledAfter > 0 && info.targetSdkVersion > enabledAfter; } // Returns the requested memory tagging level. private static int getRequestedMemtagLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) { return memtagModeToZygoteMemtagLevel(processInfo.memtagMode); } // Then at the application attribute. if (info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) { return memtagModeToZygoteMemtagLevel(info.getMemtagMode()); } if (isCompatChangeEnabled(NATIVE_MEMTAG_SYNC, info, platformCompat, 0)) { return MEMORY_TAG_LEVEL_SYNC; } if (isCompatChangeEnabled(NATIVE_MEMTAG_ASYNC, info, platformCompat, 0)) { return MEMORY_TAG_LEVEL_ASYNC; } // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute. if (!info.allowsNativeHeapPointerTagging()) { return MEMORY_TAG_LEVEL_NONE; } String defaultLevel = SystemProperties.get("persist.arm64.memtag.app_default"); if ("sync".equals(defaultLevel)) { return MEMORY_TAG_LEVEL_SYNC; } else if ("async".equals(defaultLevel)) { return MEMORY_TAG_LEVEL_ASYNC; } // Check to see that the compat feature for TBI is enabled. if (isCompatChangeEnabled( NATIVE_HEAP_POINTER_TAGGING, info, platformCompat, Build.VERSION_CODES.Q)) { return MEMORY_TAG_LEVEL_TBI; } return MEMORY_TAG_LEVEL_NONE; } private static int decideTaggingLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Get the desired tagging level (app manifest + compat features). int level = getRequestedMemtagLevel(info, processInfo, platformCompat); // Take into account the hardware capabilities. if (nativeSupportsMemoryTagging()) { // MTE devices can not do TBI, because the Zygote process already has live MTE // allocations. Downgrade TBI to NONE. if (level == MEMORY_TAG_LEVEL_TBI) { level = MEMORY_TAG_LEVEL_NONE; } } else if (nativeSupportsTaggedPointers()) { // TBI-but-not-MTE devices downgrade MTE modes to TBI. // The idea is that if an app opts into full hardware tagging (MTE), it must be ok with // the "fake" pointer tagging (TBI). if (level == MEMORY_TAG_LEVEL_ASYNC || level == MEMORY_TAG_LEVEL_SYNC) { level = MEMORY_TAG_LEVEL_TBI; } } else { // Otherwise disable all tagging. level = MEMORY_TAG_LEVEL_NONE; } return level; } private static int decideGwpAsanLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) { return processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } // Then at the application attribute. if (info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) { return info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } // If the app does not specify gwpAsanMode, the default behavior is lottery among the // system apps, and disabled for user apps, unless overwritten by the compat feature. if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) { return GWP_ASAN_LEVEL_ALWAYS; } if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return GWP_ASAN_LEVEL_LOTTERY; } return GWP_ASAN_LEVEL_NEVER; } private static boolean enableNativeHeapZeroInit( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) { return processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED; } // Then at the application attribute. if (info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) { return info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED; } // Compat feature last. if (isCompatChangeEnabled(NATIVE_HEAP_ZERO_INIT, info, platformCompat, 0)) { return true; } return false; } /** * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit) * for a given app. */ public static int getMemorySafetyRuntimeFlags( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable String instructionSet, @Nullable IPlatformCompat platformCompat) { int runtimeFlags = decideGwpAsanLevel(info, processInfo, platformCompat); // If instructionSet is non-null, this indicates that the system_server is spawning a // process with an ISA that may be different from its own. System (kernel and hardware) // compatibility for these features is checked in the decideTaggingLevel in the // system_server process (not the child process). As both MTE and TBI are only supported // in aarch64, we can simply ensure that the new process is also aarch64. This prevents // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should // enable some tagging variant. Theoretically, a 32-bit system server could exist that // spawns 64-bit processes, in which case the new process won't get any tagging. This is // fine as we haven't seen this configuration in practice, and we can reasonable assume // that if tagging is desired, the system server will be 64-bit. if (instructionSet == null || instructionSet.equals("arm64")) { runtimeFlags |= decideTaggingLevel(info, processInfo, platformCompat); } if (enableNativeHeapZeroInit(info, processInfo, platformCompat)) { runtimeFlags |= NATIVE_HEAP_ZERO_INIT_ENABLED; } return runtimeFlags; } /** * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit) * for a secondary zygote (AppZygote or WebViewZygote). */ public static int getMemorySafetyRuntimeFlagsForSecondaryZygote( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo) { final IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); int runtimeFlags = getMemorySafetyRuntimeFlags( info, processInfo, null /*instructionSet*/, platformCompat); // TBI ("fake" pointer tagging) in AppZygote is controlled by a separate compat feature. if ((runtimeFlags & MEMORY_TAG_LEVEL_MASK) == MEMORY_TAG_LEVEL_TBI && isCompatChangeEnabled( NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE, info, platformCompat, Build.VERSION_CODES.S)) { // Reset memory tag level to NONE. runtimeFlags &= ~MEMORY_TAG_LEVEL_MASK; runtimeFlags |= MEMORY_TAG_LEVEL_NONE; } return runtimeFlags; } } core/jni/com_android_internal_os_Zygote.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -346,7 +346,7 @@ enum RuntimeFlags : uint32_t { GWP_ASAN_LEVEL_NEVER = 0 << 21, GWP_ASAN_LEVEL_LOTTERY = 1 << 21, GWP_ASAN_LEVEL_ALWAYS = 2 << 21, NATIVE_HEAP_ZERO_INIT = 1 << 23, NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23, PROFILEABLE = 1 << 24, }; Loading Loading @@ -1709,13 +1709,13 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, // would be nice to have them for apps, we will have to wait until they are // proven out, have more efficient hardware, and/or apply them only to new // applications. if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) { if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) { mallopt(M_BIONIC_ZERO_INIT, 0); } // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART // runtime. runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT; runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED; bool forceEnableGwpAsan = false; switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { Loading services/core/java/com/android/server/am/ActiveServices.java +5 −3 Original line number Diff line number Diff line Loading @@ -4139,7 +4139,8 @@ public final class ActiveServices { final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; HostingRecord hostingRecord = new HostingRecord("service", r.instanceName); HostingRecord hostingRecord = new HostingRecord("service", r.instanceName, r.definingPackageName, r.definingUid, r.serviceInfo.processName); ProcessRecord app; if (!isolated) { Loading Loading @@ -4177,11 +4178,12 @@ public final class ActiveServices { app = r.isolationHostProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingRecord = HostingRecord.byWebviewZygote(r.instanceName); hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName, r.definingUid, r.serviceInfo.processName); } if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) { hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName, r.definingUid); r.definingUid, r.serviceInfo.processName); } } Loading Loading
core/java/android/os/AppZygote.java +9 −6 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package android.os; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.Zygote; import dalvik.system.VMRuntime; Loading @@ -45,8 +47,6 @@ public class AppZygote { // Last UID/GID of the range the AppZygote can setuid()/setgid() to private final int mZygoteUidGidMax; private final int mZygoteRuntimeFlags; private final Object mLock = new Object(); /** Loading @@ -57,14 +57,15 @@ public class AppZygote { private ChildZygoteProcess mZygote; private final ApplicationInfo mAppInfo; private final ProcessInfo mProcessInfo; public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax, int runtimeFlags) { public AppZygote(ApplicationInfo appInfo, ProcessInfo processInfo, int zygoteUid, int uidGidMin, int uidGidMax) { mAppInfo = appInfo; mProcessInfo = processInfo; mZygoteUid = zygoteUid; mZygoteUidGidMin = uidGidMin; mZygoteUidGidMax = uidGidMax; mZygoteRuntimeFlags = runtimeFlags; } /** Loading Loading @@ -108,13 +109,15 @@ public class AppZygote { String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi : Build.SUPPORTED_ABIS[0]; try { int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote( mAppInfo, mProcessInfo); mZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.AppZygoteInit", mAppInfo.processName + "_zygote", mZygoteUid, mZygoteUid, null, // gids mZygoteRuntimeFlags, // runtimeFlags runtimeFlags, "app_zygote", // seInfo abi, // abi abi, // acceptedAbiList Loading
core/java/android/webkit/WebViewZygote.java +4 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.Zygote; /** @hide */ public class WebViewZygote { Loading Loading @@ -127,13 +128,15 @@ public class WebViewZygote { try { String abi = sPackage.applicationInfo.primaryCpuAbi; int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote( sPackage.applicationInfo, null); sZygote = Process.ZYGOTE_PROCESS.startChildZygote( "com.android.internal.os.WebViewZygoteInit", "webview_zygote", Process.WEBVIEW_ZYGOTE_UID, Process.WEBVIEW_ZYGOTE_UID, null, // gids 0, // runtimeFlags runtimeFlags, "webview_zygote", // seInfo abi, // abi TextUtils.join(",", Build.SUPPORTED_ABIS), Loading
core/java/com/android/internal/os/Zygote.java +259 −4 Original line number Diff line number Diff line Loading @@ -20,13 +20,21 @@ import static android.system.OsConstants.O_CLOEXEC; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledAfter; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.net.Credentials; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.os.Build; import android.os.FactoryTest; import android.os.IVold; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.Trace; import android.provider.DeviceConfig; Loading @@ -34,6 +42,7 @@ import android.system.ErrnoException; import android.system.Os; import android.util.Log; import com.android.internal.compat.IPlatformCompat; import com.android.internal.net.NetworkUtilsInternal; import dalvik.annotation.optimization.CriticalNative; Loading Loading @@ -125,6 +134,7 @@ public final class Zygote { public static final int MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20); public static final int MEMORY_TAG_LEVEL_NONE = 0; /** * Enable pointer tagging in this process. * Tags are checked during memory deallocation, but not on access. Loading Loading @@ -170,10 +180,8 @@ public final class Zygote { */ public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22; /** * Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23; /** Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23; /** * Enable profiling from system services. This loads profiling related plugins in ART. Loading Loading @@ -1170,4 +1178,251 @@ public final class Zygote { * we failed to determine the level. */ public static native int nativeCurrentTaggingLevel(); /** * Native heap allocations will now have a non-zero tag in the most significant byte. * * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged * Pointers</a> */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id. /** * Native heap allocations in AppZygote process and its descendants will now have a non-zero tag * in the most significant byte. * * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged * Pointers</a> */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S) private static final long NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE = 207557677; /** * Enable asynchronous (ASYNC) memory tag checking in this process. This flag will only have an * effect on hardware supporting the ARM Memory Tagging Extension (MTE). */ @ChangeId @Disabled private static final long NATIVE_MEMTAG_ASYNC = 135772972; // This is a bug id. /** * Enable synchronous (SYNC) memory tag checking in this process. This flag will only have an * effect on hardware supporting the ARM Memory Tagging Extension (MTE). If both * NATIVE_MEMTAG_ASYNC and this option is selected, this option takes preference and MTE is * enabled in SYNC mode. */ @ChangeId @Disabled private static final long NATIVE_MEMTAG_SYNC = 177438394; // This is a bug id. /** Enable automatic zero-initialization of native heap memory allocations. */ @ChangeId @Disabled private static final long NATIVE_HEAP_ZERO_INIT = 178038272; // This is a bug id. /** * Enable sampled memory bug detection in the app. * * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>. */ @ChangeId @Disabled private static final long GWP_ASAN = 135634846; // This is a bug id. private static int memtagModeToZygoteMemtagLevel(int memtagMode) { switch (memtagMode) { case ApplicationInfo.MEMTAG_ASYNC: return MEMORY_TAG_LEVEL_ASYNC; case ApplicationInfo.MEMTAG_SYNC: return MEMORY_TAG_LEVEL_SYNC; default: return MEMORY_TAG_LEVEL_NONE; } } private static boolean isCompatChangeEnabled( long change, @NonNull ApplicationInfo info, @Nullable IPlatformCompat platformCompat, int enabledAfter) { try { if (platformCompat != null) return platformCompat.isChangeEnabled(change, info); } catch (RemoteException ignore) { } return enabledAfter > 0 && info.targetSdkVersion > enabledAfter; } // Returns the requested memory tagging level. private static int getRequestedMemtagLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) { return memtagModeToZygoteMemtagLevel(processInfo.memtagMode); } // Then at the application attribute. if (info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) { return memtagModeToZygoteMemtagLevel(info.getMemtagMode()); } if (isCompatChangeEnabled(NATIVE_MEMTAG_SYNC, info, platformCompat, 0)) { return MEMORY_TAG_LEVEL_SYNC; } if (isCompatChangeEnabled(NATIVE_MEMTAG_ASYNC, info, platformCompat, 0)) { return MEMORY_TAG_LEVEL_ASYNC; } // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute. if (!info.allowsNativeHeapPointerTagging()) { return MEMORY_TAG_LEVEL_NONE; } String defaultLevel = SystemProperties.get("persist.arm64.memtag.app_default"); if ("sync".equals(defaultLevel)) { return MEMORY_TAG_LEVEL_SYNC; } else if ("async".equals(defaultLevel)) { return MEMORY_TAG_LEVEL_ASYNC; } // Check to see that the compat feature for TBI is enabled. if (isCompatChangeEnabled( NATIVE_HEAP_POINTER_TAGGING, info, platformCompat, Build.VERSION_CODES.Q)) { return MEMORY_TAG_LEVEL_TBI; } return MEMORY_TAG_LEVEL_NONE; } private static int decideTaggingLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Get the desired tagging level (app manifest + compat features). int level = getRequestedMemtagLevel(info, processInfo, platformCompat); // Take into account the hardware capabilities. if (nativeSupportsMemoryTagging()) { // MTE devices can not do TBI, because the Zygote process already has live MTE // allocations. Downgrade TBI to NONE. if (level == MEMORY_TAG_LEVEL_TBI) { level = MEMORY_TAG_LEVEL_NONE; } } else if (nativeSupportsTaggedPointers()) { // TBI-but-not-MTE devices downgrade MTE modes to TBI. // The idea is that if an app opts into full hardware tagging (MTE), it must be ok with // the "fake" pointer tagging (TBI). if (level == MEMORY_TAG_LEVEL_ASYNC || level == MEMORY_TAG_LEVEL_SYNC) { level = MEMORY_TAG_LEVEL_TBI; } } else { // Otherwise disable all tagging. level = MEMORY_TAG_LEVEL_NONE; } return level; } private static int decideGwpAsanLevel( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) { return processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } // Then at the application attribute. if (info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) { return info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } // If the app does not specify gwpAsanMode, the default behavior is lottery among the // system apps, and disabled for user apps, unless overwritten by the compat feature. if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) { return GWP_ASAN_LEVEL_ALWAYS; } if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return GWP_ASAN_LEVEL_LOTTERY; } return GWP_ASAN_LEVEL_NEVER; } private static boolean enableNativeHeapZeroInit( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable IPlatformCompat platformCompat) { // Look at the process attribute first. if (processInfo != null && processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) { return processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED; } // Then at the application attribute. if (info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) { return info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED; } // Compat feature last. if (isCompatChangeEnabled(NATIVE_HEAP_ZERO_INIT, info, platformCompat, 0)) { return true; } return false; } /** * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit) * for a given app. */ public static int getMemorySafetyRuntimeFlags( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo, @Nullable String instructionSet, @Nullable IPlatformCompat platformCompat) { int runtimeFlags = decideGwpAsanLevel(info, processInfo, platformCompat); // If instructionSet is non-null, this indicates that the system_server is spawning a // process with an ISA that may be different from its own. System (kernel and hardware) // compatibility for these features is checked in the decideTaggingLevel in the // system_server process (not the child process). As both MTE and TBI are only supported // in aarch64, we can simply ensure that the new process is also aarch64. This prevents // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should // enable some tagging variant. Theoretically, a 32-bit system server could exist that // spawns 64-bit processes, in which case the new process won't get any tagging. This is // fine as we haven't seen this configuration in practice, and we can reasonable assume // that if tagging is desired, the system server will be 64-bit. if (instructionSet == null || instructionSet.equals("arm64")) { runtimeFlags |= decideTaggingLevel(info, processInfo, platformCompat); } if (enableNativeHeapZeroInit(info, processInfo, platformCompat)) { runtimeFlags |= NATIVE_HEAP_ZERO_INIT_ENABLED; } return runtimeFlags; } /** * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit) * for a secondary zygote (AppZygote or WebViewZygote). */ public static int getMemorySafetyRuntimeFlagsForSecondaryZygote( @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo) { final IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); int runtimeFlags = getMemorySafetyRuntimeFlags( info, processInfo, null /*instructionSet*/, platformCompat); // TBI ("fake" pointer tagging) in AppZygote is controlled by a separate compat feature. if ((runtimeFlags & MEMORY_TAG_LEVEL_MASK) == MEMORY_TAG_LEVEL_TBI && isCompatChangeEnabled( NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE, info, platformCompat, Build.VERSION_CODES.S)) { // Reset memory tag level to NONE. runtimeFlags &= ~MEMORY_TAG_LEVEL_MASK; runtimeFlags |= MEMORY_TAG_LEVEL_NONE; } return runtimeFlags; } }
core/jni/com_android_internal_os_Zygote.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -346,7 +346,7 @@ enum RuntimeFlags : uint32_t { GWP_ASAN_LEVEL_NEVER = 0 << 21, GWP_ASAN_LEVEL_LOTTERY = 1 << 21, GWP_ASAN_LEVEL_ALWAYS = 2 << 21, NATIVE_HEAP_ZERO_INIT = 1 << 23, NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23, PROFILEABLE = 1 << 24, }; Loading Loading @@ -1709,13 +1709,13 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, // would be nice to have them for apps, we will have to wait until they are // proven out, have more efficient hardware, and/or apply them only to new // applications. if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) { if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) { mallopt(M_BIONIC_ZERO_INIT, 0); } // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART // runtime. runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT; runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED; bool forceEnableGwpAsan = false; switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { Loading
services/core/java/com/android/server/am/ActiveServices.java +5 −3 Original line number Diff line number Diff line Loading @@ -4139,7 +4139,8 @@ public final class ActiveServices { final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; final String procName = r.processName; HostingRecord hostingRecord = new HostingRecord("service", r.instanceName); HostingRecord hostingRecord = new HostingRecord("service", r.instanceName, r.definingPackageName, r.definingUid, r.serviceInfo.processName); ProcessRecord app; if (!isolated) { Loading Loading @@ -4177,11 +4178,12 @@ public final class ActiveServices { app = r.isolationHostProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingRecord = HostingRecord.byWebviewZygote(r.instanceName); hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName, r.definingUid, r.serviceInfo.processName); } if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) { hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName, r.definingUid); r.definingUid, r.serviceInfo.processName); } } Loading