diff options
17 files changed, 332 insertions, 45 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 80c555bd15b9..5f2555a20f75 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -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; diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index e32068fe4b39..6ec11693d69b 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -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 @@ -1336,6 +1340,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. * @hide @@ -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; } } diff --git a/core/java/android/content/pm/ProcessInfo.java b/core/java/android/content/pm/ProcessInfo.java index d45ff98d58e4..3dd5ee102090 100644 --- a/core/java/android/content/pm/ProcessInfo.java +++ b/core/java/android/content/pm/ProcessInfo.java @@ -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() {} diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 2ee0ad67b108..983a02ca6576 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -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); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index f932bc250e28..ffc78f3fd942 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -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 = @@ -2003,6 +2014,17 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override + public int getMemtagMode() { + return memtagMode; + } + + @Nullable + @Override + public Boolean isNativeHeapZeroInit() { + return nativeHeapZeroInit; + } + + @Override public boolean isPartiallyDirectBootAware() { return partiallyDirectBootAware; } @@ -2475,6 +2497,18 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @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; return this; diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 5b53c18b820c..cd91e280b695 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -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(); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index ab0ed51fb909..890ba8a59a89 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -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(); } diff --git a/core/java/android/content/pm/parsing/component/ParsedProcess.java b/core/java/android/content/pm/parsing/component/ParsedProcess.java index e0ae81b2e30b..89fef9d8e0dd 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProcess.java +++ b/core/java/android/content/pm/parsing/component/ParsedProcess.java @@ -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 } @@ -102,6 +110,16 @@ public class ParsedProcess implements Parcelable { } @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( Parcelling.BuiltIn.ForInternedStringSet.class); @@ -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() {} diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java index 837270721078..082593efd498 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java @@ -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(); } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 9abc55b983a0..d99f30567311 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -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. */ diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 4cef2b099589..bcd203b6ca77 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -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) { diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto index e6833066f17e..bb39ea810add 100644 --- a/core/proto/android/content/package_item_info.proto +++ b/core/proto/android/content/package_item_info.proto @@ -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; } diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 0c63c1096a3a..47dbd64c0402 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -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 diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 0874a77815b5..0f846d3dbad9 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -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"> diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index b6e632d42d8e..c5a6e7b83859 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -367,6 +367,13 @@ public final class ProcessList { 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; + if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { + return Zygote.MEMORY_TAG_LEVEL_TBI; } - return true; + return Zygote.MEMORY_TAG_LEVEL_NONE; } 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)) { - return Zygote.MEMORY_TAG_LEVEL_TBI; + // 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 0; + 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", diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c5152c081e70..4775541c6781 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -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; } } diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index 09b4f8967729..64fa70812528 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -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; } |