From 78dd4a737172afe98c25ad19dacc0106a6f5474a Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Wed, 4 Nov 2009 11:49:08 -0800 Subject: [PATCH] Fix #2176803 - restores from userdebug to user builds not working The underlying issue is that ordinarily, the restore mechanism checks the signature block of the package which uploaded the restore data against the signature of the package on-device that will be handling the restore. This is to ensure that the restore goes to the "same" application as the one that uploaded it. However, applications bundled on the system partition as part of the device build are signed not with a permanent, app-identifying signature, but rather with the device's signature block, which is different for each kind of device and potentially between kinds of build for the same device. That renders the stored backup data unusable when changing devices / builds / etc. This change works around the problem by explicitly privileging applications that reside on the system partition: they have been built into the device, and so are trusted to be able to handle data that is marked as coming from its package name. Change-Id: I561011bce2b54cff3e695e82e7544b126b6ac31e --- .../com/android/server/BackupManagerService.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 754e6e578b538..c3b591ee64f9c 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -1260,9 +1260,20 @@ class BackupManagerService extends IBackupManager.Stub { // ----- Restore handling ----- - private boolean signaturesMatch(Signature[] storedSigs, Signature[] deviceSigs) { + private boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) { + // If the target resides on the system partition, we allow it to restore + // data from the like-named package in a restore set even if the signatures + // do not match. (Unlike general applications, those flashed to the system + // partition will be signed with the device's platform certificate, so on + // different phones the same system app will have different signatures.) + if ((target.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + if (DEBUG) Log.v(TAG, "System app " + target.packageName + " - skipping sig check"); + return true; + } + // Allow unsigned apps, but not signed on one device and unsigned on the other // !!! TODO: is this the right policy? + Signature[] deviceSigs = target.signatures; if (DEBUG) Log.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs); if ((storedSigs == null || storedSigs.length == 0) @@ -1465,7 +1476,7 @@ class BackupManagerService extends IBackupManager.Stub { continue; } - if (!signaturesMatch(metaInfo.signatures, packageInfo.signatures)) { + if (!signaturesMatch(metaInfo.signatures, packageInfo)) { Log.w(TAG, "Signature mismatch restoring " + packageName); EventLog.writeEvent(RESTORE_AGENT_FAILURE_EVENT, packageName, "Signature mismatch");