diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageInstallerSession.java | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 9edbaa8fadd9..2bf4b377bdd3 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_INSTA import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_UPDATED_BY_DO; import static android.content.pm.DataLoaderType.INCREMENTAL; import static android.content.pm.DataLoaderType.STREAMING; +import static android.content.pm.Flags.cloudCompilationVerification; import static android.content.pm.PackageInstaller.LOCATION_DATA_APP; import static android.content.pm.PackageInstaller.UNARCHIVAL_OK; import static android.content.pm.PackageInstaller.UNARCHIVAL_STATUS_UNSET; @@ -3570,6 +3571,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { CollectionUtils.addAll(stagedSplitTypes, apk.getSplitTypes()); } + if (cloudCompilationVerification()) { + verifySdmSignatures(artManagedFilePaths, mSigningDetails); + } + if (removeSplitList.size() > 0) { if (pkgInfo == null) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, @@ -3934,6 +3939,14 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { File targetArtManagedFile = new File( ArtManagedInstallFileHelper.getTargetPathForApk(path, targetFile.getPath())); stageFileLocked(artManagedFile, targetArtManagedFile); + if (!artManagedFile.equals(targetArtManagedFile)) { + // The file has been renamed. Update the list to reflect the change. + for (int i = 0; i < artManagedFilePaths.size(); ++i) { + if (artManagedFilePaths.get(i).equals(path)) { + artManagedFilePaths.set(i, targetArtManagedFile.getAbsolutePath()); + } + } + } } } @@ -4262,6 +4275,37 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } /** + * Verifies the signatures of SDM files. + * + * SDM is a file format that contains the cloud compilation artifacts. As a requirement, the SDM + * file should be signed with the same key as the APK. + * + * TODO(b/377474232): Move this logic to ART Service. + */ + private static void verifySdmSignatures(List<String> artManagedFilePaths, + SigningDetails expectedSigningDetails) throws PackageManagerException { + ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); + for (String path : artManagedFilePaths) { + if (!path.endsWith(".sdm")) { + continue; + } + // SDM is a format introduced in Android 16, so we don't need to support older + // signature schemes. + int minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3; + ParseResult<SigningDetails> verified = + ApkSignatureVerifier.verify(input, path, minSignatureScheme); + if (verified.isError()) { + throw new PackageManagerException( + INSTALL_FAILED_INVALID_APK, "Failed to verify SDM signatures"); + } + if (!expectedSigningDetails.signaturesMatchExactly(verified.getResult())) { + throw new PackageManagerException( + INSTALL_FAILED_INVALID_APK, "SDM signatures are inconsistent with APK"); + } + } + } + + /** * @return the uid of the owner this session */ public int getInstallerUid() { |