DO NOT MERGE : 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 494df79172 from N
Change-Id: I405b49daee8c576584575c3e46877cc97632d8c6
This commit is contained in:
@@ -79,7 +79,9 @@ import android.os.storage.StorageManager;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -91,6 +93,7 @@ import com.android.internal.backup.IBackupTransport;
|
|||||||
import com.android.internal.backup.IObbBackupService;
|
import com.android.internal.backup.IObbBackupService;
|
||||||
import com.android.server.AppWidgetBackupBridge;
|
import com.android.server.AppWidgetBackupBridge;
|
||||||
import com.android.server.EventLogTags;
|
import com.android.server.EventLogTags;
|
||||||
|
import com.android.server.SystemConfig;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
|
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
|
||||||
|
|
||||||
@@ -309,6 +312,7 @@ public class BackupManagerService extends IBackupManager.Stub {
|
|||||||
volatile boolean mClearingData;
|
volatile boolean mClearingData;
|
||||||
|
|
||||||
// Transport bookkeeping
|
// Transport bookkeeping
|
||||||
|
final ArraySet<ComponentName> mTransportWhitelist;
|
||||||
final Intent mTransportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
|
final Intent mTransportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
|
||||||
final ArrayMap<String,String> mTransportNames
|
final ArrayMap<String,String> mTransportNames
|
||||||
= new ArrayMap<String,String>(); // component name -> registration name
|
= new ArrayMap<String,String>(); // component name -> registration name
|
||||||
@@ -1058,11 +1062,15 @@ public class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
// Set up our transport options and initialize the default transport
|
// Set up our transport options and initialize the default transport
|
||||||
// TODO: Don't create transports that we don't need to?
|
// TODO: Don't create transports that we don't need to?
|
||||||
mCurrentTransport = Settings.Secure.getString(context.getContentResolver(),
|
SystemConfig systemConfig = SystemConfig.getInstance();
|
||||||
|
mTransportWhitelist = systemConfig.getBackupTransportWhitelist();
|
||||||
|
|
||||||
|
String transport = Settings.Secure.getString(context.getContentResolver(),
|
||||||
Settings.Secure.BACKUP_TRANSPORT);
|
Settings.Secure.BACKUP_TRANSPORT);
|
||||||
if ("".equals(mCurrentTransport)) {
|
if (TextUtils.isEmpty(transport)) {
|
||||||
mCurrentTransport = null;
|
transport = null;
|
||||||
}
|
}
|
||||||
|
mCurrentTransport = transport;
|
||||||
if (DEBUG) Slog.v(TAG, "Starting with transport " + mCurrentTransport);
|
if (DEBUG) Slog.v(TAG, "Starting with transport " + mCurrentTransport);
|
||||||
|
|
||||||
// Find all transport hosts and bind to their services
|
// Find all transport hosts and bind to their services
|
||||||
@@ -1073,11 +1081,11 @@ public class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
if (hosts != null) {
|
if (hosts != null) {
|
||||||
for (int i = 0; i < hosts.size(); i++) {
|
for (int i = 0; i < hosts.size(); i++) {
|
||||||
final ServiceInfo transport = hosts.get(i).serviceInfo;
|
final ServiceInfo transportService = hosts.get(i).serviceInfo;
|
||||||
if (MORE_DEBUG) {
|
if (MORE_DEBUG) {
|
||||||
Slog.v(TAG, " " + transport.packageName + "/" + transport.name);
|
Slog.v(TAG, " " + transportService.packageName + "/" + transportService.name);
|
||||||
}
|
}
|
||||||
tryBindTransport(transport);
|
tryBindTransport(transportService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1869,6 +1877,11 @@ public class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// Actually bind; presumes that we have already validated the transport service
|
// Actually bind; presumes that we have already validated the transport service
|
||||||
boolean bindTransport(ServiceInfo transport) {
|
boolean bindTransport(ServiceInfo transport) {
|
||||||
ComponentName svcName = new ComponentName(transport.packageName, transport.name);
|
ComponentName svcName = new ComponentName(transport.packageName, transport.name);
|
||||||
|
if (!mTransportWhitelist.contains(svcName)) {
|
||||||
|
Slog.w(TAG, "Proposed transport " + svcName + " not whitelisted; ignoring");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.i(TAG, "Binding to transport host " + svcName);
|
Slog.i(TAG, "Binding to transport host " + svcName);
|
||||||
}
|
}
|
||||||
@@ -9193,6 +9206,12 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
|
|||||||
+ " (now = " + System.currentTimeMillis() + ')');
|
+ " (now = " + System.currentTimeMillis() + ')');
|
||||||
pw.println(" next scheduled: " + mNextBackupPass);
|
pw.println(" next scheduled: " + mNextBackupPass);
|
||||||
|
|
||||||
|
pw.println("Transport whitelist:");
|
||||||
|
for (ComponentName transport : mTransportWhitelist) {
|
||||||
|
pw.print(" ");
|
||||||
|
pw.println(transport.flattenToShortString());
|
||||||
|
}
|
||||||
|
|
||||||
pw.println("Available transports:");
|
pw.println("Available transports:");
|
||||||
final String[] transports = listAllTransports();
|
final String[] transports = listAllTransports();
|
||||||
if (transports != null) {
|
if (transports != null) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.pm.FeatureInfo;
|
import android.content.pm.FeatureInfo;
|
||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@@ -24,7 +25,9 @@ import android.util.ArraySet;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
@@ -81,6 +84,9 @@ public class SystemConfig {
|
|||||||
// These are the app package names that should not allow IME switching.
|
// These are the app package names that should not allow IME switching.
|
||||||
final ArraySet<String> mFixedImeApps = new ArraySet<>();
|
final ArraySet<String> mFixedImeApps = new ArraySet<>();
|
||||||
|
|
||||||
|
// These are the permitted backup transport service components
|
||||||
|
final ArraySet<ComponentName> mBackupTransportWhitelist = new ArraySet<>();
|
||||||
|
|
||||||
public static SystemConfig getInstance() {
|
public static SystemConfig getInstance() {
|
||||||
synchronized (SystemConfig.class) {
|
synchronized (SystemConfig.class) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
@@ -118,6 +124,10 @@ public class SystemConfig {
|
|||||||
return mFixedImeApps;
|
return mFixedImeApps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArraySet<ComponentName> getBackupTransportWhitelist() {
|
||||||
|
return mBackupTransportWhitelist;
|
||||||
|
}
|
||||||
|
|
||||||
SystemConfig() {
|
SystemConfig() {
|
||||||
// Read configuration from system
|
// Read configuration from system
|
||||||
readPermissions(Environment.buildPath(
|
readPermissions(Environment.buildPath(
|
||||||
@@ -312,6 +322,24 @@ public class SystemConfig {
|
|||||||
XmlUtils.skipCurrentTag(parser);
|
XmlUtils.skipCurrentTag(parser);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
} else if ("backup-transport-whitelisted-service".equals(name)) {
|
||||||
|
String serviceName = parser.getAttributeValue(null, "service");
|
||||||
|
if (serviceName == null) {
|
||||||
|
Slog.w(TAG, "<backup-transport-whitelisted-service> without service in "
|
||||||
|
+ permFile + " at " + parser.getPositionDescription());
|
||||||
|
} else {
|
||||||
|
ComponentName cn = ComponentName.unflattenFromString(serviceName);
|
||||||
|
if (cn == null) {
|
||||||
|
Slog.w(TAG,
|
||||||
|
"<backup-transport-whitelisted-service> with invalid service name "
|
||||||
|
+ serviceName + " in "+ permFile
|
||||||
|
+ " at " + parser.getPositionDescription());
|
||||||
|
} else {
|
||||||
|
mBackupTransportWhitelist.add(cn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XmlUtils.skipCurrentTag(parser);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
XmlUtils.skipCurrentTag(parser);
|
XmlUtils.skipCurrentTag(parser);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user