From b9ba0c6c43f0f7f0d5e347030e3c86a86ed74542 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Wed, 26 Feb 2014 15:42:34 -0800 Subject: Prevent authenticators from using Settings to launch arbitrary activities. Various authenticator results such as getAuthToken and addAccount might result in an Intent returned to the AccountManager caller. A malicious authenticator could exploit the fact that the Settings are a system app, lead the user to launch add account for their account type and thus get Settings to use the intent to start some arbitrary third parties Activity. The fix is to make sure that the UID of the app associated with Activity to be launched by the supplied intent and the Authenticators UID share the same signature. This means that an authenticator implementer can only exploit apps they control. This is a backport of 5bab9daf3cf66f4de19f8757e386030e8bef23ce Bug: 7699048 Change-Id: Ifed345c2fc20020d55fa2cab1f2f7ea509ea09b2 --- .../android/accounts/AccountManagerService.java | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'core/java/android/accounts/AccountManagerService.java') diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index 22e454f..7d7fbac 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -34,6 +34,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; import android.content.pm.RegisteredServicesCacheListener; +import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.Cursor; @@ -1750,9 +1751,31 @@ public class AccountManagerService } } + @Override public void onResult(Bundle result) { mNumResults++; - if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { + Intent intent = null; + if (result != null + && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { + /* + * The Authenticator API allows third party authenticators to + * supply arbitrary intents to other apps that they can run, + * this can be very bad when those apps are in the system like + * the System Settings. + */ + PackageManager pm = mContext.getPackageManager(); + ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); + int targetUid = resolveInfo.activityInfo.applicationInfo.uid; + int authenticatorUid = Binder.getCallingUid(); + if (PackageManager.SIGNATURE_MATCH != + pm.checkSignatures(authenticatorUid, targetUid)) { + throw new SecurityException( + "Activity to be started with KEY_INTENT must " + + "share Authenticator's signatures"); + } + } + if (result != null + && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { String accountName = result.getString(AccountManager.KEY_ACCOUNT_NAME); String accountType = result.getString(AccountManager.KEY_ACCOUNT_TYPE); if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { -- cgit v1.1