Loading core/java/android/content/pm/ApplicationInfo.java +16 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_HAS_FRAGILE_USER_DATA = 1 << 24; /** * Indicate whether this application prefers code integrity, that is, run only code that is * signed. This requires android:extractNativeLibs to be "false", as well as .dex and .so (if * any) stored uncompressed inside the APK, which is signed. At run time, the implications * include: * * <ul> * <li>ART will JIT the dex code directly from the APK. There may be performance characteristic * changes depend on the actual workload. * </ul> * * @hide */ public static final int PRIVATE_FLAG_PREFER_CODE_INTEGRITY = 1 << 25; /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, Loading @@ -654,6 +669,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, PRIVATE_FLAG_OEM, PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, PRIVATE_FLAG_PREFER_CODE_INTEGRITY, PRIVATE_FLAG_PRIVILEGED, PRIVATE_FLAG_PRODUCT, PRIVATE_FLAG_PRODUCT_SERVICES, Loading core/java/android/content/pm/PackageParser.java +20 −2 Original line number Diff line number Diff line Loading @@ -475,6 +475,7 @@ public class PackageParser { public final boolean extractNativeLibs; public final boolean isolatedSplits; public final boolean isSplitRequired; public final boolean preferCodeIntegrity; public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit, Loading @@ -483,7 +484,7 @@ public class PackageParser { int revisionCode, int installLocation, List<VerifierInfo> verifiers, SigningDetails signingDetails, boolean coreApp, boolean debuggable, boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs, boolean isolatedSplits) { boolean preferCodeIntegrity, boolean extractNativeLibs, boolean isolatedSplits) { this.codePath = codePath; this.packageName = packageName; this.splitName = splitName; Loading @@ -500,6 +501,7 @@ public class PackageParser { this.debuggable = debuggable; this.multiArch = multiArch; this.use32bitAbi = use32bitAbi; this.preferCodeIntegrity = preferCodeIntegrity; this.extractNativeLibs = extractNativeLibs; this.isolatedSplits = isolatedSplits; this.isSplitRequired = isSplitRequired; Loading Loading @@ -1722,6 +1724,7 @@ public class PackageParser { boolean isolatedSplits = false; boolean isFeatureSplit = false; boolean isSplitRequired = false; boolean preferCodeIntegrity = false; String configForSplit = null; String usesSplitName = null; Loading Loading @@ -1784,6 +1787,9 @@ public class PackageParser { if ("extractNativeLibs".equals(attr)) { extractNativeLibs = attrs.getAttributeBooleanValue(i, true); } if ("preferCodeIntegrity".equals(attr)) { preferCodeIntegrity = attrs.getAttributeBooleanValue(i, false); } } } else if (TAG_USES_SPLIT.equals(parser.getName())) { if (usesSplitName != null) { Loading @@ -1800,10 +1806,16 @@ public class PackageParser { } } if (preferCodeIntegrity && extractNativeLibs) { throw new PackageParserException( PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, "Can't request both preferCodeIntegrity and extractNativeLibs"); } return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable, multiArch, use32bitAbi, extractNativeLibs, isolatedSplits); multiArch, use32bitAbi, preferCodeIntegrity, extractNativeLibs, isolatedSplits); } /** Loading Loading @@ -3654,6 +3666,12 @@ public class PackageParser { ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_preferCodeIntegrity, false)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, false)) { Loading core/res/res/values/attrs_manifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -1112,6 +1112,11 @@ resource] to be present in order to function. Default value is false. --> <attr name="isSplitRequired" format="boolean" /> <!-- Flag to specify if this app prioritizes code integrity. The system may choose to run with better integrity guarantee in various components if possible based on the app's <code>targetSdkVersion</code>. --> <attr name="preferCodeIntegrity" format="boolean" /> <!-- Extra options for an activity's UI. Applies to either the {@code <activity>} or {@code <application>} tag. If specified on the {@code <application>} tag these will be considered defaults for all activities in the Loading Loading @@ -1580,6 +1585,7 @@ to honor this flag as well. --> <attr name="usesCleartextTraffic" /> <attr name="multiArch" /> <attr name="preferCodeIntegrity" /> <attr name="extractNativeLibs" /> <attr name="defaultToDeviceProtectedStorage" format="boolean" /> <attr name="directBootAware" /> Loading services/core/java/com/android/server/am/ProcessList.java +3 −2 Original line number Diff line number Diff line Loading @@ -1362,8 +1362,9 @@ public final class ProcessList { mService.mNativeDebuggingApp = null; } if (app.info.isPrivilegedApp() && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) { if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY) != 0 || (app.info.isPrivilegedApp() && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +11 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; import com.android.server.pm.dex.DexManager; import libcore.io.IoUtils; Loading Loading @@ -1594,6 +1595,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } if (baseApk.preferCodeIntegrity) { for (File file : mResolvedStagedFiles) { if (file.getName().endsWith(".apk") && !DexManager.auditUncompressedCodeInApk(file.getPath())) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Some code are not uncompressed and aligned correctly for " + mPackageName); } } } if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, "Missing split for " + mPackageName); Loading Loading
core/java/android/content/pm/ApplicationInfo.java +16 −0 Original line number Diff line number Diff line Loading @@ -639,6 +639,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public static final int PRIVATE_FLAG_HAS_FRAGILE_USER_DATA = 1 << 24; /** * Indicate whether this application prefers code integrity, that is, run only code that is * signed. This requires android:extractNativeLibs to be "false", as well as .dex and .so (if * any) stored uncompressed inside the APK, which is signed. At run time, the implications * include: * * <ul> * <li>ART will JIT the dex code directly from the APK. There may be performance characteristic * changes depend on the actual workload. * </ul> * * @hide */ public static final int PRIVATE_FLAG_PREFER_CODE_INTEGRITY = 1 << 25; /** @hide */ @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = { PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE, Loading @@ -654,6 +669,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { PRIVATE_FLAG_ISOLATED_SPLIT_LOADING, PRIVATE_FLAG_OEM, PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, PRIVATE_FLAG_PREFER_CODE_INTEGRITY, PRIVATE_FLAG_PRIVILEGED, PRIVATE_FLAG_PRODUCT, PRIVATE_FLAG_PRODUCT_SERVICES, Loading
core/java/android/content/pm/PackageParser.java +20 −2 Original line number Diff line number Diff line Loading @@ -475,6 +475,7 @@ public class PackageParser { public final boolean extractNativeLibs; public final boolean isolatedSplits; public final boolean isSplitRequired; public final boolean preferCodeIntegrity; public ApkLite(String codePath, String packageName, String splitName, boolean isFeatureSplit, Loading @@ -483,7 +484,7 @@ public class PackageParser { int revisionCode, int installLocation, List<VerifierInfo> verifiers, SigningDetails signingDetails, boolean coreApp, boolean debuggable, boolean multiArch, boolean use32bitAbi, boolean extractNativeLibs, boolean isolatedSplits) { boolean preferCodeIntegrity, boolean extractNativeLibs, boolean isolatedSplits) { this.codePath = codePath; this.packageName = packageName; this.splitName = splitName; Loading @@ -500,6 +501,7 @@ public class PackageParser { this.debuggable = debuggable; this.multiArch = multiArch; this.use32bitAbi = use32bitAbi; this.preferCodeIntegrity = preferCodeIntegrity; this.extractNativeLibs = extractNativeLibs; this.isolatedSplits = isolatedSplits; this.isSplitRequired = isSplitRequired; Loading Loading @@ -1722,6 +1724,7 @@ public class PackageParser { boolean isolatedSplits = false; boolean isFeatureSplit = false; boolean isSplitRequired = false; boolean preferCodeIntegrity = false; String configForSplit = null; String usesSplitName = null; Loading Loading @@ -1784,6 +1787,9 @@ public class PackageParser { if ("extractNativeLibs".equals(attr)) { extractNativeLibs = attrs.getAttributeBooleanValue(i, true); } if ("preferCodeIntegrity".equals(attr)) { preferCodeIntegrity = attrs.getAttributeBooleanValue(i, false); } } } else if (TAG_USES_SPLIT.equals(parser.getName())) { if (usesSplitName != null) { Loading @@ -1800,10 +1806,16 @@ public class PackageParser { } } if (preferCodeIntegrity && extractNativeLibs) { throw new PackageParserException( PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, "Can't request both preferCodeIntegrity and extractNativeLibs"); } return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable, multiArch, use32bitAbi, extractNativeLibs, isolatedSplits); multiArch, use32bitAbi, preferCodeIntegrity, extractNativeLibs, isolatedSplits); } /** Loading Loading @@ -3654,6 +3666,12 @@ public class PackageParser { ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_preferCodeIntegrity, false)) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY; } if (sa.getBoolean( R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, false)) { Loading
core/res/res/values/attrs_manifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -1112,6 +1112,11 @@ resource] to be present in order to function. Default value is false. --> <attr name="isSplitRequired" format="boolean" /> <!-- Flag to specify if this app prioritizes code integrity. The system may choose to run with better integrity guarantee in various components if possible based on the app's <code>targetSdkVersion</code>. --> <attr name="preferCodeIntegrity" format="boolean" /> <!-- Extra options for an activity's UI. Applies to either the {@code <activity>} or {@code <application>} tag. If specified on the {@code <application>} tag these will be considered defaults for all activities in the Loading Loading @@ -1580,6 +1585,7 @@ to honor this flag as well. --> <attr name="usesCleartextTraffic" /> <attr name="multiArch" /> <attr name="preferCodeIntegrity" /> <attr name="extractNativeLibs" /> <attr name="defaultToDeviceProtectedStorage" format="boolean" /> <attr name="directBootAware" /> Loading
services/core/java/com/android/server/am/ProcessList.java +3 −2 Original line number Diff line number Diff line Loading @@ -1362,8 +1362,9 @@ public final class ProcessList { mService.mNativeDebuggingApp = null; } if (app.info.isPrivilegedApp() && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) { if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY) != 0 || (app.info.isPrivilegedApp() && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +11 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapter; import com.android.server.pm.dex.DexManager; import libcore.io.IoUtils; Loading Loading @@ -1594,6 +1595,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } if (baseApk.preferCodeIntegrity) { for (File file : mResolvedStagedFiles) { if (file.getName().endsWith(".apk") && !DexManager.auditUncompressedCodeInApk(file.getPath())) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Some code are not uncompressed and aligned correctly for " + mPackageName); } } } if (baseApk.isSplitRequired && stagedSplits.size() <= 1) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SPLIT, "Missing split for " + mPackageName); Loading