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

Commit 346acb12 authored by Christopher Tate's avatar Christopher Tate
Browse files

Sanity-check erroneous backup agent instantiations

Two distinct changes:

Fix a bug seen in the wild where a newly-launched application will be
spuriously asked to instantiate a backup agent.  What was happening
there is that some Activity Manager state was being left stale in certain
circumstances, and then in combination with app uninstall / install, there
could be a case where uid reuse wound up looking like an app identity
match.

We now positively verify before instantiating the agent that the intended
backup target package is uid-compatible with the app process that the
instantiation was requested of.  The incomplete bookkeeping in the
Activity Manager has also been tightened up, and the Backup Manager is
more aggressive about cleaning up pending operations pertaining to
apps being uninstalled.

Bug 5874010

Change-Id: Ic389f4a96c9dcd0ba6b3962b579084033d8ae9f8
parent 69b0c974
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -2809,6 +2809,15 @@ class ActivityManagerProxy implements IActivityManager
        return success;
        return success;
    }
    }


    public void clearPendingBackup() throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        mRemote.transact(CLEAR_PENDING_BACKUP_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException {
    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        Parcel reply = Parcel.obtain();
+20 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageManager;
import android.content.pm.InstrumentationInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.content.pm.ProviderInfo;
@@ -2396,12 +2397,31 @@ public final class ActivityThread {
    private void handleCreateBackupAgent(CreateBackupAgentData data) {
    private void handleCreateBackupAgent(CreateBackupAgentData data) {
        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);


        // Sanity check the requested target package's uid against ours
        try {
            PackageInfo requestedPackage = getPackageManager().getPackageInfo(
                    data.appInfo.packageName, 0, UserHandle.myUserId());
            if (requestedPackage.applicationInfo.uid != Process.myUid()) {
                Slog.w(TAG, "Asked to instantiate non-matching package "
                        + data.appInfo.packageName);
                return;
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Can't reach package manager", e);
            return;
        }

        // no longer idle; we have backup work to do
        // no longer idle; we have backup work to do
        unscheduleGcIdler();
        unscheduleGcIdler();


        // instantiate the BackupAgent class named in the manifest
        // instantiate the BackupAgent class named in the manifest
        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
        String packageName = packageInfo.mPackageName;
        String packageName = packageInfo.mPackageName;
        if (packageName == null) {
            Slog.d(TAG, "Asked to create backup agent for nonexistent package");
            return;
        }

        if (mBackupAgents.get(packageName) != null) {
        if (mBackupAgents.get(packageName) != null) {
            Slog.d(TAG, "BackupAgent " + "  for " + packageName
            Slog.d(TAG, "BackupAgent " + "  for " + packageName
                    + " already exists");
                    + " already exists");
+2 −0
Original line number Original line Diff line number Diff line
@@ -152,6 +152,7 @@ public interface IActivityManager extends IInterface {
    
    
    public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
    public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
            throws RemoteException;
            throws RemoteException;
    public void clearPendingBackup() throws RemoteException;
    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
    public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
    public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
    public void killApplicationProcess(String processName, int uid) throws RemoteException;
    public void killApplicationProcess(String processName, int uid) throws RemoteException;
@@ -619,4 +620,5 @@ public interface IActivityManager extends IInterface {
    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
    int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
    int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
    int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
    int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
    int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -1474,6 +1474,7 @@ class BackupManagerService extends IBackupManager.Stub {
            if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + packageName);
            if (MORE_DEBUG) Slog.v(TAG, "  removing participant " + packageName);
            removeEverBackedUp(packageName);
            removeEverBackedUp(packageName);
            set.remove(packageName);
            set.remove(packageName);
            mPendingBackups.remove(packageName);
        }
        }
    }
    }


@@ -1625,6 +1626,7 @@ class BackupManagerService extends IBackupManager.Stub {
                        } catch (InterruptedException e) {
                        } catch (InterruptedException e) {
                            // just bail
                            // just bail
                            if (DEBUG) Slog.w(TAG, "Interrupted: " + e);
                            if (DEBUG) Slog.w(TAG, "Interrupted: " + e);
                            mActivityManager.clearPendingBackup();
                            return null;
                            return null;
                        }
                        }
                    }
                    }
@@ -1632,6 +1634,7 @@ class BackupManagerService extends IBackupManager.Stub {
                    // if we timed out with no connect, abort and move on
                    // if we timed out with no connect, abort and move on
                    if (mConnecting == true) {
                    if (mConnecting == true) {
                        Slog.w(TAG, "Timeout waiting for agent " + app);
                        Slog.w(TAG, "Timeout waiting for agent " + app);
                        mActivityManager.clearPendingBackup();
                        return null;
                        return null;
                    }
                    }
                    if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent);
                    if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent);
+37 −24
Original line number Original line Diff line number Diff line
@@ -11119,8 +11119,8 @@ public final class ActivityManagerService extends ActivityManagerNative
    // instantiated.  The backup agent will invoke backupAgentCreated() on the
    // instantiated.  The backup agent will invoke backupAgentCreated() on the
    // activity manager to announce its creation.
    // activity manager to announce its creation.
    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
        synchronized(this) {
        synchronized(this) {
            // !!! TODO: currently no check here that we're already bound
            // !!! TODO: currently no check here that we're already bound
@@ -11181,6 +11181,17 @@ public final class ActivityManagerService extends ActivityManagerNative
        return true;
        return true;
    }
    }
    @Override
    public void clearPendingBackup() {
        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
        synchronized (this) {
            mBackupTarget = null;
            mBackupAppName = null;
        }
    }
    // A backup agent has just come up                    
    // A backup agent has just come up                    
    public void backupAgentCreated(String agentPackageName, IBinder agent) {
    public void backupAgentCreated(String agentPackageName, IBinder agent) {
        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
@@ -11217,6 +11228,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        }
        synchronized(this) {
        synchronized(this) {
            try {
                if (mBackupAppName == null) {
                if (mBackupAppName == null) {
                    Slog.w(TAG, "Unbinding backup agent with no active backup");
                    Slog.w(TAG, "Unbinding backup agent with no active backup");
                    return;
                    return;
@@ -11227,11 +11239,8 @@ public final class ActivityManagerService extends ActivityManagerNative
                    return;
                    return;
                }
                }
            ProcessRecord proc = mBackupTarget.app;
            mBackupTarget = null;
            mBackupAppName = null;
                // Not backing this app up any more; reset its OOM adjustment
                // Not backing this app up any more; reset its OOM adjustment
                final ProcessRecord proc = mBackupTarget.app;
                updateOomAdjLocked(proc);
                updateOomAdjLocked(proc);
                // If the app crashed during backup, 'thread' will be null here
                // If the app crashed during backup, 'thread' will be null here
@@ -11244,6 +11253,10 @@ public final class ActivityManagerService extends ActivityManagerNative
                        e.printStackTrace();
                        e.printStackTrace();
                    }
                    }
                }
                }
            } finally {
                mBackupTarget = null;
                mBackupAppName = null;
            }
        }
        }
    }
    }
    // =========================================================
    // =========================================================