Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +0 −42 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.DexManager; import com.android.server.pm.parsing.pkg.AndroidPackage; Loading Loading @@ -2357,28 +2356,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return; } // Check if APEX update is allowed. We do this check in handleInstall, since this is one of // the places that: // * Shared between staged and non-staged APEX update flows. // * Only is called after boot completes. // The later is important, since isApexUpdateAllowed check depends on the // ModuleInfoProvider, which is only populated after device has booted. if (isApexSession()) { boolean checkApexUpdateAllowed = (params.installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK) == 0; synchronized (mLock) { if (checkApexUpdateAllowed && !isApexUpdateAllowed(mPackageName, mInstallSource.installerPackageName)) { onSessionValidationFailure(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Update of APEX package " + mPackageName + " is not allowed for " + mInstallSource.installerPackageName); return; } } } if (params.isStaged) { // TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even // though ideally, we just need to send session committed broadcast. Loading Loading @@ -2825,25 +2802,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return sessionContains((s) -> !s.isApexSession()); } private boolean isApexUpdateAllowed(String apexPackageName, String installerPackageName) { if (mPm.getModuleInfo(apexPackageName, 0) != null) { final String modulesInstaller = SystemConfig.getInstance().getModulesInstallerPackageName(); if (modulesInstaller == null) { Slog.w(TAG, "No modules installer defined"); return false; } return modulesInstaller.equals(installerPackageName); } final String vendorApexInstaller = SystemConfig.getInstance().getAllowedVendorApexes().get(apexPackageName); if (vendorApexInstaller == null) { Slog.w(TAG, apexPackageName + " is not allowed to be updated"); return false; } return vendorApexInstaller.equals(installerPackageName); } /** * Validate apex install. * <p> Loading services/core/java/com/android/server/pm/PackageSessionVerifier.java +48 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.apk.ApkSignatureVerifier; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageHelper; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.rollback.RollbackManagerInternal; Loading Loading @@ -99,9 +100,11 @@ final class PackageSessionVerifier { storeSession(session.mStagedSession); if (session.isMultiPackage()) { for (PackageInstallerSession child : session.getChildSessions()) { checkApexUpdateAllowed(child); checkRebootlessApex(child); } } else { checkApexUpdateAllowed(session); checkRebootlessApex(session); } verifyAPK(session, callback); Loading Loading @@ -461,6 +464,51 @@ final class PackageSessionVerifier { return mApexManager.abortStagedSession(sessionId); } private boolean isApexUpdateAllowed(String apexPackageName, String installerPackageName) { if (mPm.getModuleInfo(apexPackageName, 0) != null) { final String modulesInstaller = SystemConfig.getInstance().getModulesInstallerPackageName(); if (modulesInstaller == null) { Slog.w(TAG, "No modules installer defined"); return false; } return modulesInstaller.equals(installerPackageName); } final String vendorApexInstaller = SystemConfig.getInstance().getAllowedVendorApexes().get(apexPackageName); if (vendorApexInstaller == null) { Slog.w(TAG, apexPackageName + " is not allowed to be updated"); return false; } return vendorApexInstaller.equals(installerPackageName); } /** * Checks if APEX update is allowed. * * This phase is shared between staged and non-staged sessions and should be called after * boot is completed since this check depends on the ModuleInfoProvider, which is only populated * after device has booted. */ private void checkApexUpdateAllowed(PackageInstallerSession session) throws PackageManagerException { if (!session.isApexSession()) { return; } final int installFlags = session.params.installFlags; if ((installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK) != 0) { return; } final String packageName = session.getPackageName(); final String installerPackageName = session.getInstallSource().installerPackageName; if (!isApexUpdateAllowed(packageName, installerPackageName)) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Update of APEX package " + packageName + " is not allowed for " + installerPackageName); } } /** * Fails this rebootless APEX session if the same package name found in any staged sessions. */ Loading tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java +24 −12 Original line number Diff line number Diff line Loading @@ -303,11 +303,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); } @Test Loading @@ -315,11 +318,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false)); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false)); } @Test Loading @@ -327,11 +333,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); } @Test Loading @@ -339,11 +348,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false)); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false)); } @Test Loading Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +0 −42 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.DexManager; import com.android.server.pm.parsing.pkg.AndroidPackage; Loading Loading @@ -2357,28 +2356,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return; } // Check if APEX update is allowed. We do this check in handleInstall, since this is one of // the places that: // * Shared between staged and non-staged APEX update flows. // * Only is called after boot completes. // The later is important, since isApexUpdateAllowed check depends on the // ModuleInfoProvider, which is only populated after device has booted. if (isApexSession()) { boolean checkApexUpdateAllowed = (params.installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK) == 0; synchronized (mLock) { if (checkApexUpdateAllowed && !isApexUpdateAllowed(mPackageName, mInstallSource.installerPackageName)) { onSessionValidationFailure(PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Update of APEX package " + mPackageName + " is not allowed for " + mInstallSource.installerPackageName); return; } } } if (params.isStaged) { // TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even // though ideally, we just need to send session committed broadcast. Loading Loading @@ -2825,25 +2802,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return sessionContains((s) -> !s.isApexSession()); } private boolean isApexUpdateAllowed(String apexPackageName, String installerPackageName) { if (mPm.getModuleInfo(apexPackageName, 0) != null) { final String modulesInstaller = SystemConfig.getInstance().getModulesInstallerPackageName(); if (modulesInstaller == null) { Slog.w(TAG, "No modules installer defined"); return false; } return modulesInstaller.equals(installerPackageName); } final String vendorApexInstaller = SystemConfig.getInstance().getAllowedVendorApexes().get(apexPackageName); if (vendorApexInstaller == null) { Slog.w(TAG, apexPackageName + " is not allowed to be updated"); return false; } return vendorApexInstaller.equals(installerPackageName); } /** * Validate apex install. * <p> Loading
services/core/java/com/android/server/pm/PackageSessionVerifier.java +48 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.util.apk.ApkSignatureVerifier; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageHelper; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.rollback.RollbackManagerInternal; Loading Loading @@ -99,9 +100,11 @@ final class PackageSessionVerifier { storeSession(session.mStagedSession); if (session.isMultiPackage()) { for (PackageInstallerSession child : session.getChildSessions()) { checkApexUpdateAllowed(child); checkRebootlessApex(child); } } else { checkApexUpdateAllowed(session); checkRebootlessApex(session); } verifyAPK(session, callback); Loading Loading @@ -461,6 +464,51 @@ final class PackageSessionVerifier { return mApexManager.abortStagedSession(sessionId); } private boolean isApexUpdateAllowed(String apexPackageName, String installerPackageName) { if (mPm.getModuleInfo(apexPackageName, 0) != null) { final String modulesInstaller = SystemConfig.getInstance().getModulesInstallerPackageName(); if (modulesInstaller == null) { Slog.w(TAG, "No modules installer defined"); return false; } return modulesInstaller.equals(installerPackageName); } final String vendorApexInstaller = SystemConfig.getInstance().getAllowedVendorApexes().get(apexPackageName); if (vendorApexInstaller == null) { Slog.w(TAG, apexPackageName + " is not allowed to be updated"); return false; } return vendorApexInstaller.equals(installerPackageName); } /** * Checks if APEX update is allowed. * * This phase is shared between staged and non-staged sessions and should be called after * boot is completed since this check depends on the ModuleInfoProvider, which is only populated * after device has booted. */ private void checkApexUpdateAllowed(PackageInstallerSession session) throws PackageManagerException { if (!session.isApexSession()) { return; } final int installFlags = session.params.installFlags; if ((installFlags & PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK) != 0) { return; } final String packageName = session.getPackageName(); final String installerPackageName = session.getInstallSource().installerPackageName; if (!isApexUpdateAllowed(packageName, installerPackageName)) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Update of APEX package " + packageName + " is not allowed for " + installerPackageName); } } /** * Fails this rebootless APEX session if the same package name found in any staged sessions. */ Loading
tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java +24 −12 Original line number Diff line number Diff line Loading @@ -303,11 +303,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); } @Test Loading @@ -315,11 +318,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false)); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false)); } @Test Loading @@ -327,11 +333,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false).setStaged()); } @Test Loading @@ -339,11 +348,14 @@ public class StagedInstallInternalTest { assertThat(InstallUtils.getInstalledVersion("test.apex.rebootless")).isEqualTo(1); TestApp apex = new TestApp("apex", "test.apex.rebootless", 2, /* isApex= */ true, "test.rebootless_apex_v2.apex"); String expectedFailMessage = "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal"; InstallUtils.commitExpectingFailure( AssertionError.class, "Update of APEX package test.apex.rebootless is not allowed " + "for com.android.tests.stagedinstallinternal", AssertionError.class, expectedFailMessage, Install.single(apex).setBypassAllowedApexUpdateCheck(false)); InstallUtils.commitExpectingFailure( AssertionError.class, expectedFailMessage, Install.multi(apex).setBypassAllowedApexUpdateCheck(false)); } @Test Loading