Merge "LocationPermissionChecker: Exempt privileged components from location check" am: 2324ff48be am: 3f78d1ce0a
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1550515 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I45afdaba68269d59cfcf670ef7fdef6a19b3a9d2
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user