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
This commit is contained in:
Aseem Kumar
2022-11-04 21:55:38 +00:00
parent 6420c14173
commit 33f942c2ef
2 changed files with 29 additions and 17 deletions

View File

@@ -528,7 +528,7 @@ public class AccountManagerService
private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
List<String> 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<UserInfo> 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<AccountAndUser> 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<Account, Integer> filtered = new LinkedHashMap<>();
for (Map.Entry<Account, Integer> entry : unfiltered.entrySet()) {

View File

@@ -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<SyncOperation> ops = getAllPendingSyncs();
for (int i = 0, opsSize = ops.size(); i < opsSize; i++) {
SyncOperation op = ops.get(i);