summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca Silberstein <silberst@google.com>2018-03-30 18:34:37 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-03-30 18:34:37 +0000
commit9ba2e5f5bf08a25a14fee695c72c534419f211cd (patch)
treeccd505f6b49e09a38b291d4111909bd93a831378
parent05a370d9aede8f307a10a8c27fa17e18240aa8d8 (diff)
parentdf39a431ac58f21f350dd8a9282fc3f7cb311a0f (diff)
Merge "WifiPermissionsUtil: update canAccessScanResults" into pi-dev
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsUtil.java31
-rw-r--r--service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java108
3 files changed, 149 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
index 594d9426c..0f333d498 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java
@@ -88,6 +88,22 @@ public class WifiPermissionsUtil {
}
/**
+ * Checks if the app has the permission to access Wi-Fi state or not.
+ *
+ * @param uid uid of the app.
+ * @return true if the app does have the permission, false otherwise.
+ */
+ public boolean checkWifiAccessPermission(int uid) {
+ try {
+ int permission = mWifiPermissionsWrapper.getAccessWifiStatePermission(uid);
+ return (permission == PackageManager.PERMISSION_GRANTED);
+ } catch (RemoteException e) {
+ mLog.err("Error checking for permission: %").r(e.getMessage()).flush();
+ return false;
+ }
+ }
+
+ /**
* Check and enforce Coarse Location permission.
*
* @param pkgName PackageName of the application requesting access
@@ -163,11 +179,22 @@ public class WifiPermissionsUtil {
// Coarse Location permission to have access to location information.
boolean canAppPackageUseLocation = isLocationModeEnabled(pkgName)
&& checkCallersLocationPermission(pkgName, uid);
+ // "Connectivity" apps can access scan results if they have both the location permission and
+ // (ACCESS_WIFI_STATE or CHANGE_WIFI_STATE), if wifi is enabled and location is off.
+ // While subtle, the requirement of having wifi enabled is enforced by the lack of private
+ // information when wifi is toggled off and we will not enter Scan mode if Location is
+ // toggled off.
+ boolean appTypeConnectivity = checkCallersLocationPermission(pkgName, uid)
+ && (checkChangePermission(uid) || checkWifiAccessPermission(uid));
+
// If neither caller or app has location access, there is no need to check
// any other permissions. Deny access to scan results.
if (!canCallingUidAccessLocation && !canAppPackageUseLocation) {
- mLog.tC("Denied: no location permission");
- return false;
+ // also check if it is a connectivity app
+ if (!appTypeConnectivity) {
+ mLog.tC("Denied: no location permission");
+ return false;
+ }
}
// Check if Wifi Scan request is an operation allowed for this App.
if (!isScanAllowedbyApps(pkgName, uid)) {
diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
index 84aacdff4..18e08d260 100644
--- a/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
+++ b/service/java/com/android/server/wifi/util/WifiPermissionsWrapper.java
@@ -110,6 +110,18 @@ public class WifiPermissionsWrapper {
}
/**
+ * Determines if the caller has the access wifi state permission.
+ *
+ * @param uid to check the permission for
+ * @return int representation of success or denied
+ * @throws RemoteException
+ */
+ public int getAccessWifiStatePermission(int uid) throws RemoteException {
+ return AppGlobals.getPackageManager().checkUidPermission(
+ Manifest.permission.ACCESS_WIFI_STATE, uid);
+ }
+
+ /**
* Determines if the caller has local mac address permission.
*
* @param uid to check the permission for
diff --git a/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
index d5608a677..6e582db6d 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/WifiPermissionsUtilTest.java
@@ -37,6 +37,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.support.test.filters.SmallTest;
import com.android.server.wifi.BinderUtil;
import com.android.server.wifi.FakeWifiLog;
@@ -58,6 +59,7 @@ import java.util.HashMap;
/** Unit tests for {@link WifiPermissionsUtil}. */
@RunWith(JUnit4.class)
+@SmallTest
public class WifiPermissionsUtilTest {
public static final String TAG = "WifiPermissionsUtilTest";
@@ -368,6 +370,112 @@ public class WifiPermissionsUtilTest {
}
/**
+ * Test case setting: Package is valid
+ * Location Mode Disabled
+ * Caller has location permission
+ * has Peer Mac Address read permission
+ * Validate result is false
+ * - Uid is not an active network scorer
+ * - Uid doesn't have Coarse Location Access
+ * - which implies No Location Permission
+ */
+ @Test
+ public void testCannotAccessScanResults_LocationModeDisabled() throws Exception {
+ boolean output = true;
+ mThrowSecurityException = false;
+ mUid = MANAGED_PROFILE_UID;
+ mPermissionsList.put(mMacAddressPermission, mUid);
+ mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
+ mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid);
+ mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF;
+
+ setupTestCase();
+ when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+
+ WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
+ mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector);
+ try {
+ output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid);
+ } catch (SecurityException e) {
+ throw e;
+ }
+ assertEquals(true, output);
+ }
+
+ /**
+ * Test case setting: Package is valid
+ * Location Mode Disabled
+ * Caller has location permisson
+ * Caller has CHANGE_WIFI_STATE
+ * Validate result is false
+ * - Doesn't have Peer Mac Address read permission
+ * - Uid is not an active network scorer
+ * - Location Mode is enabled but the uid
+ * - doesn't have Coarse Location Access
+ * - which implies scan result access
+ */
+ @Test
+ public void testCanAccessScanResults_LocationModeDisabledHasChangeWifiState() throws Exception {
+ boolean output = false;
+ mThrowSecurityException = false;
+ mUid = MANAGED_PROFILE_UID;
+ mPermissionsList.put(mMacAddressPermission, mUid);
+ mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
+ mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid);
+ mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF;
+
+ setupTestCase();
+ when(mMockPermissionsWrapper.getChangeWifiConfigPermission(mUid))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
+ mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector);
+ try {
+ output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid);
+ } catch (SecurityException e) {
+ throw e;
+ }
+ assertEquals(true, output);
+ }
+
+ /**
+ * Test case setting: Package is valid
+ * Location Mode Disabled
+ * Caller has location permisson
+ * Caller has ACCESS_WIFI_STATE
+ * Validate result is false
+ * - Doesn't have Peer Mac Address read permission
+ * - Uid is not an active network scorer
+ * - Location Mode is enabled but the uid
+ * - doesn't have Coarse Location Access
+ * - which implies scan result access
+ */
+ @Test
+ public void testCanAccessScanResults_LocationModeDisabledHasAccessWifiState() throws Exception {
+ boolean output = false;
+ mThrowSecurityException = false;
+ mUid = MANAGED_PROFILE_UID;
+ mPermissionsList.put(mMacAddressPermission, mUid);
+ mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
+ mPermissionsList.put(mInteractAcrossUsersFullPermission, mUid);
+ mLocationModeSetting = Settings.Secure.LOCATION_MODE_OFF;
+
+ setupTestCase();
+ when(mMockPermissionsWrapper.getAccessWifiStatePermission(mUid))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ WifiPermissionsUtil codeUnderTest = new WifiPermissionsUtil(mMockPermissionsWrapper,
+ mMockContext, mMockWifiSettingsStore, mMockUserManager, mWifiInjector);
+ try {
+ output = codeUnderTest.canAccessScanResults(TEST_PACKAGE_NAME, mUid);
+ } catch (SecurityException e) {
+ throw e;
+ }
+ assertEquals(true, output);
+ }
+
+ /**
* Test case setting: Invalid Package
* Expect a securityException
*/