diff options
| -rw-r--r-- | services/core/java/com/android/server/content/SyncManager.java | 31 | ||||
| -rw-r--r-- | services/core/java/com/android/server/content/SyncStorageEngine.java | 13 |
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); |