Skip to content

Commit 3f91e43

Browse files
Christopher TateAndroid (Google) Code Review
authored andcommitted
Merge "Full (local) restore security changes" into jb-mr1-dev
2 parents 41148af + f6d6fa8 commit 3f91e43

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

core/java/android/app/backup/FullBackup.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ static public native int backupToTar(String packageName, String domain,
6464

6565
/**
6666
* Copy data from a socket to the given File location on permanent storage. The
67-
* modification time and access mode of the resulting file will be set if desired.
67+
* modification time and access mode of the resulting file will be set if desired,
68+
* although group/all rwx modes will be stripped: the restored file will not be
69+
* accessible from outside the target application even if the original file was.
6870
* If the {@code type} parameter indicates that the result should be a directory,
6971
* the socket parameter may be {@code null}; even if it is valid, no data will be
7072
* read from it in this case.
@@ -79,8 +81,9 @@ static public native int backupToTar(String packageName, String domain,
7981
* @param type Must be either {@link BackupAgent#TYPE_FILE} for ordinary file data
8082
* or {@link BackupAgent#TYPE_DIRECTORY} for a directory.
8183
* @param mode Unix-style file mode (as used by the chmod(2) syscall) to be set on
82-
* the output file or directory. If this parameter is negative then neither
83-
* the mode nor the mtime parameters will be used.
84+
* the output file or directory. group/all rwx modes are stripped even if set
85+
* in this parameter. If this parameter is negative then neither
86+
* the mode nor the mtime values will be applied to the restored file.
8487
* @param mtime A timestamp in the standard Unix epoch that will be imposed as the
8588
* last modification time of the output file. if the {@code mode} parameter is
8689
* negative then this parameter will be ignored.
@@ -105,8 +108,6 @@ static public void restoreFile(ParcelFileDescriptor data,
105108
if (!parent.exists()) {
106109
// in practice this will only be for the default semantic directories,
107110
// and using the default mode for those is appropriate.
108-
// TODO: support the edge case of apps that have adjusted the
109-
// permissions on these core directories
110111
parent.mkdirs();
111112
}
112113
out = new FileOutputStream(outFile);
@@ -146,6 +147,8 @@ static public void restoreFile(ParcelFileDescriptor data,
146147
// Now twiddle the state to match the backup, assuming all went well
147148
if (mode >= 0 && outFile != null) {
148149
try {
150+
// explicitly prevent emplacement of files accessible by outside apps
151+
mode &= 0700;
149152
Libcore.os.chmod(outFile.getPath(), (int)mode);
150153
} catch (ErrnoException e) {
151154
e.rethrowAsIOException();

services/java/com/android/server/BackupManagerService.java

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,21 @@ public void run() {
24512451
}
24522452
}
24532453

2454+
// Cull any packages that run as system-domain uids but do not define their
2455+
// own backup agents
2456+
for (int i = 0; i < packagesToBackup.size(); ) {
2457+
PackageInfo pkg = packagesToBackup.get(i);
2458+
if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
2459+
&& (pkg.applicationInfo.backupAgentName == null)) {
2460+
if (MORE_DEBUG) {
2461+
Slog.i(TAG, "... ignoring non-agent system package " + pkg.packageName);
2462+
}
2463+
packagesToBackup.remove(i);
2464+
} else {
2465+
i++;
2466+
}
2467+
}
2468+
24542469
FileOutputStream ofstream = new FileOutputStream(mOutputFile.getFileDescriptor());
24552470
OutputStream out = null;
24562471

@@ -3669,29 +3684,37 @@ RestorePolicy readAppManifest(FileMetadata info, InputStream instream)
36693684
// Fall through to IGNORE if the app explicitly disallows backup
36703685
final int flags = pkgInfo.applicationInfo.flags;
36713686
if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
3672-
// Verify signatures against any installed version; if they
3673-
// don't match, then we fall though and ignore the data. The
3674-
// signatureMatch() method explicitly ignores the signature
3675-
// check for packages installed on the system partition, because
3676-
// such packages are signed with the platform cert instead of
3677-
// the app developer's cert, so they're different on every
3678-
// device.
3679-
if (signaturesMatch(sigs, pkgInfo)) {
3680-
if (pkgInfo.versionCode >= version) {
3681-
Slog.i(TAG, "Sig + version match; taking data");
3682-
policy = RestorePolicy.ACCEPT;
3687+
// Restore system-uid-space packages only if they have
3688+
// defined a custom backup agent
3689+
if ((pkgInfo.applicationInfo.uid >= Process.FIRST_APPLICATION_UID)
3690+
|| (pkgInfo.applicationInfo.backupAgentName != null)) {
3691+
// Verify signatures against any installed version; if they
3692+
// don't match, then we fall though and ignore the data. The
3693+
// signatureMatch() method explicitly ignores the signature
3694+
// check for packages installed on the system partition, because
3695+
// such packages are signed with the platform cert instead of
3696+
// the app developer's cert, so they're different on every
3697+
// device.
3698+
if (signaturesMatch(sigs, pkgInfo)) {
3699+
if (pkgInfo.versionCode >= version) {
3700+
Slog.i(TAG, "Sig + version match; taking data");
3701+
policy = RestorePolicy.ACCEPT;
3702+
} else {
3703+
// The data is from a newer version of the app than
3704+
// is presently installed. That means we can only
3705+
// use it if the matching apk is also supplied.
3706+
Slog.d(TAG, "Data version " + version
3707+
+ " is newer than installed version "
3708+
+ pkgInfo.versionCode + " - requiring apk");
3709+
policy = RestorePolicy.ACCEPT_IF_APK;
3710+
}
36833711
} else {
3684-
// The data is from a newer version of the app than
3685-
// is presently installed. That means we can only
3686-
// use it if the matching apk is also supplied.
3687-
Slog.d(TAG, "Data version " + version
3688-
+ " is newer than installed version "
3689-
+ pkgInfo.versionCode + " - requiring apk");
3690-
policy = RestorePolicy.ACCEPT_IF_APK;
3712+
Slog.w(TAG, "Restore manifest signatures do not match "
3713+
+ "installed application for " + info.packageName);
36913714
}
36923715
} else {
3693-
Slog.w(TAG, "Restore manifest signatures do not match "
3694-
+ "installed application for " + info.packageName);
3716+
Slog.w(TAG, "Package " + info.packageName
3717+
+ " is system level with no agent");
36953718
}
36963719
} else {
36973720
if (DEBUG) Slog.i(TAG, "Restore manifest from "

0 commit comments

Comments
 (0)