summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2012-10-15 19:20:25 -0700
committerChristopher Tate <ctate@google.com>2012-10-17 13:36:15 -0700
commit346acb123dd87396726941b484be6fdd5cd4ea44 (patch)
treec5e247777d848bf67125efb212c031d5d960995d /services
parent69b0c974b5abb38a4443410cf09f7d5f28cf2c7f (diff)
downloadframeworks_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.java3
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java61
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;
}
}
}