From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: tiansiming Date: Wed, 20 Sep 2017 13:59:13 +0800 Subject: [PATCH] Fix another AddAccountSettings memory leak The memory leak will always occur in AddAccoutSettings when Bundle with an invalid intent returned in the addAccount we implement. Bug:https://issuetracker.google.com/issues/66088681 Test:Install the app through the github offered in above link, then press the "Test" item in ChooseAccountActivity (adb shell am start -n 'com.android.settings/.accounts.ChooseAccountActivity') serveal times. Check the activity number by "adb shell dumpsys meminfo com.android.settings". Change-Id: Id15fc73521d0ddc6ca891b6029ad04cd4427dbfe Signed-off-by: tiansiming --- .../accounts/AccountManagerService.java | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 520a0d314318..dd3e4d9cb17c 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -2530,9 +2530,13 @@ public class AccountManagerService * have users launching arbitrary activities by tricking users to * interact with malicious notifications. */ - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } doNotification(mAccounts, account, result.getString(AccountManager.KEY_AUTH_FAILED_MESSAGE), intent, "android", accounts.userId); @@ -2941,9 +2945,13 @@ public class AccountManagerService Intent intent = null; if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } } IAccountManagerResponse response; if (mExpectActivityLaunch && result != null @@ -4209,9 +4217,7 @@ public class AccountManagerService * into launching aribtrary intents on the device via by tricking to click authenticator * supplied entries in the system Settings app. */ - protected void checkKeyIntent( - int authUid, - Intent intent) throws SecurityException { + protected boolean checkKeyIntent(int authUid, Intent intent) { intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION @@ -4220,6 +4226,9 @@ public class AccountManagerService try { PackageManager pm = mContext.getPackageManager(); ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); + if (resolveInfo == null) { + return false; + } ActivityInfo targetActivityInfo = resolveInfo.activityInfo; int targetUid = targetActivityInfo.applicationInfo.uid; if (PackageManager.SIGNATURE_MATCH != pm.checkSignatures(authUid, targetUid)) { @@ -4227,9 +4236,10 @@ public class AccountManagerService String activityName = targetActivityInfo.name; String tmpl = "KEY_INTENT resolved to an Activity (%s) in a package (%s) that " + "does not share a signature with the supplying authenticator (%s)."; - throw new SecurityException( - String.format(tmpl, activityName, pkgName, mAccountType)); + Log.e(TAG, String.format(tmpl, activityName, pkgName, mAccountType)); + return false; } + return true; } finally { Binder.restoreCallingIdentity(bid); } @@ -4378,9 +4388,13 @@ public class AccountManagerService } if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - checkKeyIntent( + if (!checkKeyIntent( Binder.getCallingUid(), - intent); + intent)) { + onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, + "invalid intent in bundle returned"); + return; + } } if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) {