Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ede9c3d authored by Carlos Valdivia's avatar Carlos Valdivia
Browse files

Logging to KEY_INTENT security failure

To help debugging we would like to know the targetPackageName and uid of
the KEY_INTENT that is being rejected.

Bug: 27598664
Change-Id: Idcf1eea82a96913947975b6fe3aa1e9c6e5109a7
parent a4750fd7
Loading
Loading
Loading
Loading
+37 −43
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -2460,31 +2461,12 @@ public class AccountManagerService
        public void onResult(Bundle result) {
            mNumResults++;
            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.
                 */
                int authenticatorUid = Binder.getCallingUid();
                long bid = Binder.clearCallingIdentity();
                try {
                    PackageManager pm = mContext.getPackageManager();
                    ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId);
                    int targetUid = resolveInfo.activityInfo.applicationInfo.uid;
                    if (PackageManager.SIGNATURE_MATCH != pm.checkSignatures(authenticatorUid,
                            targetUid)) {
                        throw new SecurityException("Activity to be started with KEY_INTENT must "
                                + "share Authenticator's signatures");
                    }
                } finally {
                    Binder.restoreCallingIdentity(bid);
                checkKeyIntent(
                        Binder.getCallingUid(),
                        intent);
            }
            }

            IAccountManagerResponse response;
            if (mExpectActivityLaunch && result != null
                    && result.containsKey(AccountManager.KEY_INTENT)) {
@@ -3569,6 +3551,36 @@ public class AccountManagerService
            return response;
        }

        /**
         * Checks Intents, supplied via KEY_INTENT, to make sure that they don't violate our
         * security policy.
         *
         * In particular we want to make sure that the Authenticator doesn't try to trick users
         * 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 {
            long bid = Binder.clearCallingIdentity();
            try {
                PackageManager pm = mContext.getPackageManager();
                ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId);
                ActivityInfo targetActivityInfo = resolveInfo.activityInfo;
                int targetUid = targetActivityInfo.applicationInfo.uid;
                if (PackageManager.SIGNATURE_MATCH != pm.checkSignatures(authUid, targetUid)) {
                    String pkgName = targetActivityInfo.packageName;
                    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));
                }
            } finally {
                Binder.restoreCallingIdentity(bid);
            }
        }

        private void close() {
            synchronized (mSessions) {
                if (mSessions.remove(toString()) == null) {
@@ -3711,27 +3723,9 @@ public class AccountManagerService
            }
            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.
                 */
                int authenticatorUid = Binder.getCallingUid();
                long bid = Binder.clearCallingIdentity();
                try {
                    PackageManager pm = mContext.getPackageManager();
                    ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId);
                    int targetUid = resolveInfo.activityInfo.applicationInfo.uid;
                    if (PackageManager.SIGNATURE_MATCH !=
                            pm.checkSignatures(authenticatorUid, targetUid)) {
                        throw new SecurityException(
                                "Activity to be started with KEY_INTENT must " +
                               "share Authenticator's signatures");
                    }
                } finally {
                    Binder.restoreCallingIdentity(bid);
                }
                checkKeyIntent(
                        Binder.getCallingUid(),
                        intent);
            }
            if (result != null
                    && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) {