summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java31
-rw-r--r--services/core/java/com/android/server/content/SyncStorageEngine.java13
2 files changed, 43 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index f739fa81d5aa..705eae677d2b 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -645,6 +645,37 @@ public class SyncManager {
mContext.startService(startServiceIntent);
}
});
+
+ // Sync adapters were able to access the synced account without the accounts
+ // permission which circumvents our permission model. Therefore, we require
+ // sync adapters that don't have access to the account to get user consent.
+ // This can be noisy, therefore we will white-list sync adapters installed
+ // before we started checking for account access because they already know
+ // the account (they run before) which is the genie is out of the bottle.
+ whiteListExistingSyncAdaptersIfNeeded();
+ }
+
+ private void whiteListExistingSyncAdaptersIfNeeded() {
+ if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
+ return;
+ }
+ List<UserInfo> users = mUserManager.getUsers(true);
+ final int userCount = users.size();
+ for (int i = 0; i < userCount; i++) {
+ UserHandle userHandle = users.get(i).getUserHandle();
+ final int userId = userHandle.getIdentifier();
+ for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> service
+ : mSyncAdapters.getAllServices(userId)) {
+ String packageName = service.componentName.getPackageName();
+ for (Account account : mAccountManager.getAccountsByTypeAsUser(
+ service.type.accountType, userHandle)) {
+ if (!canAccessAccount(account, packageName, userId)) {
+ mAccountManager.updateAppPermission(account,
+ AccountManager.ACCOUNT_ACCESS_TOKEN, service.uid, true);
+ }
+ }
+ }
+ }
}
private boolean isDeviceProvisioned() {
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 64849aa321da..8289bae8793b 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -137,7 +137,7 @@ public class SyncStorageEngine extends Handler {
private static final boolean SYNC_ENABLED_DEFAULT = false;
// the version of the accounts xml file format
- private static final int ACCOUNTS_VERSION = 2;
+ private static final int ACCOUNTS_VERSION = 3;
private static HashMap<String, String> sAuthorityRenames;
private static PeriodicSyncAddedListener mPeriodicSyncAddedListener;
@@ -408,6 +408,8 @@ public class SyncStorageEngine extends Handler {
private OnSyncRequestListener mSyncRequestListener;
private OnAuthorityRemovedListener mAuthorityRemovedListener;
+ private boolean mGrantSyncAdaptersAccountAccess;
+
private SyncStorageEngine(Context context, File dataDir) {
mContext = context;
sSyncStorageEngine = this;
@@ -1410,6 +1412,10 @@ public class SyncStorageEngine extends Handler {
}
}
+ public boolean shouldGrantSyncAdaptersAccountAccess() {
+ return mGrantSyncAdaptersAccountAccess;
+ }
+
/**
* public for testing
*/
@@ -1464,6 +1470,11 @@ public class SyncStorageEngine extends Handler {
} catch (NumberFormatException e) {
version = 0;
}
+
+ if (version < 3) {
+ mGrantSyncAdaptersAccountAccess = true;
+ }
+
String nextIdString = parser.getAttributeValue(null, XML_ATTR_NEXT_AUTHORITY_ID);
try {
int id = (nextIdString == null) ? 0 : Integer.parseInt(nextIdString);