From a858cb075d0c87e2965d401656ff2d5bc16406da Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Fri, 3 Jun 2011 12:27:51 -0700 Subject: [PATCH] Respect android:allowBackup="false" during full backup & restore Packages with this manifest attribute set 'false' will not be backed up even through the "full device backup" infrastructure. If someone produces an apparent restore file with data for such an application, it will not actually be restored onto the device. When an apk is installed during the course of a restore operation, it is validated against the manifest contents and deleted if there is a mismatch. Also, if the newly-installed app is found to disallow backups, no file content will be processed for that app. Bug 4532159 Change-Id: I59630054584b1394e567de939192e22e597044ee --- .../AndroidManifest.xml | 2 +- .../android/server/BackupManagerService.java | 139 +++++++++++++++--- 2 files changed, 119 insertions(+), 22 deletions(-) diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml index ed9a51945f25d..19848f611e774 100644 --- a/packages/BackupRestoreConfirmation/AndroidManifest.xml +++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml @@ -21,7 +21,7 @@ 0) { - sigs = new Signature[numSigs]; + Signature[] sigs = new Signature[numSigs]; for (int i = 0; i < numSigs; i++) { offset = extractLine(buffer, offset, str); sigs[i] = new Signature(str[0]); } + mManifestSignatures.put(info.packageName, sigs); // Okay, got the manifest info we need... try { - // Verify signatures against any installed version; if they - // don't match, then we fall though and ignore the data. The - // signatureMatch() method explicitly ignores the signature - // check for packages installed on the system partition, because - // such packages are signed with the platform cert instead of - // the app developer's cert, so they're different on every - // device. PackageInfo pkgInfo = mPackageManager.getPackageInfo( info.packageName, PackageManager.GET_SIGNATURES); - if (signaturesMatch(sigs, pkgInfo)) { - if (pkgInfo.versionCode >= version) { - Slog.i(TAG, "Sig + version match; taking data"); - policy = RestorePolicy.ACCEPT; + // Fall through to IGNORE if the app explicitly disallows backup + final int flags = pkgInfo.applicationInfo.flags; + if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) { + // Verify signatures against any installed version; if they + // don't match, then we fall though and ignore the data. The + // signatureMatch() method explicitly ignores the signature + // check for packages installed on the system partition, because + // such packages are signed with the platform cert instead of + // the app developer's cert, so they're different on every + // device. + if (signaturesMatch(sigs, pkgInfo)) { + if (pkgInfo.versionCode >= version) { + Slog.i(TAG, "Sig + version match; taking data"); + policy = RestorePolicy.ACCEPT; + } else { + // The data is from a newer version of the app than + // is presently installed. That means we can only + // use it if the matching apk is also supplied. + Slog.d(TAG, "Data version " + version + + " is newer than installed version " + + pkgInfo.versionCode + " - requiring apk"); + policy = RestorePolicy.ACCEPT_IF_APK; + } } else { - // The data is from a newer version of the app than - // is presently installed. That means we can only - // use it if the matching apk is also supplied. - Slog.d(TAG, "Data version " + version - + " is newer than installed version " - + pkgInfo.versionCode + " - requiring apk"); - policy = RestorePolicy.ACCEPT_IF_APK; + Slog.w(TAG, "Restore manifest signatures do not match " + + "installed application for " + info.packageName); } + } else { + if (DEBUG) Slog.i(TAG, "Restore manifest from " + + info.packageName + " but allowBackup=false"); } } catch (NameNotFoundException e) { // Okay, the target app isn't installed. We can process