Merge "Add permission check to Intents used by Authenticator Settings."

This commit is contained in:
Dmitry Dementyev
2017-02-14 01:27:45 +00:00
committed by Android (Google) Code Review

View File

@@ -37,6 +37,7 @@ import android.os.UserHandle;
import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
@@ -84,7 +85,7 @@ public class ManageAccountsSettings extends AccountPreferenceBase
// If an account type is set, then show only accounts of that type // If an account type is set, then show only accounts of that type
private String mAccountType; private String mAccountType;
// Temporary hack, to deal with backward compatibility // Temporary hack, to deal with backward compatibility
// mFirstAccount is used for the injected preferences // mFirstAccount is used for the injected preferences
private Account mFirstAccount; private Account mFirstAccount;
@@ -448,15 +449,18 @@ public class ManageAccountsSettings extends AccountPreferenceBase
} }
/** /**
* Filters through the preference list provided by GoogleLoginService. * Recursively filters through the preference list provided by GoogleLoginService.
* *
* This method removes all the invalid intent from the list, adds account name as extra into the * This method removes all the invalid intent from the list, adds account name as extra into the
* intent, and hack the location settings to start it as a fragment. * intent, and hack the location settings to start it as a fragment.
*/ */
private void updatePreferenceIntents(PreferenceScreen prefs) { private void updatePreferenceIntents(PreferenceGroup prefs) {
final PackageManager pm = getActivity().getPackageManager(); final PackageManager pm = getActivity().getPackageManager();
for (int i = 0; i < prefs.getPreferenceCount(); ) { for (int i = 0; i < prefs.getPreferenceCount(); ) {
Preference pref = prefs.getPreference(i); Preference pref = prefs.getPreference(i);
if (pref instanceof PreferenceGroup) {
updatePreferenceIntents((PreferenceGroup) pref);
}
Intent intent = pref.getIntent(); Intent intent = pref.getIntent();
if (intent != null) { if (intent != null) {
// Hack. Launch "Location" as fragment instead of as activity. // Hack. Launch "Location" as fragment instead of as activity.
@@ -526,16 +530,24 @@ public class ManageAccountsSettings extends AccountPreferenceBase
private boolean isSafeIntent(PackageManager pm, Intent intent) { private boolean isSafeIntent(PackageManager pm, Intent intent) {
AuthenticatorDescription authDesc = AuthenticatorDescription authDesc =
mAuthenticatorHelper.getAccountTypeDescription(mAccountType); mAuthenticatorHelper.getAccountTypeDescription(mAccountType);
ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); ResolveInfo resolveInfo =
pm.resolveActivityAsUser(intent, 0, mUserHandle.getIdentifier());
if (resolveInfo == null) { if (resolveInfo == null) {
return false; return false;
} }
ActivityInfo resolvedActivityInfo = resolveInfo.activityInfo; ActivityInfo resolvedActivityInfo = resolveInfo.activityInfo;
ApplicationInfo resolvedAppInfo = resolvedActivityInfo.applicationInfo; ApplicationInfo resolvedAppInfo = resolvedActivityInfo.applicationInfo;
try { try {
if (resolvedActivityInfo.exported) {
if (resolvedActivityInfo.permission == null) {
return true; // exported activity without permission.
} else if (pm.checkPermission(resolvedActivityInfo.permission,
authDesc.packageName) == PackageManager.PERMISSION_GRANTED) {
return true;
}
}
ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0); ApplicationInfo authenticatorAppInf = pm.getApplicationInfo(authDesc.packageName, 0);
return resolvedActivityInfo.exported return resolvedAppInfo.uid == authenticatorAppInf.uid;
|| resolvedAppInfo.uid == authenticatorAppInf.uid;
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
Log.e(TAG, Log.e(TAG,
"Intent considered unsafe due to exception.", "Intent considered unsafe due to exception.",