Skip to content

Commit 9b8c6d2

Browse files
Christopher TateThe Android Automerger
authored andcommitted
Backport of backup transport whitelist
Sysconfig define a whitelist of permitted backup transports Previously any apk bundled in priv-app could insert a backup transport. Reduce risk surface by giving the OEM explicit control over who is allowed to handle backup data. Bug 28406080 Backport of 494df79 from N Change-Id: I9f90e324169a68720d608f74754d284a7e59cf87
1 parent d2ef34d commit 9b8c6d2

2 files changed

Lines changed: 51 additions & 7 deletions

File tree

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

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@
8080
import android.provider.Settings;
8181
import android.system.ErrnoException;
8282
import android.system.Os;
83+
import android.text.TextUtils;
8384
import android.util.ArrayMap;
85+
import android.util.ArraySet;
8486
import android.util.AtomicFile;
8587
import android.util.EventLog;
8688
import android.util.Log;
@@ -93,6 +95,7 @@
9395
import com.android.internal.backup.IObbBackupService;
9496
import com.android.server.AppWidgetBackupBridge;
9597
import com.android.server.EventLogTags;
98+
import com.android.server.SystemConfig;
9699
import com.android.server.SystemService;
97100
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
98101

@@ -300,6 +303,7 @@ public String toString() {
300303
volatile boolean mClearingData;
301304

302305
// Transport bookkeeping
306+
final ArraySet<ComponentName> mTransportWhitelist;
303307
final Intent mTransportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
304308
final ArrayMap<String,String> mTransportNames
305309
= new ArrayMap<String,String>(); // component name -> registration name
@@ -1084,11 +1088,15 @@ public BackupManagerService(Context context, Trampoline parent) {
10841088

10851089
// Set up our transport options and initialize the default transport
10861090
// TODO: Don't create transports that we don't need to?
1087-
mCurrentTransport = Settings.Secure.getString(context.getContentResolver(),
1091+
SystemConfig systemConfig = SystemConfig.getInstance();
1092+
mTransportWhitelist = systemConfig.getBackupTransportWhitelist();
1093+
1094+
String transport = Settings.Secure.getString(context.getContentResolver(),
10881095
Settings.Secure.BACKUP_TRANSPORT);
1089-
if ("".equals(mCurrentTransport)) {
1090-
mCurrentTransport = null;
1096+
if (TextUtils.isEmpty(transport)) {
1097+
transport = null;
10911098
}
1099+
mCurrentTransport = transport;
10921100
if (DEBUG) Slog.v(TAG, "Starting with transport " + mCurrentTransport);
10931101

10941102
// Find all transport hosts and bind to their services
@@ -1099,11 +1107,11 @@ public BackupManagerService(Context context, Trampoline parent) {
10991107
}
11001108
if (hosts != null) {
11011109
for (int i = 0; i < hosts.size(); i++) {
1102-
final ServiceInfo transport = hosts.get(i).serviceInfo;
1110+
final ServiceInfo transportService = hosts.get(i).serviceInfo;
11031111
if (MORE_DEBUG) {
1104-
Slog.v(TAG, " " + transport.packageName + "/" + transport.name);
1112+
Slog.v(TAG, " " + transportService.packageName + "/" + transportService.name);
11051113
}
1106-
tryBindTransport(transport);
1114+
tryBindTransport(transportService);
11071115
}
11081116
}
11091117

@@ -1983,7 +1991,12 @@ boolean tryBindTransport(ServiceInfo info) {
19831991
// Actually bind; presumes that we have already validated the transport service
19841992
boolean bindTransport(ServiceInfo transport) {
19851993
ComponentName svcName = new ComponentName(transport.packageName, transport.name);
1986-
if (MORE_DEBUG) {
1994+
if (!mTransportWhitelist.contains(svcName)) {
1995+
Slog.w(TAG, "Proposed transport " + svcName + " not whitelisted; ignoring");
1996+
return false;
1997+
}
1998+
1999+
if (DEBUG) {
19872000
Slog.i(TAG, "Binding to transport host " + svcName);
19882001
}
19892002
Intent intent = new Intent(mTransportServiceIntent);
@@ -9636,6 +9649,12 @@ private void dumpInternal(PrintWriter pw) {
96369649
+ " (now = " + System.currentTimeMillis() + ')');
96379650
pw.println(" next scheduled: " + KeyValueBackupJob.nextScheduled());
96389651

9652+
pw.println("Transport whitelist:");
9653+
for (ComponentName transport : mTransportWhitelist) {
9654+
pw.print(" ");
9655+
pw.println(transport.flattenToShortString());
9656+
}
9657+
96399658
pw.println("Available transports:");
96409659
final String[] transports = listAllTransports();
96419660
if (transports != null) {

services/core/java/com/android/server/SystemConfig.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.android.server;
1818

1919
import android.app.ActivityManager;
20+
import android.content.ComponentName;
2021
import android.content.pm.FeatureInfo;
2122
import android.os.*;
2223
import android.os.Process;
@@ -99,6 +100,9 @@ public static final class PermissionEntry {
99100
// URL-handling state upon factory reset.
100101
final ArraySet<String> mLinkedApps = new ArraySet<>();
101102

103+
// These are the permitted backup transport service components
104+
final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
105+
102106
public static SystemConfig getInstance() {
103107
synchronized (SystemConfig.class) {
104108
if (sInstance == null) {
@@ -144,6 +148,10 @@ public ArraySet<String> getLinkedApps() {
144148
return mLinkedApps;
145149
}
146150

151+
public ArraySet<ComponentName> getBackupTransportWhitelist() {
152+
return mBackupTransportWhitelist;
153+
}
154+
147155
SystemConfig() {
148156
// Read configuration from system
149157
readPermissions(Environment.buildPath(
@@ -380,6 +388,23 @@ private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
380388
mLinkedApps.add(pkgname);
381389
}
382390
XmlUtils.skipCurrentTag(parser);
391+
} else if ("backup-transport-whitelisted-service".equals(name)) {
392+
String serviceName = parser.getAttributeValue(null, "service");
393+
if (serviceName == null) {
394+
Slog.w(TAG, "<backup-transport-whitelisted-service> without service in "
395+
+ permFile + " at " + parser.getPositionDescription());
396+
} else {
397+
ComponentName cn = ComponentName.unflattenFromString(serviceName);
398+
if (cn == null) {
399+
Slog.w(TAG,
400+
"<backup-transport-whitelisted-service> with invalid service name "
401+
+ serviceName + " in "+ permFile
402+
+ " at " + parser.getPositionDescription());
403+
} else {
404+
mBackupTransportWhitelist.add(cn);
405+
}
406+
}
407+
XmlUtils.skipCurrentTag(parser);
383408

384409
} else {
385410
XmlUtils.skipCurrentTag(parser);

0 commit comments

Comments
 (0)