From 33f942c2efc97ac04feca3d9635ad26aa74fe0da Mon Sep 17 00:00:00 2001 From: Aseem Kumar Date: Fri, 4 Nov 2022 21:55:38 +0000 Subject: [PATCH] Use `android` as packageName instead of `null` for methods used by system to fetch accounts. When `null` is used with getAccountsFromCache method, there is conversion from calling UID to packageName (call getPackageNameForUid in filterAccounts), and then another conversion using packageName to UID in resolveAccountVisbility). Sometimes (as determined by PackageManager), a package which is installed in primary profile but is not installed in work profile is used to fetch accounts for work profile. This causes fetching accounts in work profile to fail. The fix uses "android" as packageName for all methods used by system process. This ensures that this conversion always works. Test: atest AccountManagerServiceTest Bug: 246257147 Change-Id: Id2e4b860f49366db5a85a3fd83b3fedeeabc9cbb --- .../accounts/AccountManagerService.java | 37 ++++++++++++------- .../android/server/content/SyncManager.java | 9 +++-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 6c2806e402b44..1a163a8264b21 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -528,7 +528,7 @@ public class AccountManagerService private Map getAccountsAndVisibilityForPackage(String packageName, List accountTypes, Integer callingUid, UserAccounts accounts) { if (!packageExistsForUser(packageName, accounts.userId)) { - Log.d(TAG, "Package not found " + packageName); + Log.w(TAG, "getAccountsAndVisibilityForPackage#Package not found " + packageName); return new LinkedHashMap<>(); } @@ -677,7 +677,7 @@ public class AccountManagerService restoreCallingIdentity(identityToken); } } catch (NameNotFoundException e) { - Log.d(TAG, "Package not found " + e.getMessage()); + Log.w(TAG, "resolveAccountVisibility#Package not found " + e.getMessage()); return AccountManager.VISIBILITY_NOT_VISIBLE; } @@ -756,7 +756,7 @@ public class AccountManagerService } return true; } catch (NameNotFoundException e) { - Log.d(TAG, "Package not found " + e.getMessage()); + Log.w(TAG, "isPreOApplication#Package not found " + e.getMessage()); return true; } } @@ -4063,7 +4063,7 @@ public class AccountManagerService int uid = mPackageManager.getPackageUidAsUser(packageName, userId); return hasAccountAccess(account, packageName, uid); } catch (NameNotFoundException e) { - Log.d(TAG, "Package not found " + e.getMessage()); + Log.w(TAG, "hasAccountAccess#Package not found " + e.getMessage()); return false; } } @@ -4195,7 +4195,7 @@ public class AccountManagerService } final long token = Binder.clearCallingIdentity(); try { - AccountAndUser[] allAccounts = getAllAccounts(); + AccountAndUser[] allAccounts = getAllAccountsForSystemProcess(); for (int i = allAccounts.length - 1; i >= 0; i--) { if (allAccounts[i].account.equals(account)) { return true; @@ -4345,10 +4345,11 @@ public class AccountManagerService /** * Returns accounts for all running users, ignores visibility values. * + * Should only be called by System process. * @hide */ @NonNull - public AccountAndUser[] getRunningAccounts() { + public AccountAndUser[] getRunningAccountsForSystem() { final int[] runningUserIds; try { runningUserIds = ActivityManager.getService().getRunningUserIds(); @@ -4356,26 +4357,34 @@ public class AccountManagerService // Running in system_server; should never happen throw new RuntimeException(e); } - return getAccounts(runningUserIds); + return getAccountsForSystem(runningUserIds); } /** * Returns accounts for all users, ignores visibility values. * + * Should only be called by system process + * * @hide */ @NonNull - public AccountAndUser[] getAllAccounts() { + public AccountAndUser[] getAllAccountsForSystemProcess() { final List users = getUserManager().getAliveUsers(); final int[] userIds = new int[users.size()]; for (int i = 0; i < userIds.length; i++) { userIds[i] = users.get(i).id; } - return getAccounts(userIds); + return getAccountsForSystem(userIds); } + /** + * Returns all accounts for the given user, ignores all visibility checks. + * This should only be called by system process. + * + * @hide + */ @NonNull - private AccountAndUser[] getAccounts(int[] userIds) { + private AccountAndUser[] getAccountsForSystem(int[] userIds) { final ArrayList runningAccounts = Lists.newArrayList(); for (int userId : userIds) { UserAccounts userAccounts = getUserAccounts(userId); @@ -4384,7 +4393,7 @@ public class AccountManagerService userAccounts, null /* type */, Binder.getCallingUid(), - null /* packageName */, + "android"/* packageName */, false /* include managed not visible*/); for (Account account : accounts) { runningAccounts.add(new AccountAndUser(account, userId)); @@ -5360,7 +5369,7 @@ public class AccountManagerService } } else { Account[] accounts = getAccountsFromCache(userAccounts, null /* type */, - Process.SYSTEM_UID, null /* packageName */, false); + Process.SYSTEM_UID, "android" /* packageName */, false); fout.println("Accounts: " + accounts.length); for (Account account : accounts) { fout.println(" " + account.toString()); @@ -5555,7 +5564,7 @@ public class AccountManagerService return true; } } catch (PackageManager.NameNotFoundException e) { - Log.d(TAG, "Package not found " + e.getMessage()); + Log.w(TAG, "isPrivileged#Package not found " + e.getMessage()); } } } finally { @@ -6079,7 +6088,7 @@ public class AccountManagerService } } } catch (NameNotFoundException e) { - Log.d(TAG, "Package not found " + e.getMessage()); + Log.w(TAG, "filterSharedAccounts#Package not found " + e.getMessage()); } Map filtered = new LinkedHashMap<>(); for (Map.Entry entry : unfiltered.entrySet()) { diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 73afa60e85102..eb81e70363d40 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -2215,7 +2215,8 @@ public class SyncManager { pw.print("Storage low: "); pw.println(storageLowIntent != null); pw.print("Clock valid: "); pw.println(mSyncStorageEngine.isClockValid()); - final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts(); + final AccountAndUser[] accounts = + AccountManagerService.getSingleton().getAllAccountsForSystemProcess(); pw.print("Accounts: "); if (accounts != INITIAL_ACCOUNTS_ARRAY) { @@ -3274,7 +3275,8 @@ public class SyncManager { private void updateRunningAccountsH(EndPoint syncTargets) { synchronized (mAccountsLock) { AccountAndUser[] oldAccounts = mRunningAccounts; - mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts(); + mRunningAccounts = + AccountManagerService.getSingleton().getRunningAccountsForSystem(); if (Log.isLoggable(TAG, Log.VERBOSE)) { Slog.v(TAG, "Accounts list: "); for (AccountAndUser acc : mRunningAccounts) { @@ -3316,7 +3318,8 @@ public class SyncManager { } // Cancel all jobs from non-existent accounts. - AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts(); + AccountAndUser[] allAccounts = + AccountManagerService.getSingleton().getAllAccountsForSystemProcess(); List ops = getAllPendingSyncs(); for (int i = 0, opsSize = ops.size(); i < opsSize; i++) { SyncOperation op = ops.get(i);