Fix checkKeyIntentParceledCorrectly's bypass

The checkKeyIntentParceledCorrectly method was added in checkKeyIntent, which was originaly  only invoked when AccountManagerService deserializes the KEY_INTENT value as not NULL. However, due to the self-changing bundle technique in Parcel mismatch problems, the Intent value can change after reparceling; hence would bypass the added checkKeyIntentParceledCorrectly call.

This CL did the following:

- Ensure the checkKeyIntent method is also called when result.getParcelable(AccountManager.KEY_INTENT, Intent.class) == null.
- Migrate to the safer Bundle.getParcelable(String, Class<T>) API call
  in AccountManagerService.

Bug: 260567867
Bug: 262230405
Test: local test, see b/262230405
Test: atest CtsAccountManagerTestCases
Merged-In: I7b528f52c41767ae12731838fdd36aa26a8f3477
Change-Id: I7b528f52c41767ae12731838fdd36aa26a8f3477
This commit is contained in:
Hao Ke
2022-12-12 15:49:16 +00:00
parent a8b7595558
commit e7c9cedab6

View File

@@ -3558,8 +3558,7 @@ public class AccountManagerService
Bundle.setDefusable(result, true);
mNumResults++;
Intent intent = null;
if (result != null
&& (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) {
if (result != null) {
if (!checkKeyIntent(
Binder.getCallingUid(),
result)) {
@@ -4928,8 +4927,10 @@ public class AccountManagerService
EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
return false;
}
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
if (intent == null) {
return true;
}
// Explicitly set an empty ClipData to ensure that we don't offer to
// promote any Uris contained inside for granting purposes
if (intent.getClipData() == null) {
@@ -4979,8 +4980,12 @@ public class AccountManagerService
Bundle simulateBundle = p.readBundle();
p.recycle();
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT, Intent.class);
return (intent.filterEquals(simulateBundle.getParcelable(AccountManager.KEY_INTENT,
Intent.class)));
Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT,
Intent.class);
if (intent == null) {
return (simulateIntent == null);
}
return intent.filterEquals(simulateIntent);
}
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
@@ -5129,8 +5134,7 @@ public class AccountManagerService
}
}
}
if (result != null
&& (intent = result.getParcelable(AccountManager.KEY_INTENT, android.content.Intent.class)) != null) {
if (result != null) {
if (!checkKeyIntent(
Binder.getCallingUid(),
result)) {