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

Commit 2324ff48 authored by Roshan Pius's avatar Roshan Pius Committed by Gerrit Code Review
Browse files

Merge "LocationPermissionChecker: Exempt privileged components from location check"

parents 1ef84733 7692fba5
Loading
Loading
Loading
Loading
+41 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.AppOpsManager;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.location.LocationManager;
import android.net.NetworkStack;
import android.os.Binder;
import android.os.Binder;
import android.os.Build;
import android.os.Build;
import android.os.UserHandle;
import android.os.UserHandle;
@@ -147,6 +148,13 @@ public class LocationPermissionChecker {
            int uid, @Nullable String message) {
            int uid, @Nullable String message) {
        checkPackage(uid, pkgName);
        checkPackage(uid, pkgName);


        // Apps with NETWORK_SETTINGS, NETWORK_SETUP_WIZARD, NETWORK_STACK & MAINLINE_NETWORK_STACK
        // are granted a bypass.
        if (checkNetworkSettingsPermission(uid) || checkNetworkSetupWizardPermission(uid)
                || checkNetworkStackPermission(uid) || checkMainlineNetworkStackPermission(uid)) {
            return SUCCEEDED;
        }

        // Location mode must be enabled
        // Location mode must be enabled
        if (!isLocationModeEnabled()) {
        if (!isLocationModeEnabled()) {
            return ERROR_LOCATION_MODE_OFF;
            return ERROR_LOCATION_MODE_OFF;
@@ -259,4 +267,37 @@ public class LocationPermissionChecker {
        // We don't care about pid, pass in -1
        // We don't care about pid, pass in -1
        return mContext.checkPermission(permissionType, -1, uid);
        return mContext.checkPermission(permissionType, -1, uid);
    }
    }

    /**
     * Returns true if the |uid| holds NETWORK_SETTINGS permission.
     */
    public boolean checkNetworkSettingsPermission(int uid) {
        return getUidPermission(android.Manifest.permission.NETWORK_SETTINGS, uid)
                == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Returns true if the |uid| holds NETWORK_SETUP_WIZARD permission.
     */
    public boolean checkNetworkSetupWizardPermission(int uid) {
        return getUidPermission(android.Manifest.permission.NETWORK_SETUP_WIZARD, uid)
                == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Returns true if the |uid| holds NETWORK_STACK permission.
     */
    public boolean checkNetworkStackPermission(int uid) {
        return getUidPermission(android.Manifest.permission.NETWORK_STACK, uid)
                == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Returns true if the |uid| holds MAINLINE_NETWORK_STACK permission.
     */
    public boolean checkMainlineNetworkStackPermission(int uid) {
        return getUidPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, uid)
                == PackageManager.PERMISSION_GRANTED;
    }

}
}
+21 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,8 @@
 */
 */
package com.android.internal.util;
package com.android.internal.util;


import static android.Manifest.permission.NETWORK_SETTINGS;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
@@ -82,6 +84,7 @@ public class LocationPermissionCheckerTest {
    private int mAllowCoarseLocationApps;
    private int mAllowCoarseLocationApps;
    private int mFineLocationPermission;
    private int mFineLocationPermission;
    private int mAllowFineLocationApps;
    private int mAllowFineLocationApps;
    private int mNetworkSettingsPermission;
    private int mCurrentUser;
    private int mCurrentUser;
    private boolean mIsLocationEnabled;
    private boolean mIsLocationEnabled;
    private boolean mThrowSecurityException;
    private boolean mThrowSecurityException;
@@ -138,6 +141,7 @@ public class LocationPermissionCheckerTest {
        mFineLocationPermission = PackageManager.PERMISSION_DENIED;
        mFineLocationPermission = PackageManager.PERMISSION_DENIED;
        mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED;
        mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED;
        mAllowFineLocationApps = AppOpsManager.MODE_ERRORED;
        mAllowFineLocationApps = AppOpsManager.MODE_ERRORED;
        mNetworkSettingsPermission = PackageManager.PERMISSION_DENIED;
    }
    }


    private void setupMockInterface() {
    private void setupMockInterface() {
@@ -151,6 +155,8 @@ public class LocationPermissionCheckerTest {
                .thenReturn(mCoarseLocationPermission);
                .thenReturn(mCoarseLocationPermission);
        when(mMockContext.checkPermission(mManifestStringFine, -1, mUid))
        when(mMockContext.checkPermission(mManifestStringFine, -1, mUid))
                .thenReturn(mFineLocationPermission);
                .thenReturn(mFineLocationPermission);
        when(mMockContext.checkPermission(NETWORK_SETTINGS, -1, mUid))
                .thenReturn(mNetworkSettingsPermission);
        when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled);
        when(mLocationManager.isLocationEnabledForUser(any())).thenReturn(mIsLocationEnabled);
    }
    }


@@ -264,6 +270,21 @@ public class LocationPermissionCheckerTest {
        assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result);
        assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result);
    }
    }


    @Test
    public void testenforceCanAccessScanResults_LocationModeDisabledHasNetworkSettings()
            throws Exception {
        mThrowSecurityException = false;
        mIsLocationEnabled = false;
        mNetworkSettingsPermission = PackageManager.PERMISSION_GRANTED;
        setupTestCase();

        final int result =
                mChecker.checkLocationPermissionWithDetailInfo(
                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
        assertEquals(LocationPermissionChecker.SUCCEEDED, result);
    }


    private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
    private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
        try {
        try {
            r.run();
            r.run();
+20 −8
Original line number Original line Diff line number Diff line
@@ -2074,10 +2074,6 @@ public class ConnectivityServiceTest {


    @Test
    @Test
    public void testOwnerUidCannotChange() throws Exception {
    public void testOwnerUidCannotChange() throws Exception {
        // Owner UIDs are not visible without location permission.
        setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION);

        final NetworkCapabilities ncTemplate = new NetworkCapabilities();
        final NetworkCapabilities ncTemplate = new NetworkCapabilities();
        final int originalOwnerUid = Process.myUid();
        final int originalOwnerUid = Process.myUid();
        ncTemplate.setOwnerUid(originalOwnerUid);
        ncTemplate.setOwnerUid(originalOwnerUid);
@@ -2097,6 +2093,10 @@ public class ConnectivityServiceTest {
        mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true);
        mWiFiNetworkAgent.setNetworkCapabilities(agentCapabilities, true);
        waitForIdle();
        waitForIdle();


        // Owner UIDs are not visible without location permission.
        setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION);

        // Check that the capability change has been applied but the owner UID is not modified.
        // Check that the capability change has been applied but the owner UID is not modified.
        NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
        NetworkCapabilities nc = mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork());
        assertEquals(originalOwnerUid, nc.getOwnerUid());
        assertEquals(originalOwnerUid, nc.getOwnerUid());
@@ -7781,8 +7781,22 @@ public class ConnectivityServiceTest {
        naExtraInfo.unregister();
        naExtraInfo.unregister();
    }
    }


    // To avoid granting location permission bypass.
    private void denyAllLocationPrivilegedPermissions() {
        mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
                PERMISSION_DENIED);
        mServiceContext.setPermission(Manifest.permission.NETWORK_SETTINGS,
                PERMISSION_DENIED);
        mServiceContext.setPermission(Manifest.permission.NETWORK_STACK,
                PERMISSION_DENIED);
        mServiceContext.setPermission(Manifest.permission.NETWORK_SETUP_WIZARD,
                PERMISSION_DENIED);
    }

    private void setupLocationPermissions(
    private void setupLocationPermissions(
            int targetSdk, boolean locationToggle, String op, String perm) throws Exception {
            int targetSdk, boolean locationToggle, String op, String perm) throws Exception {
        denyAllLocationPrivilegedPermissions();

        final ApplicationInfo applicationInfo = new ApplicationInfo();
        final ApplicationInfo applicationInfo = new ApplicationInfo();
        applicationInfo.targetSdkVersion = targetSdk;
        applicationInfo.targetSdkVersion = targetSdk;
        when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
        when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
@@ -8156,15 +8170,13 @@ public class ConnectivityServiceTest {
                new NetworkAgentInfo(null, network, null, null, new NetworkCapabilities(), 0,
                new NetworkAgentInfo(null, network, null, null, new NetworkCapabilities(), 0,
                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);


        setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION);

        mMockVpn.establishForMyUid();
        mMockVpn.establishForMyUid();
        assertUidRangesUpdatedForMyUid(true);
        assertUidRangesUpdatedForMyUid(true);


        // Wait for networks to connect and broadcasts to be sent before removing permissions.
        // Wait for networks to connect and broadcasts to be sent before removing permissions.
        waitForIdle();
        waitForIdle();
        mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
        setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION);


        assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {network}));
        assertTrue(mService.setUnderlyingNetworksForVpn(new Network[] {network}));
        waitForIdle();
        waitForIdle();