Merge "Fix memory flags in external services and secondary zygotes." into tm-dev am: 951aa29f72
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16989014 Change-Id: Ifdab9053602186f63979ec62b053368f55b42a71
This commit is contained in:
@@ -17,9 +17,11 @@
|
|||||||
package android.os;
|
package android.os;
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.ProcessInfo;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.internal.os.Zygote;
|
||||||
|
|
||||||
import dalvik.system.VMRuntime;
|
import dalvik.system.VMRuntime;
|
||||||
|
|
||||||
@@ -45,8 +47,6 @@ public class AppZygote {
|
|||||||
// Last UID/GID of the range the AppZygote can setuid()/setgid() to
|
// Last UID/GID of the range the AppZygote can setuid()/setgid() to
|
||||||
private final int mZygoteUidGidMax;
|
private final int mZygoteUidGidMax;
|
||||||
|
|
||||||
private final int mZygoteRuntimeFlags;
|
|
||||||
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,14 +57,15 @@ public class AppZygote {
|
|||||||
private ChildZygoteProcess mZygote;
|
private ChildZygoteProcess mZygote;
|
||||||
|
|
||||||
private final ApplicationInfo mAppInfo;
|
private final ApplicationInfo mAppInfo;
|
||||||
|
private final ProcessInfo mProcessInfo;
|
||||||
|
|
||||||
public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax,
|
public AppZygote(ApplicationInfo appInfo, ProcessInfo processInfo, int zygoteUid, int uidGidMin,
|
||||||
int runtimeFlags) {
|
int uidGidMax) {
|
||||||
mAppInfo = appInfo;
|
mAppInfo = appInfo;
|
||||||
|
mProcessInfo = processInfo;
|
||||||
mZygoteUid = zygoteUid;
|
mZygoteUid = zygoteUid;
|
||||||
mZygoteUidGidMin = uidGidMin;
|
mZygoteUidGidMin = uidGidMin;
|
||||||
mZygoteUidGidMax = uidGidMax;
|
mZygoteUidGidMax = uidGidMax;
|
||||||
mZygoteRuntimeFlags = runtimeFlags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,13 +109,15 @@ public class AppZygote {
|
|||||||
String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi :
|
String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi :
|
||||||
Build.SUPPORTED_ABIS[0];
|
Build.SUPPORTED_ABIS[0];
|
||||||
try {
|
try {
|
||||||
|
int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote(
|
||||||
|
mAppInfo, mProcessInfo);
|
||||||
mZygote = Process.ZYGOTE_PROCESS.startChildZygote(
|
mZygote = Process.ZYGOTE_PROCESS.startChildZygote(
|
||||||
"com.android.internal.os.AppZygoteInit",
|
"com.android.internal.os.AppZygoteInit",
|
||||||
mAppInfo.processName + "_zygote",
|
mAppInfo.processName + "_zygote",
|
||||||
mZygoteUid,
|
mZygoteUid,
|
||||||
mZygoteUid,
|
mZygoteUid,
|
||||||
null, // gids
|
null, // gids
|
||||||
mZygoteRuntimeFlags, // runtimeFlags
|
runtimeFlags,
|
||||||
"app_zygote", // seInfo
|
"app_zygote", // seInfo
|
||||||
abi, // abi
|
abi, // abi
|
||||||
abi, // acceptedAbiList
|
abi, // acceptedAbiList
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.internal.os.Zygote;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public class WebViewZygote {
|
public class WebViewZygote {
|
||||||
@@ -127,13 +128,15 @@ public class WebViewZygote {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String abi = sPackage.applicationInfo.primaryCpuAbi;
|
String abi = sPackage.applicationInfo.primaryCpuAbi;
|
||||||
|
int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote(
|
||||||
|
sPackage.applicationInfo, null);
|
||||||
sZygote = Process.ZYGOTE_PROCESS.startChildZygote(
|
sZygote = Process.ZYGOTE_PROCESS.startChildZygote(
|
||||||
"com.android.internal.os.WebViewZygoteInit",
|
"com.android.internal.os.WebViewZygoteInit",
|
||||||
"webview_zygote",
|
"webview_zygote",
|
||||||
Process.WEBVIEW_ZYGOTE_UID,
|
Process.WEBVIEW_ZYGOTE_UID,
|
||||||
Process.WEBVIEW_ZYGOTE_UID,
|
Process.WEBVIEW_ZYGOTE_UID,
|
||||||
null, // gids
|
null, // gids
|
||||||
0, // runtimeFlags
|
runtimeFlags,
|
||||||
"webview_zygote", // seInfo
|
"webview_zygote", // seInfo
|
||||||
abi, // abi
|
abi, // abi
|
||||||
TextUtils.join(",", Build.SUPPORTED_ABIS),
|
TextUtils.join(",", Build.SUPPORTED_ABIS),
|
||||||
|
|||||||
@@ -20,13 +20,21 @@ import static android.system.OsConstants.O_CLOEXEC;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
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.ApplicationInfo;
|
||||||
|
import android.content.pm.ProcessInfo;
|
||||||
import android.net.Credentials;
|
import android.net.Credentials;
|
||||||
import android.net.LocalServerSocket;
|
import android.net.LocalServerSocket;
|
||||||
import android.net.LocalSocket;
|
import android.net.LocalSocket;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.FactoryTest;
|
import android.os.FactoryTest;
|
||||||
import android.os.IVold;
|
import android.os.IVold;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.ServiceManager;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
@@ -34,6 +42,7 @@ import android.system.ErrnoException;
|
|||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.compat.IPlatformCompat;
|
||||||
import com.android.internal.net.NetworkUtilsInternal;
|
import com.android.internal.net.NetworkUtilsInternal;
|
||||||
|
|
||||||
import dalvik.annotation.optimization.CriticalNative;
|
import dalvik.annotation.optimization.CriticalNative;
|
||||||
@@ -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_MASK = (1 << 19) | (1 << 20);
|
||||||
|
|
||||||
public static final int MEMORY_TAG_LEVEL_NONE = 0;
|
public static final int MEMORY_TAG_LEVEL_NONE = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable pointer tagging in this process.
|
* Enable pointer tagging in this process.
|
||||||
* Tags are checked during memory deallocation, but not on access.
|
* Tags are checked during memory deallocation, but not on access.
|
||||||
@@ -170,10 +180,8 @@ public final class Zygote {
|
|||||||
*/
|
*/
|
||||||
public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22;
|
public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22;
|
||||||
|
|
||||||
/**
|
/** Enable automatic zero-initialization of native heap memory allocations. */
|
||||||
* Enable automatic zero-initialization of native heap memory allocations.
|
public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23;
|
||||||
*/
|
|
||||||
public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable profiling from system services. This loads profiling related plugins in ART.
|
* Enable profiling from system services. This loads profiling related plugins in ART.
|
||||||
@@ -1170,4 +1178,251 @@ public final class Zygote {
|
|||||||
* we failed to determine the level.
|
* we failed to determine the level.
|
||||||
*/
|
*/
|
||||||
public static native int nativeCurrentTaggingLevel();
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ enum RuntimeFlags : uint32_t {
|
|||||||
GWP_ASAN_LEVEL_NEVER = 0 << 21,
|
GWP_ASAN_LEVEL_NEVER = 0 << 21,
|
||||||
GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
|
GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
|
||||||
GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
|
GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
|
||||||
NATIVE_HEAP_ZERO_INIT = 1 << 23,
|
NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23,
|
||||||
PROFILEABLE = 1 << 24,
|
PROFILEABLE = 1 << 24,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -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
|
// 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
|
// proven out, have more efficient hardware, and/or apply them only to new
|
||||||
// applications.
|
// applications.
|
||||||
if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) {
|
if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) {
|
||||||
mallopt(M_BIONIC_ZERO_INIT, 0);
|
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
|
// Now that we've used the flag, clear it so that we don't pass unknown flags to the ART
|
||||||
// runtime.
|
// runtime.
|
||||||
runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT;
|
runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED;
|
||||||
|
|
||||||
bool forceEnableGwpAsan = false;
|
bool forceEnableGwpAsan = false;
|
||||||
switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
|
switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
|
||||||
|
|||||||
@@ -4139,7 +4139,8 @@ public final class ActiveServices {
|
|||||||
|
|
||||||
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
|
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
|
||||||
final String procName = r.processName;
|
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;
|
ProcessRecord app;
|
||||||
|
|
||||||
if (!isolated) {
|
if (!isolated) {
|
||||||
@@ -4177,11 +4178,12 @@ public final class ActiveServices {
|
|||||||
app = r.isolationHostProc;
|
app = r.isolationHostProc;
|
||||||
if (WebViewZygote.isMultiprocessEnabled()
|
if (WebViewZygote.isMultiprocessEnabled()
|
||||||
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
|
&& 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) {
|
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
|
||||||
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
|
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
|
||||||
r.definingUid);
|
r.definingUid, r.serviceInfo.processName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,19 +56,27 @@ public final class HostingRecord {
|
|||||||
private final String mDefiningPackageName;
|
private final String mDefiningPackageName;
|
||||||
private final int mDefiningUid;
|
private final int mDefiningUid;
|
||||||
private final boolean mIsTopApp;
|
private final boolean mIsTopApp;
|
||||||
|
private final String mDefiningProcessName;
|
||||||
|
|
||||||
public HostingRecord(String hostingType) {
|
public HostingRecord(String hostingType) {
|
||||||
this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
|
this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
|
||||||
-1 /* mDefiningUid */, false /* isTopApp */);
|
-1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostingRecord(String hostingType, ComponentName hostingName) {
|
public HostingRecord(String hostingType, ComponentName hostingName) {
|
||||||
this(hostingType, hostingName, REGULAR_ZYGOTE);
|
this(hostingType, hostingName, REGULAR_ZYGOTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HostingRecord(String hostingType, ComponentName hostingName, String definingPackageName,
|
||||||
|
int definingUid, String definingProcessName) {
|
||||||
|
this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
|
||||||
|
definingUid, false /* isTopApp */, definingProcessName);
|
||||||
|
}
|
||||||
|
|
||||||
public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
|
public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
|
||||||
this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
|
this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
|
||||||
null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */);
|
null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */,
|
||||||
|
null /* definingProcessName */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostingRecord(String hostingType, String hostingName) {
|
public HostingRecord(String hostingType, String hostingName) {
|
||||||
@@ -81,17 +89,19 @@ public final class HostingRecord {
|
|||||||
|
|
||||||
private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
|
private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
|
||||||
this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
|
this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
|
||||||
-1 /* mDefiningUid */, false /* isTopApp */);
|
-1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HostingRecord(String hostingType, String hostingName, int hostingZygote,
|
private HostingRecord(String hostingType, String hostingName, int hostingZygote,
|
||||||
String definingPackageName, int definingUid, boolean isTopApp) {
|
String definingPackageName, int definingUid, boolean isTopApp,
|
||||||
|
String definingProcessName) {
|
||||||
mHostingType = hostingType;
|
mHostingType = hostingType;
|
||||||
mHostingName = hostingName;
|
mHostingName = hostingName;
|
||||||
mHostingZygote = hostingZygote;
|
mHostingZygote = hostingZygote;
|
||||||
mDefiningPackageName = definingPackageName;
|
mDefiningPackageName = definingPackageName;
|
||||||
mDefiningUid = definingUid;
|
mDefiningUid = definingUid;
|
||||||
mIsTopApp = isTopApp;
|
mIsTopApp = isTopApp;
|
||||||
|
mDefiningProcessName = definingProcessName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
@@ -126,13 +136,25 @@ public final class HostingRecord {
|
|||||||
return mDefiningPackageName;
|
return mDefiningPackageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the processName of the component we want to start as specified in the defining app's
|
||||||
|
* manifest.
|
||||||
|
*
|
||||||
|
* @return the processName of the process in the hosting application
|
||||||
|
*/
|
||||||
|
public String getDefiningProcessName() {
|
||||||
|
return mDefiningProcessName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a HostingRecord for a process that must spawn from the webview zygote
|
* Creates a HostingRecord for a process that must spawn from the webview zygote
|
||||||
* @param hostingName name of the component to be hosted in this process
|
* @param hostingName name of the component to be hosted in this process
|
||||||
* @return The constructed HostingRecord
|
* @return The constructed HostingRecord
|
||||||
*/
|
*/
|
||||||
public static HostingRecord byWebviewZygote(ComponentName hostingName) {
|
public static HostingRecord byWebviewZygote(ComponentName hostingName,
|
||||||
return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
|
String definingPackageName, int definingUid, String definingProcessName) {
|
||||||
|
return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE,
|
||||||
|
definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,9 +165,9 @@ public final class HostingRecord {
|
|||||||
* @return The constructed HostingRecord
|
* @return The constructed HostingRecord
|
||||||
*/
|
*/
|
||||||
public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
|
public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
|
||||||
int definingUid) {
|
int definingUid, String definingProcessName) {
|
||||||
return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
|
return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
|
||||||
definingPackageName, definingUid, false /* isTopApp */);
|
definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ import android.app.IApplicationThread;
|
|||||||
import android.app.IProcessObserver;
|
import android.app.IProcessObserver;
|
||||||
import android.app.IUidObserver;
|
import android.app.IUidObserver;
|
||||||
import android.compat.annotation.ChangeId;
|
import android.compat.annotation.ChangeId;
|
||||||
import android.compat.annotation.Disabled;
|
|
||||||
import android.compat.annotation.EnabledAfter;
|
import android.compat.annotation.EnabledAfter;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -362,59 +361,6 @@ public final class ProcessList {
|
|||||||
// lmkd reconnect delay in msecs
|
// lmkd reconnect delay in msecs
|
||||||
private static final long LMKD_RECONNECT_DELAY_MS = 1000;
|
private static final long LMKD_RECONNECT_DELAY_MS = 1000;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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_APP_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.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apps have no access to the private data directories of any other app, even if the other
|
* Apps have no access to the private data directories of any other app, even if the other
|
||||||
* app has made them world-readable.
|
* app has made them world-readable.
|
||||||
@@ -1681,136 +1627,6 @@ public final class ProcessList {
|
|||||||
return gidArray;
|
return gidArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int memtagModeToZygoteMemtagLevel(int memtagMode) {
|
|
||||||
switch (memtagMode) {
|
|
||||||
case ApplicationInfo.MEMTAG_ASYNC:
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_ASYNC;
|
|
||||||
case ApplicationInfo.MEMTAG_SYNC:
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_SYNC;
|
|
||||||
default:
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the requested memory tagging level.
|
|
||||||
private int getRequestedMemtagLevel(ProcessRecord app) {
|
|
||||||
// Look at the process attribute first.
|
|
||||||
if (app.processInfo != null
|
|
||||||
&& app.processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
|
|
||||||
return memtagModeToZygoteMemtagLevel(app.processInfo.memtagMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then at the application attribute.
|
|
||||||
if (app.info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) {
|
|
||||||
return memtagModeToZygoteMemtagLevel(app.info.getMemtagMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPlatformCompat.isChangeEnabled(NATIVE_MEMTAG_SYNC, app.info)) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_SYNC;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPlatformCompat.isChangeEnabled(NATIVE_MEMTAG_ASYNC, app.info)) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_ASYNC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
|
|
||||||
if (!app.info.allowsNativeHeapPointerTagging()) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
String defaultLevel = SystemProperties.get("persist.arm64.memtag.app_default");
|
|
||||||
if ("sync".equals(defaultLevel)) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_SYNC;
|
|
||||||
} else if ("async".equals(defaultLevel)) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_ASYNC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to see that the compat feature for TBI is enabled.
|
|
||||||
if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_TBI;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decideTaggingLevel(ProcessRecord app) {
|
|
||||||
// Get the desired tagging level (app manifest + compat features).
|
|
||||||
int level = getRequestedMemtagLevel(app);
|
|
||||||
|
|
||||||
// Take into account the hardware capabilities.
|
|
||||||
if (Zygote.nativeSupportsMemoryTagging()) {
|
|
||||||
// MTE devices can not do TBI, because the Zygote process already has live MTE
|
|
||||||
// allocations. Downgrade TBI to NONE.
|
|
||||||
if (level == Zygote.MEMORY_TAG_LEVEL_TBI) {
|
|
||||||
level = Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
} else if (Zygote.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 == Zygote.MEMORY_TAG_LEVEL_ASYNC || level == Zygote.MEMORY_TAG_LEVEL_SYNC) {
|
|
||||||
level = Zygote.MEMORY_TAG_LEVEL_TBI;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Otherwise disable all tagging.
|
|
||||||
level = Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decideTaggingLevelForAppZygote(ProcessRecord app) {
|
|
||||||
int level = decideTaggingLevel(app);
|
|
||||||
// TBI ("fake" pointer tagging) in AppZygote is controlled by a separate compat feature.
|
|
||||||
if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING_APP_ZYGOTE, app.info)
|
|
||||||
&& level == Zygote.MEMORY_TAG_LEVEL_TBI) {
|
|
||||||
level = Zygote.MEMORY_TAG_LEVEL_NONE;
|
|
||||||
}
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int decideGwpAsanLevel(ProcessRecord app) {
|
|
||||||
// Look at the process attribute first.
|
|
||||||
if (app.processInfo != null
|
|
||||||
&& app.processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
|
|
||||||
return app.processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS
|
|
||||||
? Zygote.GWP_ASAN_LEVEL_ALWAYS
|
|
||||||
: Zygote.GWP_ASAN_LEVEL_NEVER;
|
|
||||||
}
|
|
||||||
// Then at the application attribute.
|
|
||||||
if (app.info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) {
|
|
||||||
return app.info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS
|
|
||||||
? Zygote.GWP_ASAN_LEVEL_ALWAYS
|
|
||||||
: Zygote.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 (mPlatformCompat.isChangeEnabled(GWP_ASAN, app.info)) {
|
|
||||||
return Zygote.GWP_ASAN_LEVEL_ALWAYS;
|
|
||||||
}
|
|
||||||
if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
|
||||||
return Zygote.GWP_ASAN_LEVEL_LOTTERY;
|
|
||||||
}
|
|
||||||
return Zygote.GWP_ASAN_LEVEL_NEVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean enableNativeHeapZeroInit(ProcessRecord app) {
|
|
||||||
// Look at the process attribute first.
|
|
||||||
if (app.processInfo != null
|
|
||||||
&& app.processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) {
|
|
||||||
return app.processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED;
|
|
||||||
}
|
|
||||||
// Then at the application attribute.
|
|
||||||
if (app.info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) {
|
|
||||||
return app.info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED;
|
|
||||||
}
|
|
||||||
// Compat feature last.
|
|
||||||
if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_ZERO_INIT, app.info)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@code true} if process start is successful, false otherwise.
|
* @return {@code true} if process start is successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
@@ -1992,8 +1808,6 @@ public final class ProcessList {
|
|||||||
runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
|
runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeFlags |= decideGwpAsanLevel(app);
|
|
||||||
|
|
||||||
String invokeWith = null;
|
String invokeWith = null;
|
||||||
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
|
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
|
||||||
// Debuggable apps may include a wrapper script with their library directory.
|
// Debuggable apps may include a wrapper script with their library directory.
|
||||||
@@ -2024,23 +1838,21 @@ public final class ProcessList {
|
|||||||
app.setRequiredAbi(requiredAbi);
|
app.setRequiredAbi(requiredAbi);
|
||||||
app.setInstructionSet(instructionSet);
|
app.setInstructionSet(instructionSet);
|
||||||
|
|
||||||
// If instructionSet is non-null, this indicates that the system_server is spawning a
|
// If this was an external service, the package name and uid in the passed in
|
||||||
// process with an ISA that may be different from its own. System (kernel and hardware)
|
// ApplicationInfo have been changed to match those of the calling package;
|
||||||
// compatibility for these features is checked in the decideTaggingLevel in the
|
// that will incorrectly apply compat feature overrides for the calling package instead
|
||||||
// system_server process (not the child process). As both MTE and TBI are only supported
|
// of the defining one.
|
||||||
// in aarch64, we can simply ensure that the new process is also aarch64. This prevents
|
ApplicationInfo definingAppInfo;
|
||||||
// the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should
|
if (hostingRecord.getDefiningPackageName() != null) {
|
||||||
// enable some tagging variant. Theoretically, a 32-bit system server could exist that
|
definingAppInfo = new ApplicationInfo(app.info);
|
||||||
// spawns 64-bit processes, in which case the new process won't get any tagging. This is
|
definingAppInfo.packageName = hostingRecord.getDefiningPackageName();
|
||||||
// fine as we haven't seen this configuration in practice, and we can reasonable assume
|
definingAppInfo.uid = uid;
|
||||||
// that if tagging is desired, the system server will be 64-bit.
|
} else {
|
||||||
if (instructionSet == null || instructionSet.equals("arm64")) {
|
definingAppInfo = app.info;
|
||||||
runtimeFlags |= decideTaggingLevel(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableNativeHeapZeroInit(app)) {
|
runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags(
|
||||||
runtimeFlags |= Zygote.NATIVE_HEAP_ZERO_INIT;
|
definingAppInfo, app.processInfo, instructionSet, mPlatformCompat);
|
||||||
}
|
|
||||||
|
|
||||||
// the per-user SELinux context must be set
|
// the per-user SELinux context must be set
|
||||||
if (TextUtils.isEmpty(app.info.seInfoUser)) {
|
if (TextUtils.isEmpty(app.info.seInfoUser)) {
|
||||||
@@ -2299,8 +2111,7 @@ public final class ProcessList {
|
|||||||
// not the calling one.
|
// not the calling one.
|
||||||
appInfo.packageName = app.getHostingRecord().getDefiningPackageName();
|
appInfo.packageName = app.getHostingRecord().getDefiningPackageName();
|
||||||
appInfo.uid = uid;
|
appInfo.uid = uid;
|
||||||
int runtimeFlags = decideTaggingLevelForAppZygote(app);
|
appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid);
|
||||||
appZygote = new AppZygote(appInfo, uid, firstUid, lastUid, runtimeFlags);
|
|
||||||
mAppZygotes.put(app.info.processName, uid, appZygote);
|
mAppZygotes.put(app.info.processName, uid, appZygote);
|
||||||
zygoteProcessList = new ArrayList<ProcessRecord>();
|
zygoteProcessList = new ArrayList<ProcessRecord>();
|
||||||
mAppZygoteProcesses.put(appZygote, zygoteProcessList);
|
mAppZygoteProcesses.put(appZygote, zygoteProcessList);
|
||||||
@@ -3158,7 +2969,8 @@ public final class ProcessList {
|
|||||||
FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
|
FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
|
||||||
FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
|
FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
|
||||||
}
|
}
|
||||||
final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
|
final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
|
||||||
|
hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
|
||||||
final ProcessStateRecord state = r.mState;
|
final ProcessStateRecord state = r.mState;
|
||||||
|
|
||||||
if (!mService.mBooted && !mService.mBooting
|
if (!mService.mBooted && !mService.mBooting
|
||||||
|
|||||||
@@ -492,15 +492,25 @@ class ProcessRecord implements WindowProcessListener {
|
|||||||
|
|
||||||
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
|
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
|
||||||
int _uid) {
|
int _uid) {
|
||||||
|
this(_service, _info, _processName, _uid, -1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
|
||||||
|
int _uid, int _definingUid, String _definingProcessName) {
|
||||||
mService = _service;
|
mService = _service;
|
||||||
mProcLock = _service.mProcLock;
|
mProcLock = _service.mProcLock;
|
||||||
info = _info;
|
info = _info;
|
||||||
ProcessInfo procInfo = null;
|
ProcessInfo procInfo = null;
|
||||||
if (_service.mPackageManagerInt != null) {
|
if (_service.mPackageManagerInt != null) {
|
||||||
|
if (_definingUid > 0) {
|
||||||
|
ArrayMap<String, ProcessInfo> processes =
|
||||||
|
_service.mPackageManagerInt.getProcessesForUid(_definingUid);
|
||||||
|
if (processes != null) procInfo = processes.get(_definingProcessName);
|
||||||
|
} else {
|
||||||
ArrayMap<String, ProcessInfo> processes =
|
ArrayMap<String, ProcessInfo> processes =
|
||||||
_service.mPackageManagerInt.getProcessesForUid(_uid);
|
_service.mPackageManagerInt.getProcessesForUid(_uid);
|
||||||
if (processes != null) {
|
if (processes != null) procInfo = processes.get(_processName);
|
||||||
procInfo = processes.get(_processName);
|
}
|
||||||
if (procInfo != null && procInfo.deniedPermissions == null
|
if (procInfo != null && procInfo.deniedPermissions == null
|
||||||
&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
|
&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
|
||||||
&& procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
|
&& procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
|
||||||
@@ -511,7 +521,6 @@ class ProcessRecord implements WindowProcessListener {
|
|||||||
procInfo = null;
|
procInfo = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
processInfo = procInfo;
|
processInfo = procInfo;
|
||||||
isolated = Process.isIsolated(_uid);
|
isolated = Process.isIsolated(_uid);
|
||||||
appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID
|
appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID
|
||||||
|
|||||||
@@ -1000,7 +1000,7 @@ public class ApplicationExitInfoTest {
|
|||||||
final String dummyPackageName = "com.android.test";
|
final String dummyPackageName = "com.android.test";
|
||||||
final String dummyClassName = ".Foo";
|
final String dummyClassName = ".Foo";
|
||||||
app.setHostingRecord(HostingRecord.byAppZygote(new ComponentName(
|
app.setHostingRecord(HostingRecord.byAppZygote(new ComponentName(
|
||||||
dummyPackageName, dummyClassName), "", definingUid));
|
dummyPackageName, dummyClassName), "", definingUid, ""));
|
||||||
}
|
}
|
||||||
app.mServices.setConnectionGroup(connectionGroup);
|
app.mServices.setConnectionGroup(connectionGroup);
|
||||||
app.mState.setReportedProcState(procState);
|
app.mState.setReportedProcState(procState);
|
||||||
|
|||||||
Reference in New Issue
Block a user