From 761fec1b48fa7329dc40713ccfe0637dd9dd20a9 Mon Sep 17 00:00:00 2001 From: xshu Date: Wed, 22 Apr 2020 18:36:54 -0700 Subject: Randomize sta MAC address upon start This is needed to prevent factory MAC leakage for features like DPP, which at some point sends packets using the currently programed MAC. Bug: 154393320 Test: com.android.server.wifi Change-Id: I3c5a388545e049daa8430af5010f4b2386210ac9 --- .../com/android/server/wifi/ClientModeImpl.java | 2 ++ .../android/server/wifi/ClientModeImplTest.java | 32 ++++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 00e02df4a..7d89505e3 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -67,6 +67,7 @@ import android.net.shared.Inet4AddressUtils; import android.net.shared.Layer2Information; import android.net.shared.ProvisioningConfiguration; import android.net.shared.ProvisioningConfiguration.ScanResultInfo; +import android.net.util.MacAddressUtils; import android.net.util.NetUtils; import android.net.wifi.IActionListener; import android.net.wifi.INetworkRequestMatchCallback; @@ -3549,6 +3550,7 @@ public class ClientModeImpl extends StateMachine { mLastSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; mLastSimBasedConnectionCarrierName = null; mLastSignalLevel = -1; + mWifiNative.setMacAddress(mInterfaceName, MacAddressUtils.createRandomUnicastAddress()); mWifiInfo.setMacAddress(mWifiNative.getMacAddress(mInterfaceName)); // TODO: b/79504296 This broadcast has been deprecated and should be removed sendSupplicantConnectionChangedBroadcast(true); diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 2923315d6..0c48521e1 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -2646,7 +2646,7 @@ public class ClientModeImplTest extends WifiBaseTest { * 3. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_PERSISTENT and * 4. randomized MAC for the network to connect to is different from the current MAC. * - * Then the current MAC does not change when CMD_START_CONNECT executes. + * The factory MAC address is used for the connection. */ @Test public void testConnectedMacRandomizationNotSupported() throws Exception { @@ -2657,11 +2657,7 @@ public class ClientModeImplTest extends WifiBaseTest { assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState()); connect(); - verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_LOCAL_MAC_ADDRESS); - verify(mWifiMetrics, never()) - .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); - } /** @@ -2746,9 +2742,8 @@ public class ClientModeImplTest extends WifiBaseTest { * Verifies that when * 1. connected MAC randomization is on and * 2. macRandomizationSetting of the WifiConfiguration is RANDOMIZATION_NONE and - * 3. current MAC is the factory MAC. * - * Then MAC change should not occur when CMD_START_CONNECT executes. + * Then the factory MAC should be used to connect to the network. * @throws Exception */ @Test @@ -2765,9 +2760,6 @@ public class ClientModeImplTest extends WifiBaseTest { mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); mLooper.dispatchAll(); - verify(mWifiNative, never()).setMacAddress(WIFI_IFACE_NAME, TEST_GLOBAL_MAC_ADDRESS); - verify(mWifiMetrics, never()) - .logStaEvent(eq(StaEvent.TYPE_MAC_CHANGE), any(WifiConfiguration.class)); assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getWifiInfo().getMacAddress()); } @@ -2812,7 +2804,8 @@ public class ClientModeImplTest extends WifiBaseTest { mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID); mLooper.dispatchAll(); - verify(mWifiNative, never()).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class)); + // setMacAddress is invoked once when ClientModeImpl starts to prevent leak of factory MAC. + verify(mWifiNative).setMacAddress(eq(WIFI_IFACE_NAME), any(MacAddress.class)); } /** @@ -3828,7 +3821,7 @@ public class ClientModeImplTest extends WifiBaseTest { initializeCmi(); initializeAndAddNetworkAndVerifySuccess(); when(mWifiNative.getFactoryMacAddress(WIFI_IFACE_NAME)).thenReturn(null); - assertEquals(TEST_GLOBAL_MAC_ADDRESS.toString(), mCmi.getFactoryMacAddress()); + mCmi.getFactoryMacAddress(); verify(mWifiNative).getFactoryMacAddress(anyString()); verify(mWifiNative, times(2)).getMacAddress(WIFI_IFACE_NAME); } @@ -3844,6 +3837,21 @@ public class ClientModeImplTest extends WifiBaseTest { WifiManager.DEVICE_MOBILITY_STATE_STATIONARY); } + /** + * Verify the MAC address is being randomized at start to prevent leaking the factory MAC. + */ + @Test + public void testRandomizeMacAddressOnStart() throws Exception { + ArgumentCaptor macAddressCaptor = ArgumentCaptor.forClass(MacAddress.class); + loadComponentsInStaMode(); + verify(mWifiNative).setMacAddress(anyString(), macAddressCaptor.capture()); + MacAddress currentMac = macAddressCaptor.getValue(); + + assertNotEquals("The currently programmed MAC address should be different from the factory " + + "MAC address after ClientModeImpl starts", + mCmi.getFactoryMacAddress(), currentMac.toString()); + } + /** * Verify bugreport will be taken when get IP_REACHABILITY_LOST */ -- cgit v1.2.3