Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7eb1893c authored by Mohammad Samiul Islam's avatar Mohammad Samiul Islam
Browse files

Prevent exceptions in pre-reboot verification from crashing system server

An unhandled exception during pre-reboot verification will cause system
server to crash and restart. Upon restart, pre-reboot verification will
be retried and it will cause system server to crash again. Thus creating
a loop.

Instead of allowing the exception to crash the system server, we now
catch it and fail the corresponding staged session with appropriate
message.

Bug: 170784748
Test: manual
Test: verified that without this fix, any unhandled exception sends
system server into a crash loop

Change-Id: Ie3343681601c072add0b2d50cbaa2e088a27d94b
Merged-In: If100796687906be67bc02ea63a78e1b6e291ce7a
(cherry picked from commit 5a2548589560404f9fce4914216564b0333895d4)
parent e7069bce
Loading
Loading
Loading
Loading
+70 −63
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ public class StagingManager {
    }

    private void preRebootVerification(@NonNull PackageInstallerSession session) {
        try {
            boolean success = true;

            final ApexInfoList apexInfoList = new ApexInfoList();
@@ -247,11 +248,12 @@ public class StagingManager {
                for (ApexInfo apexPackage : apexInfoList.apexInfos) {
                    if (!validateApexSignature(apexPackage.packagePath,
                            apexPackage.packageName)) {
                    session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                        session.setStagedSessionFailed(
                                SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                                "APK-container signature verification failed for package "
                                        + apexPackage.packageName + ". Signature of file "
                                    + apexPackage.packagePath + " does not match the signature of "
                                    + " the package already installed.");
                                        + apexPackage.packagePath + " does not match the signature"
                                        + " of the package already installed.");
                        // TODO(b/118865310): abort the session on apexd.
                        return;
                    }
@@ -260,8 +262,8 @@ public class StagingManager {

            if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
                // If rollback is enabled for this session, we call through to the RollbackManager
            // with the list of sessions it must enable rollback for. Note that notifyStagedSession
            // is a synchronous operation.
                // with the list of sessions it must enable rollback for. Note that
                // notifyStagedSession is a synchronous operation.
                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
                try {
@@ -282,6 +284,11 @@ public class StagingManager {
                        "APEX staging failed, check logcat messages from apexd for more "
                                + "details.");
            }
        } catch (Exception e) {
            Slog.e(TAG, "Pre-reboot verification failed due to unhandled exception", e);
            session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                    "Pre-reboot verification failed due to unhandled exception: " + e);
        }
    }