summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxshu <xshu@google.com>2020-01-14 12:12:22 -0800
committerEtan Cohen <etancohen@google.com>2020-01-15 21:30:47 +0000
commitb4486b2a1bce042384b6da156aced9c8ff76b5ec (patch)
tree0ae1d069858f6176169ce18af2034965e0a9861b
parent84c9ba1c7c5271215d7a50ef23c5d57c0b38bbdb (diff)
fix soft reboot caused by KeyStore exception
The Mac handle obtained from AndroidKeyStore is sometimes invalidated by the AndroidKeyStore based on some LRU technique. This change make sure that we always get a valid handle. And adds exception handling to make sure a crash will not happen for the same reason again. If KeyStore continuously fails to generate MAC address, we will use locally generated MAC as it is the next best option. Bug: 146203882 Bug: 140065828 Test: atest FrameworksWifiTests Merged-In: I8a3b810ba95898a96d81fe57979db4787e1a46c4 Change-Id: I8a3b810ba95898a96d81fe57979db4787e1a46c4 (cherry-picked from 0b3eca3c05190e5824638f3da25b8b3167dc9d60)
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java21
-rw-r--r--service/java/com/android/server/wifi/WifiConfigurationUtil.java10
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java22
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java18
4 files changed, 60 insertions, 11 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 4ac4fb7a6..fb84cf0b1 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -76,8 +76,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.crypto.Mac;
-
/**
* This class provides the APIs to manage configured Wi-Fi networks.
* It deals with the following:
@@ -268,7 +266,6 @@ public class WifiConfigManager {
*/
private final Context mContext;
private final Clock mClock;
- private final Mac mMac;
private final UserManager mUserManager;
private final BackupManagerProxy mBackupManagerProxy;
private final TelephonyManager mTelephonyManager;
@@ -449,11 +446,6 @@ public class WifiConfigManager {
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to resolve SystemUI's UID.");
}
- mMac = WifiConfigurationUtil.obtainMacRandHashFunction(Process.WIFI_UID);
- if (mMac == null) {
- Log.wtf(TAG, "Failed to obtain secret for MAC randomization."
- + " All randomized MAC addresses are lost!");
- }
}
/**
@@ -505,7 +497,18 @@ public class WifiConfigManager {
mRandomizedMacAddressMapping.remove(config.getSsidAndSecurityTypeString());
}
}
- return WifiConfigurationUtil.calculatePersistentMacForConfiguration(config, mMac);
+ MacAddress result = WifiConfigurationUtil.calculatePersistentMacForConfiguration(config,
+ WifiConfigurationUtil.obtainMacRandHashFunction(Process.WIFI_UID));
+ if (result == null) {
+ result = WifiConfigurationUtil.calculatePersistentMacForConfiguration(config,
+ WifiConfigurationUtil.obtainMacRandHashFunction(Process.WIFI_UID));
+ }
+ if (result == null) {
+ Log.wtf(TAG, "Failed to generate MAC address from KeyStore even after retrying. "
+ + "Using locally generated MAC address instead.");
+ result = MacAddress.createRandomUnicastAddress();
+ }
+ return result;
}
/**
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index c59d4faf7..69a655bd4 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -259,8 +259,14 @@ public class WifiConfigurationUtil {
if (config == null || hashFunction == null) {
return null;
}
- byte[] hashedBytes = hashFunction.doFinal(
- config.getSsidAndSecurityTypeString().getBytes(StandardCharsets.UTF_8));
+ byte[] hashedBytes;
+ try {
+ hashedBytes = hashFunction.doFinal(
+ config.getSsidAndSecurityTypeString().getBytes(StandardCharsets.UTF_8));
+ } catch (ProviderException | IllegalStateException e) {
+ Log.e(TAG, "Failure in calculatePersistentMac", e);
+ return null;
+ }
ByteBuffer bf = ByteBuffer.wrap(hashedBytes);
long longFromSsid = bf.getLong();
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index dad88f3c0..ce1c6b2ee 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -292,6 +292,28 @@ public class WifiConfigManagerTest {
}
/**
+ * Verify that a randomized MAC address is generated even if the KeyStore operation fails.
+ */
+ @Test
+ public void testRandomizedMacIsGeneratedEvenIfKeyStoreFails() {
+ when(WifiConfigurationUtil.calculatePersistentMacForConfiguration(
+ any(), any())).thenReturn(null);
+
+ // Try adding a network.
+ WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+ List<WifiConfiguration> networks = new ArrayList<>();
+ networks.add(openNetwork);
+ verifyAddNetworkToWifiConfigManager(openNetwork);
+ List<WifiConfiguration> retrievedNetworks =
+ mWifiConfigManager.getConfiguredNetworksWithPasswords();
+
+ // Verify that despite KeyStore returning null, we are still getting a valid MAC address.
+ assertEquals(1, retrievedNetworks.size());
+ assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS,
+ retrievedNetworks.get(0).getRandomizedMacAddress().toString());
+ }
+
+ /**
* Verifies the addition of a single network using
* {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
*/
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
index 7173dae5b..6687390c1 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationUtilTest.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
import android.content.pm.UserInfo;
import android.net.IpConfiguration;
@@ -34,6 +35,7 @@ import androidx.test.filters.SmallTest;
import org.junit.Test;
+import java.security.ProviderException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
@@ -991,6 +993,22 @@ public class WifiConfigurationUtilTest {
}
}
+ /**
+ * Verify the java.security.ProviderException is caught.
+ */
+ @Test
+ public void testCalculatePersistentMacCatchesException() {
+ Mac hashFunction = mock(Mac.class);
+ when(hashFunction.doFinal(any())).thenThrow(new ProviderException("error occurred"));
+ try {
+ WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
+ assertNull(WifiConfigurationUtil.calculatePersistentMacForConfiguration(config,
+ hashFunction));
+ } catch (Exception e) {
+ fail("Exception not caught.");
+ }
+ }
+
private static class EnterpriseConfig {
public String eap;
public String phase2;