Merge "Implement memtagMode and nativeHeapZeroInit manifest attrs." am: d600f5067a

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1556655

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I9c84f162736af927f6cac041f4200dc3ab2b8efa
This commit is contained in:
Evgenii Stepanov
2021-02-26 20:50:30 +00:00
committed by Automerger Merge Worker
17 changed files with 336 additions and 49 deletions

View File

@@ -954,6 +954,7 @@ package android {
field public static final int measureWithLargestChild = 16843476; // 0x10102d4
field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
field public static final int mediaRouteTypes = 16843694; // 0x10103ae
field public static final int memtagMode = 16844313; // 0x1010619
field public static final int menuCategory = 16843230; // 0x10101de
field public static final int mimeGroup = 16844309; // 0x1010615
field public static final int mimeType = 16842790; // 0x1010026
@@ -977,6 +978,7 @@ package android {
field public static final int multiArch = 16843918; // 0x101048e
field public static final int multiprocess = 16842771; // 0x1010013
field public static final int name = 16842755; // 0x1010003
field public static final int nativeHeapZeroInit = 16844314; // 0x101061a
field public static final int navigationBarColor = 16843858; // 0x1010452
field public static final int navigationBarDividerColor = 16844141; // 0x101056d
field public static final int navigationContentDescription = 16843969; // 0x10104c1
@@ -11461,6 +11463,8 @@ package android.content.pm {
method public void dump(android.util.Printer, String);
method public static CharSequence getCategoryTitle(android.content.Context, int);
method public int getGwpAsanMode();
method public int getMemtagMode();
method @Nullable public Boolean isNativeHeapZeroInit();
method public boolean isProfileableByShell();
method public boolean isResourceOverlay();
method public boolean isVirtualPreload();
@@ -11510,6 +11514,10 @@ package android.content.pm {
field public static final int GWP_ASAN_ALWAYS = 1; // 0x1
field public static final int GWP_ASAN_DEFAULT = -1; // 0xffffffff
field public static final int GWP_ASAN_NEVER = 0; // 0x0
field public static final int MEMTAG_ASYNC = 1; // 0x1
field public static final int MEMTAG_DEFAULT = -1; // 0xffffffff
field public static final int MEMTAG_OFF = 0; // 0x0
field public static final int MEMTAG_SYNC = 2; // 0x2
field public String appComponentFactory;
field public String backupAgentName;
field public int category;

View File

@@ -38,6 +38,8 @@ import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Parcelling;
import com.android.internal.util.Parcelling.BuiltIn.ForBoolean;
import com.android.server.SystemConfig;
import java.lang.annotation.Retention;
@@ -56,6 +58,8 @@ import java.util.UUID;
* <application> tag.
*/
public class ApplicationInfo extends PackageItemInfo implements Parcelable {
private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
/**
* Default task affinity of all activities in this application. See
* {@link ActivityInfo#taskAffinity} for more information. This comes
@@ -1335,6 +1339,51 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
private @GwpAsanMode int gwpAsanMode;
/**
* Default (unspecified) setting of Memtag.
*/
public static final int MEMTAG_DEFAULT = -1;
/**
* Do not enable Memtag in this application or process.
*/
public static final int MEMTAG_OFF = 0;
/**
* Enable Memtag in Async mode in this application or process.
*/
public static final int MEMTAG_ASYNC = 1;
/**
* Enable Memtag in Sync mode in this application or process.
*/
public static final int MEMTAG_SYNC = 2;
/**
* These constants need to match the values of memtagMode in application manifest.
* @hide
*/
@IntDef(prefix = {"MEMTAG_"}, value = {
MEMTAG_DEFAULT,
MEMTAG_OFF,
MEMTAG_ASYNC,
MEMTAG_SYNC,
})
@Retention(RetentionPolicy.SOURCE)
public @interface MemtagMode {}
/**
* Indicates if the application has requested Memtag to be enabled, disabled, or left
* unspecified. Processes can override this setting.
*/
private @MemtagMode int memtagMode;
/**
* Enable automatic zero-initialization of native heap memory allocations.
*/
@Nullable
private Boolean nativeHeapZeroInit;
/**
* Represents the default policy. The actual policy used will depend on other properties of
* the application, e.g. the target SDK version.
@@ -1479,6 +1528,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
if (gwpAsanMode != GWP_ASAN_DEFAULT) {
pw.println(prefix + "gwpAsanMode=" + gwpAsanMode);
}
if (memtagMode != MEMTAG_DEFAULT) {
pw.println(prefix + "memtagMode=" + memtagMode);
}
if (nativeHeapZeroInit != null) {
pw.println(prefix + "nativeHeapZeroInit=" + nativeHeapZeroInit);
}
}
super.dumpBack(pw, prefix);
}
@@ -1580,6 +1635,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
if (gwpAsanMode != GWP_ASAN_DEFAULT) {
proto.write(ApplicationInfoProto.Detail.ENABLE_GWP_ASAN, gwpAsanMode);
}
if (memtagMode != MEMTAG_DEFAULT) {
proto.write(ApplicationInfoProto.Detail.ENABLE_MEMTAG, memtagMode);
}
if (nativeHeapZeroInit != null) {
proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, nativeHeapZeroInit);
}
proto.end(detailToken);
}
proto.end(token);
@@ -1690,6 +1751,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
hiddenUntilInstalled = orig.hiddenUntilInstalled;
zygotePreloadName = orig.zygotePreloadName;
gwpAsanMode = orig.gwpAsanMode;
memtagMode = orig.memtagMode;
nativeHeapZeroInit = orig.nativeHeapZeroInit;
}
public String toString() {
@@ -1774,6 +1837,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeInt(hiddenUntilInstalled ? 1 : 0);
dest.writeString8(zygotePreloadName);
dest.writeInt(gwpAsanMode);
dest.writeInt(memtagMode);
sForBoolean.parcel(nativeHeapZeroInit, dest, parcelableFlags);
}
public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1855,6 +1920,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
hiddenUntilInstalled = source.readInt() != 0;
zygotePreloadName = source.readString8();
gwpAsanMode = source.readInt();
memtagMode = source.readInt();
nativeHeapZeroInit = sForBoolean.unparcel(source);
}
/**
@@ -2237,6 +2304,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/** {@hide} */ public void setBaseResourcePath(String baseResourcePath) { publicSourceDir = baseResourcePath; }
/** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; }
/** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; }
/** {@hide} */ public void setMemtagMode(@MemtagMode int value) { memtagMode = value; }
/** {@hide} */ public void setNativeHeapZeroInit(@Nullable Boolean value) { nativeHeapZeroInit = value; }
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2250,4 +2319,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
@GwpAsanMode
public int getGwpAsanMode() { return gwpAsanMode; }
@MemtagMode
public int getMemtagMode() { return memtagMode; }
@Nullable
public Boolean isNativeHeapZeroInit() { return nativeHeapZeroInit; }
}

View File

@@ -53,16 +53,30 @@ public class ProcessInfo implements Parcelable {
*/
public @ApplicationInfo.GwpAsanMode int gwpAsanMode;
/**
* Indicates if the process has requested Memtag to be enabled (in sync or async mode),
* disabled, or left unspecified.
*/
public @ApplicationInfo.MemtagMode int memtagMode;
/**
* Enable automatic zero-initialization of native heap memory allocations.
*/
@Nullable
public Boolean nativeHeapZeroInit;
@Deprecated
public ProcessInfo(@NonNull ProcessInfo orig) {
this.name = orig.name;
this.deniedPermissions = orig.deniedPermissions;
this.gwpAsanMode = orig.gwpAsanMode;
this.memtagMode = orig.memtagMode;
this.nativeHeapZeroInit = orig.nativeHeapZeroInit;
}
// Code below generated by codegen v1.0.15.
// Code below generated by codegen v1.0.22.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -84,12 +98,19 @@ public class ProcessInfo implements Parcelable {
* If non-null, these are permissions that are not allowed in this process.
* @param gwpAsanMode
* Indicates if the process has requested GWP-ASan to be enabled, disabled, or left unspecified.
* @param memtagMode
* Indicates if the process has requested Memtag to be enabled (in sync or async mode),
* disabled, or left unspecified.
* @param nativeHeapZeroInit
* Enable automatic zero-initialization of native heap memory allocations.
*/
@DataClass.Generated.Member
public ProcessInfo(
@NonNull String name,
@Nullable ArraySet<String> deniedPermissions,
@ApplicationInfo.GwpAsanMode int gwpAsanMode) {
@ApplicationInfo.GwpAsanMode int gwpAsanMode,
@ApplicationInfo.MemtagMode int memtagMode,
@Nullable Boolean nativeHeapZeroInit) {
this.name = name;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, name);
@@ -97,6 +118,10 @@ public class ProcessInfo implements Parcelable {
this.gwpAsanMode = gwpAsanMode;
com.android.internal.util.AnnotationValidations.validate(
ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
this.memtagMode = memtagMode;
com.android.internal.util.AnnotationValidations.validate(
ApplicationInfo.MemtagMode.class, null, memtagMode);
this.nativeHeapZeroInit = nativeHeapZeroInit;
// onConstructed(); // You can define this method to get a callback
}
@@ -120,10 +145,13 @@ public class ProcessInfo implements Parcelable {
byte flg = 0;
if (deniedPermissions != null) flg |= 0x2;
if (nativeHeapZeroInit != null) flg |= 0x10;
dest.writeByte(flg);
dest.writeString(name);
sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
dest.writeInt(gwpAsanMode);
dest.writeInt(memtagMode);
if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
}
@Override
@@ -141,6 +169,8 @@ public class ProcessInfo implements Parcelable {
String _name = in.readString();
ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
int _gwpAsanMode = in.readInt();
int _memtagMode = in.readInt();
Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
this.name = _name;
com.android.internal.util.AnnotationValidations.validate(
@@ -149,6 +179,10 @@ public class ProcessInfo implements Parcelable {
this.gwpAsanMode = _gwpAsanMode;
com.android.internal.util.AnnotationValidations.validate(
ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
this.memtagMode = _memtagMode;
com.android.internal.util.AnnotationValidations.validate(
ApplicationInfo.MemtagMode.class, null, memtagMode);
this.nativeHeapZeroInit = _nativeHeapZeroInit;
// onConstructed(); // You can define this method to get a callback
}
@@ -168,10 +202,10 @@ public class ProcessInfo implements Parcelable {
};
@DataClass.Generated(
time = 1584555730519L,
codegenVersion = "1.0.15",
time = 1611614699049L,
codegenVersion = "1.0.22",
sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java",
inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
@Deprecated
private void __metadata() {}

View File

@@ -241,6 +241,10 @@ public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage setGwpAsanMode(int gwpAsanMode);
ParsingPackage setMemtagMode(int memtagMode);
ParsingPackage setNativeHeapZeroInit(@Nullable Boolean nativeHeapZeroInit);
ParsingPackage setCrossProfile(boolean crossProfile);
ParsingPackage setFullBackupContent(int fullBackupContent);

View File

@@ -416,6 +416,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
private boolean preserveLegacyExternalStorage;
protected int gwpAsanMode;
protected int memtagMode;
@Nullable
@DataClass.ParcelWith(ForBoolean.class)
private Boolean nativeHeapZeroInit;
// TODO(chiuwinson): Non-null
@Nullable
@@ -926,6 +931,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
appInfo.zygotePreloadName = zygotePreloadName;
appInfo.crossProfile = isCrossProfile();
appInfo.setGwpAsanMode(gwpAsanMode);
appInfo.setMemtagMode(memtagMode);
appInfo.setNativeHeapZeroInit(nativeHeapZeroInit);
appInfo.setBaseCodePath(baseCodePath);
appInfo.setBaseResourcePath(baseCodePath);
appInfo.setCodePath(codePath);
@@ -1110,6 +1117,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
dest.writeArraySet(this.mimeGroups);
dest.writeInt(this.gwpAsanMode);
dest.writeSparseIntArray(this.minExtensionVersions);
dest.writeInt(this.memtagMode);
sForBoolean.parcel(this.nativeHeapZeroInit, dest, flags);
}
public ParsingPackageImpl(Parcel in) {
@@ -1270,6 +1279,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
this.mimeGroups = (ArraySet<String>) in.readArraySet(boot);
this.gwpAsanMode = in.readInt();
this.minExtensionVersions = in.readSparseIntArray();
this.memtagMode = in.readInt();
this.nativeHeapZeroInit = sForBoolean.unparcel(in);
}
public static final Parcelable.Creator<ParsingPackageImpl> CREATOR =
@@ -2002,6 +2013,17 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return gwpAsanMode;
}
@Override
public int getMemtagMode() {
return memtagMode;
}
@Nullable
@Override
public Boolean isNativeHeapZeroInit() {
return nativeHeapZeroInit;
}
@Override
public boolean isPartiallyDirectBootAware() {
return partiallyDirectBootAware;
@@ -2474,6 +2496,18 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable {
return this;
}
@Override
public ParsingPackageImpl setMemtagMode(int value) {
memtagMode = value;
return this;
}
@Override
public ParsingPackageImpl setNativeHeapZeroInit(@Nullable Boolean value) {
nativeHeapZeroInit = value;
return this;
}
@Override
public ParsingPackageImpl setPartiallyDirectBootAware(boolean value) {
partiallyDirectBootAware = value;

View File

@@ -856,6 +856,19 @@ public interface ParsingPackageRead extends Parcelable {
*/
public int getGwpAsanMode();
/**
* @see ApplicationInfo#memtagMode
* @see R.styleable#AndroidManifest_memtagMode
*/
int getMemtagMode();
/**
* @see ApplicationInfo#nativeHeapZeroInit
* @see R.styleable#AndroidManifest_nativeHeapZeroInit
*/
@Nullable
Boolean isNativeHeapZeroInit();
// TODO(b/135203078): Hide and enforce going through PackageInfoUtils
ApplicationInfo toAppInfoWithoutState();

View File

@@ -1799,6 +1799,11 @@ public class ParsingPackageUtils {
}
pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1));
pkg.setMemtagMode(sa.getInt(R.styleable.AndroidManifestApplication_memtagMode, -1));
if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInit)) {
pkg.setNativeHeapZeroInit(sa.getBoolean(
R.styleable.AndroidManifestApplication_nativeHeapZeroInit, false));
}
} finally {
sa.recycle();
}

View File

@@ -20,6 +20,7 @@ import static java.util.Collections.emptySet;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -41,7 +42,10 @@ public class ParsedProcess implements Parcelable {
@DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class)
protected Set<String> deniedPermissions = emptySet();
protected int gwpAsanMode = -1;
protected int gwpAsanMode = ApplicationInfo.GWP_ASAN_DEFAULT;
protected int memtagMode = ApplicationInfo.MEMTAG_DEFAULT;
@Nullable
protected Boolean nativeHeapZeroInit = null;
public ParsedProcess() {
}
@@ -57,7 +61,7 @@ public class ParsedProcess implements Parcelable {
// Code below generated by codegen v1.0.15.
// Code below generated by codegen v1.0.22.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -74,7 +78,9 @@ public class ParsedProcess implements Parcelable {
public ParsedProcess(
@NonNull String name,
@NonNull Set<String> deniedPermissions,
int gwpAsanMode) {
int gwpAsanMode,
int memtagMode,
@Nullable Boolean nativeHeapZeroInit) {
this.name = name;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, name);
@@ -82,6 +88,8 @@ public class ParsedProcess implements Parcelable {
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, deniedPermissions);
this.gwpAsanMode = gwpAsanMode;
this.memtagMode = memtagMode;
this.nativeHeapZeroInit = nativeHeapZeroInit;
// onConstructed(); // You can define this method to get a callback
}
@@ -101,6 +109,16 @@ public class ParsedProcess implements Parcelable {
return gwpAsanMode;
}
@DataClass.Generated.Member
public int getMemtagMode() {
return memtagMode;
}
@DataClass.Generated.Member
public @Nullable Boolean getNativeHeapZeroInit() {
return nativeHeapZeroInit;
}
@DataClass.Generated.Member
static Parcelling<Set<String>> sParcellingForDeniedPermissions =
Parcelling.Cache.get(
@@ -118,9 +136,14 @@ public class ParsedProcess implements Parcelable {
// You can override field parcelling by defining methods like:
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
if (nativeHeapZeroInit != null) flg |= 0x10;
dest.writeByte(flg);
dest.writeString(name);
sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
dest.writeInt(gwpAsanMode);
dest.writeInt(memtagMode);
if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
}
@Override
@@ -134,9 +157,12 @@ public class ParsedProcess implements Parcelable {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
String _name = in.readString();
Set<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
int _gwpAsanMode = in.readInt();
int _memtagMode = in.readInt();
Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
this.name = _name;
com.android.internal.util.AnnotationValidations.validate(
@@ -145,6 +171,8 @@ public class ParsedProcess implements Parcelable {
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, deniedPermissions);
this.gwpAsanMode = _gwpAsanMode;
this.memtagMode = _memtagMode;
this.nativeHeapZeroInit = _nativeHeapZeroInit;
// onConstructed(); // You can define this method to get a callback
}
@@ -164,10 +192,10 @@ public class ParsedProcess implements Parcelable {
};
@DataClass.Generated(
time = 1584557524776L,
codegenVersion = "1.0.15",
time = 1611615591258L,
codegenVersion = "1.0.22",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedProcess.java",
inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected int gwpAsanMode\npublic void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected int gwpAsanMode\nprotected int memtagMode\nprotected @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\npublic void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
@Deprecated
private void __metadata() {}

View File

@@ -105,6 +105,11 @@ public class ParsedProcessUtils {
}
proc.gwpAsanMode = sa.getInt(R.styleable.AndroidManifestProcess_gwpAsanMode, -1);
proc.memtagMode = sa.getInt(R.styleable.AndroidManifestProcess_memtagMode, -1);
if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInit)) {
proc.nativeHeapZeroInit =
sa.getBoolean(R.styleable.AndroidManifestProcess_nativeHeapZeroInit, false);
}
} finally {
sa.recycle();
}

View File

@@ -123,6 +123,8 @@ public final class Zygote {
public static final int DISABLE_TEST_API_ENFORCEMENT_POLICY = 1 << 18;
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.
@@ -168,6 +170,11 @@ public final class Zygote {
*/
public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21;
/**
* Enable automatic zero-initialization of native heap memory allocations.
*/
public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23;
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
/** Default external storage should be mounted. */

View File

@@ -344,6 +344,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,
};
enum UnsolicitedZygoteMessageTypes : uint32_t {
@@ -1682,15 +1683,20 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
}
mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level);
// Now that we've used the flag, clear it so that we don't pass unknown flags to the ART runtime.
runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK;
// Avoid heap zero initialization for applications without MTE. Zero init may
// cause app compat problems, use more memory, or reduce performance. While it
// 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.
mallopt(M_BIONIC_ZERO_INIT, 0);
if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) {
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::MEMORY_TAG_LEVEL_MASK;
runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT;
bool forceEnableGwpAsan = false;
switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {

View File

@@ -110,6 +110,8 @@ message ApplicationInfoProto {
optional int32 network_security_config_res = 17;
optional int32 category = 18;
optional int32 enable_gwp_asan = 19;
optional int32 enable_memtag = 20;
optional bool native_heap_zero_init = 21;
}
optional Detail detail = 17;
}

View File

@@ -1560,6 +1560,13 @@
<enum name="always" value="1" />
</attr>
<attr name="memtagMode">
<enum name="default" value="-1" />
<enum name="off" value="0" />
<enum name="async" value="1" />
<enum name="sync" value="2" />
</attr>
<!-- The <code>manifest</code> tag is the root of an
<code>AndroidManifest.xml</code> file,
describing the contents of an Android package (.apk) file. One
@@ -1827,6 +1834,10 @@
<attr name="gwpAsanMode" />
<attr name="memtagMode" />
<attr name="nativeHeapZeroInit" format="boolean" />
<!-- @hide no longer used, kept to preserve padding -->
<attr name="allowAutoRevokePermissionsExemption" format="boolean" />
@@ -2350,6 +2361,8 @@
<!-- Required name of the process that is allowed -->
<attr name="process" />
<attr name="gwpAsanMode" />
<attr name="memtagMode" />
<attr name="nativeHeapZeroInit" />
</declare-styleable>
<!-- The <code>deny-permission</code> tag specifies that a permission is to be denied

View File

@@ -3046,6 +3046,8 @@
<public name="canPauseRecording" />
<!-- attribute definitions go here -->
<public name="requireDeviceScreenOn" />
<public name="memtagMode" />
<public name="nativeHeapZeroInit" />
</public-group>
<public-group type="drawable" first-id="0x010800b5">

View File

@@ -366,6 +366,13 @@ public final class ProcessList {
@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>.
@@ -1687,12 +1694,28 @@ public final class ProcessList {
return gidArray;
}
// Returns the memory tagging level to be enabled. If memory tagging isn't
// requested, returns zero.
private int getMemtagLevel(ProcessRecord app) {
// Ensure the hardware + kernel actually supports MTE.
if (!Zygote.nativeSupportsMemoryTagging()) {
return 0;
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)) {
@@ -1703,40 +1726,43 @@ public final class ProcessList {
return Zygote.MEMORY_TAG_LEVEL_ASYNC;
}
return 0;
}
private boolean shouldEnableTaggedPointers(ProcessRecord app) {
// Ensure we have platform + kernel support for TBI.
if (!Zygote.nativeSupportsTaggedPointers()) {
return false;
}
// Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
if (!app.info.allowsNativeHeapPointerTagging()) {
return false;
return Zygote.MEMORY_TAG_LEVEL_NONE;
}
// Check to see that the compat feature for TBI is enabled.
if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
return false;
}
return true;
}
private int decideTaggingLevel(ProcessRecord app) {
// Check MTE support first, as it should take precedence over TBI.
int memtagLevel = getMemtagLevel(app);
if (memtagLevel != 0) {
return memtagLevel;
}
if (shouldEnableTaggedPointers(app)) {
if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
return Zygote.MEMORY_TAG_LEVEL_TBI;
}
return 0;
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 decideGwpAsanLevel(ProcessRecord app) {
@@ -1747,7 +1773,7 @@ public final class ProcessList {
? Zygote.GWP_ASAN_LEVEL_ALWAYS
: Zygote.GWP_ASAN_LEVEL_NEVER;
}
// Then at the applicaton attribute.
// 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
@@ -1764,6 +1790,22 @@ public final class ProcessList {
return Zygote.GWP_ASAN_LEVEL_NEVER;
}
private boolean enableNativeHeapZeroInit(ProcessRecord app) {
// Look at the process attribute first.
if (app.processInfo != null && app.processInfo.nativeHeapZeroInit != null) {
return app.processInfo.nativeHeapZeroInit;
}
// Then at the application attribute.
if (app.info.isNativeHeapZeroInit() != null) {
return app.info.isNativeHeapZeroInit();
}
// 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.
*/
@@ -1971,6 +2013,10 @@ public final class ProcessList {
runtimeFlags |= decideTaggingLevel(app);
}
if (enableNativeHeapZeroInit(app)) {
runtimeFlags |= Zygote.NATIVE_HEAP_ZERO_INIT;
}
// the per-user SELinux context must be set
if (TextUtils.isEmpty(app.info.seInfoUser)) {
Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",

View File

@@ -388,6 +388,9 @@ class ProcessRecord implements WindowProcessListener {
if (processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
pw.print(prefix); pw.println(" gwpAsanMode=" + processInfo.gwpAsanMode);
}
if (processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
pw.print(prefix); pw.println(" memtagMode=" + processInfo.memtagMode);
}
}
pw.print(prefix); pw.print("mRequiredAbi="); pw.print(mRequiredAbi);
pw.print(" instructionSet="); pw.println(instructionSet);
@@ -645,9 +648,12 @@ class ProcessRecord implements WindowProcessListener {
if (processes != null) {
procInfo = processes.get(_processName);
if (procInfo != null && procInfo.deniedPermissions == null
&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT) {
&& procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
&& procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
&& procInfo.nativeHeapZeroInit == null) {
// If this process hasn't asked for permissions to be denied, or for a
// non-default GwpAsan mode, then we don't care about it.
// non-default GwpAsan mode, or any other non-default setting, then we don't
// care about it.
procInfo = null;
}
}

View File

@@ -399,7 +399,8 @@ public class PackageInfoUtils {
ParsedProcess proc = procs.get(key);
retProcs.put(proc.getName(),
new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()),
proc.getGwpAsanMode()));
proc.getGwpAsanMode(), proc.getMemtagMode(),
proc.getNativeHeapZeroInit()));
}
return retProcs;
}