diff options
author | Christopher Tate <ctate@google.com> | 2012-10-15 19:20:25 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2012-10-17 13:36:15 -0700 |
commit | 346acb123dd87396726941b484be6fdd5cd4ea44 (patch) | |
tree | c5e247777d848bf67125efb212c031d5d960995d /services | |
parent | 69b0c974b5abb38a4443410cf09f7d5f28cf2c7f (diff) | |
download | frameworks_base-346acb123dd87396726941b484be6fdd5cd4ea44.zip frameworks_base-346acb123dd87396726941b484be6fdd5cd4ea44.tar.gz frameworks_base-346acb123dd87396726941b484be6fdd5cd4ea44.tar.bz2 |
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
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 61 |
2 files changed, 40 insertions, 24 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 9f01eca..f241c80 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -1474,6 +1474,7 @@ class BackupManagerService extends IBackupManager.Stub { if (MORE_DEBUG) Slog.v(TAG, " removing participant " + packageName); removeEverBackedUp(packageName); set.remove(packageName); + mPendingBackups.remove(packageName); } } @@ -1625,6 +1626,7 @@ class BackupManagerService extends IBackupManager.Stub { } catch (InterruptedException e) { // just bail if (DEBUG) Slog.w(TAG, "Interrupted: " + e); + mActivityManager.clearPendingBackup(); return null; } } @@ -1632,6 +1634,7 @@ class BackupManagerService extends IBackupManager.Stub { // if we timed out with no connect, abort and move on if (mConnecting == true) { Slog.w(TAG, "Timeout waiting for agent " + app); + mActivityManager.clearPendingBackup(); return null; } if (DEBUG) Slog.i(TAG, "got agent " + mConnectedAgent); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 7132e1e..1737876 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -11119,8 +11119,8 @@ public final class ActivityManagerService extends ActivityManagerNative // instantiated. The backup agent will invoke backupAgentCreated() on the // activity manager to announce its creation. public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { - if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); - enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); + if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); + enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); synchronized(this) { // !!! TODO: currently no check here that we're already bound @@ -11181,6 +11181,17 @@ public final class ActivityManagerService extends ActivityManagerNative 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 public void backupAgentCreated(String agentPackageName, IBinder agent) { if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName @@ -11217,32 +11228,34 @@ public final class ActivityManagerService extends ActivityManagerNative } synchronized(this) { - if (mBackupAppName == null) { - Slog.w(TAG, "Unbinding backup agent with no active backup"); - return; - } - - if (!mBackupAppName.equals(appInfo.packageName)) { - Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); - return; - } + try { + if (mBackupAppName == null) { + Slog.w(TAG, "Unbinding backup agent with no active backup"); + return; + } - ProcessRecord proc = mBackupTarget.app; - mBackupTarget = null; - mBackupAppName = null; + if (!mBackupAppName.equals(appInfo.packageName)) { + Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); + return; + } - // Not backing this app up any more; reset its OOM adjustment - updateOomAdjLocked(proc); + // Not backing this app up any more; reset its OOM adjustment + final ProcessRecord proc = mBackupTarget.app; + updateOomAdjLocked(proc); - // If the app crashed during backup, 'thread' will be null here - if (proc.thread != null) { - try { - proc.thread.scheduleDestroyBackupAgent(appInfo, - compatibilityInfoForPackageLocked(appInfo)); - } catch (Exception e) { - Slog.e(TAG, "Exception when unbinding backup agent:"); - e.printStackTrace(); + // If the app crashed during backup, 'thread' will be null here + if (proc.thread != null) { + try { + proc.thread.scheduleDestroyBackupAgent(appInfo, + compatibilityInfoForPackageLocked(appInfo)); + } catch (Exception e) { + Slog.e(TAG, "Exception when unbinding backup agent:"); + e.printStackTrace(); + } } + } finally { + mBackupTarget = null; + mBackupAppName = null; } } } |