Merge cherrypicks of ['googleplex-android-review.googlesource.com/28665239'] into udc-platform-release.
Change-Id: Ia691f471cbdce2b142d0b6b55d4a316da733e78a
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 4f636cb..7642697 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -16,7 +16,11 @@
package com.android.server.wifi;
+import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_NUM;
import static android.net.wifi.WifiManager.ALL_ZEROS_MAC_ADDRESS;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_NUMBER_OF_OI;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_OI_VALUE;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_URL_BYTES;
import static com.android.server.wifi.util.NativeUtil.addEnclosingQuotes;
@@ -31,6 +35,7 @@
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiSsid;
+import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.PatternMatcher;
import android.text.TextUtils;
import android.util.Log;
@@ -46,8 +51,10 @@
import java.util.Arrays;
import java.util.BitSet;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* WifiConfiguration utility for any {@link android.net.wifi.WifiConfiguration} related operations.
@@ -70,6 +77,7 @@
private static final int PSK_SAE_HEX_LEN = 64;
private static final int WEP104_KEY_BYTES_LEN = 13;
private static final int WEP40_KEY_BYTES_LEN = 5;
+ private static final int MAX_STRING_LENGTH = 512;
@VisibleForTesting
public static final String PASSWORD_MASK = "*";
@@ -723,7 +731,8 @@
if (!validateSsid(config.SSID, isAdd)) {
return false;
}
- if (!validateBssid(config.BSSID)) {
+ if (!validateBssid(config.BSSID) || !validateBssid(config.dhcpServer)
+ || !validateBssid(config.defaultGwMacAddress)) {
return false;
}
if (!validateBitSets(config)) {
@@ -732,9 +741,22 @@
if (!validateKeyMgmt(config.allowedKeyManagement)) {
return false;
}
- if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_WEP)
- && config.wepKeys != null
- && !validateWepKeys(config.wepKeys, config.wepTxKeyIndex, isAdd)) {
+ if (!validateSecurityParameters(config.getSecurityParamsList())) {
+ return false;
+ }
+ if (!validatePasspoint(config)) {
+ return false;
+ }
+ if (!validateNetworkSelectionStatus(config.getNetworkSelectionStatus())) {
+ return false;
+ }
+
+ if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_WEP)) {
+ if (config.wepKeys != null
+ && !validateWepKeys(config.wepKeys, config.wepTxKeyIndex, isAdd)) {
+ return false;
+ }
+ } else if (!validateWepKeys(config.wepKeys, config.wepTxKeyIndex, false)) {
return false;
}
if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
@@ -766,10 +788,92 @@
if (!validateIpConfiguration(config.getIpConfiguration())) {
return false;
}
+
+ if (config.getDppConnector().length > MAX_URL_BYTES
+ || config.getDppCSignKey().length > MAX_URL_BYTES
+ || config.getDppPrivateEcKey().length > MAX_URL_BYTES
+ || config.getDppNetAccessKey().length > MAX_URL_BYTES) {
+ return false;
+ }
// TBD: Validate some enterprise params as well in the future here.
return true;
}
+ private static boolean validateStringField(String field, int maxLength) {
+ return field == null || field.length() <= maxLength;
+ }
+
+ private static boolean validatePasspoint(WifiConfiguration config) {
+ if (!validateStringField(config.FQDN, PasspointConfiguration.MAX_STRING_LENGTH)) {
+ return false;
+ }
+ if (!validateStringField(config.providerFriendlyName,
+ PasspointConfiguration.MAX_STRING_LENGTH)) {
+ return false;
+ }
+ if (!validateRoamingConsortiumIds(config.roamingConsortiumIds)) {
+ return false;
+ }
+ if (!validateUpdateIdentifier(config.updateIdentifier)) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean validateUpdateIdentifier(String updateIdentifier) {
+ if (TextUtils.isEmpty(updateIdentifier)) {
+ return true;
+ }
+ try {
+ Integer.valueOf(updateIdentifier);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean validateNetworkSelectionStatus(
+ WifiConfiguration.NetworkSelectionStatus status) {
+ if (status == null) {
+ return false;
+ }
+ return validateStringField(status.getConnectChoice(), MAX_STRING_LENGTH)
+ && validateBssid(status.getNetworkSelectionBSSID());
+ }
+
+ private static boolean validateRoamingConsortiumIds(long[] roamingConsortiumIds) {
+ if (roamingConsortiumIds != null) {
+ if (roamingConsortiumIds.length > MAX_NUMBER_OF_OI) {
+ Log.d(TAG, "too many Roaming Consortium Organization Identifiers in the "
+ + "profile");
+ return false;
+ }
+ for (long oi : roamingConsortiumIds) {
+ if (oi < 0 || oi > MAX_OI_VALUE) {
+ Log.d(TAG, "Organization Identifiers is out of range");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static boolean validateSecurityParameters(List<SecurityParams> paramsList) {
+ Set<Integer> uniqueSecurityTypes = new HashSet<>(SECURITY_TYPE_NUM + 1);
+ for (SecurityParams params : paramsList) {
+ int securityType = params.getSecurityType();
+ if (securityType < 0 || securityType > SECURITY_TYPE_NUM) {
+ return false;
+ }
+ if (uniqueSecurityTypes.contains(securityType)) {
+ return false;
+ }
+ uniqueSecurityTypes.add(securityType);
+ }
+ return true;
+
+ }
+
private static boolean validateBssidPattern(
Pair<MacAddress, MacAddress> bssidPatternMatcher) {
if (bssidPatternMatcher == null) return true;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 83d737d..22396b6 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -3740,6 +3740,11 @@
boolean isCamera = mWifiPermissionsUtil.checkCameraPermission(callingUid);
boolean isSystem = mWifiPermissionsUtil.isSystem(packageName, callingUid);
boolean isPrivileged = isPrivileged(callingPid, callingUid);
+ if (!isPrivileged && !isSystem && !isAdmin && config.getBssidAllowlistInternal() != null) {
+ mLog.info("addOrUpdateNetwork with allow bssid list is not allowed for uid=%")
+ .c(callingUid).flush();
+ return -1;
+ }
if (!isTargetSdkLessThanQOrPrivileged(packageName, callingPid, callingUid)) {
mLog.info("addOrUpdateNetwork not allowed for uid=%").c(callingUid).flush();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 0722d3e..1567ed4 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -18,6 +18,7 @@
import static android.net.wifi.WifiEnterpriseConfig.OCSP_NONE;
import static android.net.wifi.WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
+import static android.net.wifi.hotspot2.PasspointConfiguration.MAX_URL_BYTES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -53,6 +54,7 @@
import org.mockito.MockitoSession;
import org.mockito.quality.Strictness;
+import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
@@ -77,6 +79,7 @@
new UserInfo(CURRENT_USER_ID, "owner", 0),
new UserInfo(CURRENT_USER_MANAGED_PROFILE_USER_ID, "managed profile", 0));
private static final long SUPPORTED_FEATURES_ALL = Long.MAX_VALUE;
+ private final String mGeneratedString256 = "a".repeat(256);
private MockitoSession mSession;
@@ -1592,4 +1595,76 @@
assertTrue(WifiConfigurationUtil.isConfigLinkable(saeConfig));
assertFalse(WifiConfigurationUtil.isConfigLinkable(saeDisabledConfig));
}
+
+ @Test
+ public void testWepKeyOnNonWepConfig() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ pskConfig.wepKeys = new String[4];
+ pskConfig.wepKeys[0] = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidFqdnAndFriendlyName() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+
+ pskConfig.FQDN = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+
+ pskConfig.FQDN = null;
+ pskConfig.providerFriendlyName = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidDhcpAndGtw() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ pskConfig.dhcpServer = TEST_BSSID;
+ pskConfig.defaultGwMacAddress = TEST_BSSID;
+ assertTrue(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ pskConfig.dhcpServer = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ pskConfig.dhcpServer = TEST_BSSID;
+ pskConfig.defaultGwMacAddress = mGeneratedString256;
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidSecurityParameter() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ List<SecurityParams> securityParamsList = new ArrayList<>();
+ securityParamsList.add(SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+ securityParamsList.add(SecurityParams.createSecurityParamsBySecurityType(
+ WifiConfiguration.SECURITY_TYPE_PSK));
+
+ pskConfig.setSecurityParams(securityParamsList);
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidUserConnectChoice() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ String generatedString513 = "a".repeat(513);
+ pskConfig.getNetworkSelectionStatus().setConnectChoice(generatedString513);
+
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
+
+ @Test
+ public void testInvalidDppConfig() {
+ WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork();
+ String generatedString = "a".repeat(MAX_URL_BYTES + 1);
+ pskConfig.setDppConfigurator(generatedString.getBytes(StandardCharsets.UTF_8));
+ assertFalse(WifiConfigurationUtil.validate(pskConfig, SUPPORTED_FEATURES_ALL,
+ WifiConfigurationUtil.VALIDATE_FOR_ADD));
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index c06ae93..df32b92 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -6483,6 +6483,31 @@
}
/**
+ * Verify that add or update networks is allowed for apps targeting below Q SDK.
+ */
+ @Test
+ public void testAddOrUpdateNetworkWithBssidAllowListIsNotAllowedForAppsNotPrivileged()
+ throws Exception {
+ doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager)
+ .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
+ when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt(), any(), eq(false))).thenReturn(
+ new NetworkUpdateResult(0));
+ when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(),
+ eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ config.setBssidAllowlist(Collections.emptyList());
+ mLooper.startAutoDispatch();
+ assertEquals(-1,
+ mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME, mAttribution));
+ mLooper.stopAutoDispatchAndIgnoreExceptions();
+
+ verifyCheckChangePermission(TEST_PACKAGE_NAME);
+ verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), any(), eq(false));
+ verify(mWifiMetrics, never()).incrementNumAddOrUpdateNetworkCalls();
+ }
+
+ /**
* Verify that add or update networks is not allowed for apps targeting below Q SDK
* when DISALLOW_ADD_WIFI_CONFIG user restriction is set.
*/