Merge "Settings 2-pane deep link vulnerabilities" into tm-qpr-dev
This commit is contained in:
@@ -27,6 +27,8 @@ import android.app.ActivityManager;
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -66,6 +68,7 @@ import com.android.settings.core.CategoryMixin;
|
|||||||
import com.android.settings.core.FeatureFlags;
|
import com.android.settings.core.FeatureFlags;
|
||||||
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
|
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
import com.android.settings.password.PasswordUtils;
|
||||||
import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
|
import com.android.settings.safetycenter.SafetyCenterManagerWrapper;
|
||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
||||||
@@ -444,6 +447,32 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()),
|
||||||
|
getPackageName())) {
|
||||||
|
ActivityInfo targetActivityInfo = null;
|
||||||
|
try {
|
||||||
|
targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName,
|
||||||
|
/* flags= */ 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Log.e(TAG, "Failed to get target ActivityInfo: " + e);
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetActivityInfo.exported) {
|
||||||
|
Log.e(TAG, "Must not launch an unexported Actvity for deep link");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCallingAppPermitted(targetActivityInfo.permission)) {
|
||||||
|
Log.e(TAG, "Calling app must have the permission of deep link Activity");
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
targetIntent.setComponent(targetComponentName);
|
targetIntent.setComponent(targetComponentName);
|
||||||
|
|
||||||
// To prevent launchDeepLinkIntentToRight again for configuration change.
|
// To prevent launchDeepLinkIntentToRight again for configuration change.
|
||||||
@@ -485,6 +514,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isCallingAppPermitted(String permission) {
|
||||||
|
return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(
|
||||||
|
this, getActivityToken(), permission);
|
||||||
|
}
|
||||||
|
|
||||||
private String getHighlightMenuKey() {
|
private String getHighlightMenuKey() {
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
if (intent != null && TextUtils.equals(intent.getAction(),
|
if (intent != null && TextUtils.equals(intent.getAction(),
|
||||||
|
@@ -20,6 +20,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -40,9 +42,11 @@ import androidx.fragment.app.Fragment;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
|
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
|
||||||
import com.android.settings.testutils.shadow.ShadowActivityEmbeddingUtils;
|
import com.android.settings.testutils.shadow.ShadowActivityEmbeddingUtils;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
|
||||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||||
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -69,6 +73,11 @@ public class SettingsHomepageActivityTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
ShadowPasswordUtils.reset();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void launch_shouldHaveAnimationForIaFragment() {
|
public void launch_shouldHaveAnimationForIaFragment() {
|
||||||
final SettingsHomepageActivity activity = Robolectric.buildActivity(
|
final SettingsHomepageActivity activity = Robolectric.buildActivity(
|
||||||
@@ -208,6 +217,32 @@ public class SettingsHomepageActivityTest {
|
|||||||
verify(activity).initSplitPairRules();
|
verify(activity).initSplitPairRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(shadows = {ShadowPasswordUtils.class})
|
||||||
|
public void isCallingAppPermitted_emptyPermission_returnTrue() {
|
||||||
|
SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity());
|
||||||
|
|
||||||
|
assertTrue(homepageActivity.isCallingAppPermitted(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(shadows = {ShadowPasswordUtils.class})
|
||||||
|
public void isCallingAppPermitted_noGrantedPermission_returnFalse() {
|
||||||
|
SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity());
|
||||||
|
|
||||||
|
assertFalse(homepageActivity.isCallingAppPermitted("android.permission.TEST"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(shadows = {ShadowPasswordUtils.class})
|
||||||
|
public void isCallingAppPermitted_grantedPermission_returnTrue() {
|
||||||
|
SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity());
|
||||||
|
String permission = "android.permission.TEST";
|
||||||
|
ShadowPasswordUtils.addGrantedPermission(permission);
|
||||||
|
|
||||||
|
assertTrue(homepageActivity.isCallingAppPermitted(permission));
|
||||||
|
}
|
||||||
|
|
||||||
@Implements(SuggestionFeatureProviderImpl.class)
|
@Implements(SuggestionFeatureProviderImpl.class)
|
||||||
public static class ShadowSuggestionFeatureProviderImpl {
|
public static class ShadowSuggestionFeatureProviderImpl {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user