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 5bab9daf3c

Bug: 7699048
Change-Id: Ifed345c2fc20020d55fa2cab1f2f7ea509ea09b2
This commit is contained in:
Paul Lawrence
2014-02-26 15:42:34 -08:00
parent 8e0c7768c8
commit b9ba0c6c43

View File

@ -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)) {