diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/StagingManager.java | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 6d3424cf3942..dd1eb8355de1 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -35,7 +35,6 @@ import android.content.pm.PackageParser.PackageParserException; import android.content.pm.PackageParser.SigningDetails; import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion; import android.content.pm.ParceledListSlice; -import android.content.pm.Signature; import android.content.rollback.IRollbackManager; import android.os.Bundle; import android.os.Handler; @@ -106,8 +105,19 @@ public class StagingManager { return new ParceledListSlice<>(result); } - private void validateApexSignature(String apexPath, String packageName) + /** + * Validates the signature used to sign the container of the new apex package + * + * @param newApexPkg The new apex package that is being installed + * @param installFlags flags related to the session + * @throws PackageManagerException + */ + private void validateApexSignature(PackageInfo newApexPkg, int installFlags) throws PackageManagerException { + // Get signing details of the new package + final String apexPath = newApexPkg.applicationInfo.sourceDir; + final String packageName = newApexPkg.packageName; + final SigningDetails signingDetails; try { signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR); @@ -116,9 +126,10 @@ public class StagingManager { "Failed to parse APEX package " + apexPath, e); } - final PackageInfo packageInfo = mApexManager.getPackageInfo(packageName, + // Get signing details of the existing package + final PackageInfo existingApexPkg = mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE); - if (packageInfo == null) { + if (existingApexPkg == null) { // This should never happen, because submitSessionToApexService ensures that no new // apexes were installed. throw new IllegalStateException("Unknown apex package " + packageName); @@ -127,22 +138,22 @@ public class StagingManager { final SigningDetails existingSigningDetails; try { existingSigningDetails = ApkSignatureVerifier.verify( - packageInfo.applicationInfo.sourceDir, SignatureSchemeVersion.JAR); + existingApexPkg.applicationInfo.sourceDir, SignatureSchemeVersion.JAR); } catch (PackageParserException e) { throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, - "Failed to parse APEX package " + packageInfo.applicationInfo.sourceDir, e); + "Failed to parse APEX package " + existingApexPkg.applicationInfo.sourceDir, e); } - // Now that we have both sets of signatures, demand that they're an exact match. - if (Signature.areExactMatch(existingSigningDetails.signatures, signingDetails.signatures)) { + // Verify signing details for upgrade + if (signingDetails.checkCapability(existingSigningDetails, + PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) { return; } throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, - "APK-container signature verification failed for package " - + packageName + ". Signature of file " - + apexPath + " does not match the signature of " - + " the package already installed."); + "APK-container signature of APEX package " + packageName + " with version " + + newApexPkg.versionCodeMajor + " and path " + apexPath + " is not" + + " compatible with the one currently installed on device"); } private List<PackageInfo> submitSessionToApexService( @@ -239,8 +250,7 @@ public class StagingManager { try { final List<PackageInfo> apexPackages = submitSessionToApexService(session); for (PackageInfo apexPackage : apexPackages) { - validateApexSignature(apexPackage.applicationInfo.sourceDir, - apexPackage.packageName); + validateApexSignature(apexPackage, session.params.installFlags); } } catch (PackageManagerException e) { session.setStagedSessionFailed(e.error, e.getMessage()); |