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

Commit 7aade1ac authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Settings 2-pane deep link vulnerabilities" into tm-dev

parents 7c1b4588 434c8934
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -43,6 +45,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toolbar;

import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowCompat;
@@ -65,6 +68,7 @@ import com.android.settings.core.CategoryMixin;
import com.android.settings.core.FeatureFlags;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.PasswordUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;

@@ -431,6 +435,32 @@ public class SettingsHomepageActivity extends FragmentActivity implements
            finish();
            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);

        // To prevent launchDeepLinkIntentToRight again for configuration change.
@@ -472,6 +502,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements
        }
    }

    @VisibleForTesting
    boolean isCallingAppPermitted(String permission) {
        return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(
                this, getActivityToken(), permission);
    }

    private String getHighlightMenuKey() {
        final Intent intent = getIntent();
        if (intent != null && TextUtils.equals(intent.getAction(),
+35 −0
Original line number Diff line number Diff line
@@ -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 org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -37,9 +39,11 @@ import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -66,6 +70,11 @@ public class SettingsHomepageActivityTest {
        MockitoAnnotations.initMocks(this);
    }

    @After
    public void tearDown() {
        ShadowPasswordUtils.reset();
    }

    @Test
    public void launch_shouldHaveAnimationForIaFragment() {
        final SettingsHomepageActivity activity = Robolectric.buildActivity(
@@ -195,6 +204,32 @@ public class SettingsHomepageActivityTest {
                & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
    }

    @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)
    public static class ShadowSuggestionFeatureProviderImpl {