1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.cts.CVE_2024_31332; 18 19 import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; 20 21 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 22 23 import static com.android.sts.common.DumpsysUtils.isActivityVisible; 24 import static com.android.sts.common.SystemUtil.poll; 25 26 import static com.google.common.truth.Truth.assertWithMessage; 27 import static com.google.common.truth.TruthJUnit.assume; 28 29 import android.app.admin.DevicePolicyManager; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.net.Uri; 34 import android.net.wifi.WifiManager; 35 import android.provider.Settings; 36 37 import androidx.test.runner.AndroidJUnit4; 38 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.util.function.BooleanSupplier; 43 44 @RunWith(AndroidJUnit4.class) 45 public class DeviceTest { 46 47 @Test testCVE_2024_31332()48 public void testCVE_2024_31332() { 49 try { 50 // Check for easy connect support 51 final Context context = getApplicationContext(); 52 final WifiManager wifiManager = context.getSystemService(WifiManager.class); 53 assume().withMessage( 54 "Current device does not support easy connect." 55 + " Hence, CTS for CVE-2024-31332 cannot be validated.") 56 .that(wifiManager.isEasyConnectSupported()) 57 .isTrue(); 58 59 // Fetch 'DeviceOwnerComponentName' from 'DevicePolicyManager' 60 final DevicePolicyManager devicePolicyManager = 61 context.getSystemService(DevicePolicyManager.class); 62 final ComponentName deviceOwnerComponentName = 63 devicePolicyManager.getDeviceOwnerComponentOnCallingUser(); 64 assume().withMessage( 65 "Unable to get 'DeviceOwnerComponentName' from DevicePolicyManager") 66 .that(deviceOwnerComponentName) 67 .isNotNull(); 68 69 // Check whether 'PocDeviceAdminReceiver' is set as device owner 70 final ComponentName pocDeviceAdminReceiverComponentName = 71 new ComponentName(context, PocDeviceAdminReceiver.class); 72 assume().withMessage("Unable to set 'PocDeviceAdminReceiver' as device owner") 73 .that(deviceOwnerComponentName.flattenToString()) 74 .isEqualTo(pocDeviceAdminReceiverComponentName.flattenToString()); 75 76 try (AutoCloseable withDisallowAddWifiConfigRestriction = 77 withDisallowAddWifiConfigRestriction( 78 devicePolicyManager, pocDeviceAdminReceiverComponentName)) { 79 // Launch activity to reproduce the vulnerability 80 final int cveBugId = 299931076; 81 final String mockQrCode = String.format("DPP:I:%d;K:%d;", cveBugId, cveBugId); 82 final Intent intent = new Intent(Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_URI); 83 context.startActivity( 84 intent.setData(Uri.parse(mockQrCode)) 85 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 86 87 // Without fix 'WifiDppConfiguratorActivity' launches and test fails 88 final String activityName = 89 intent.resolveActivity(context.getPackageManager()).flattenToString(); 90 assertWithMessage( 91 "Device is vulnerable to b/299931076 !! Connect to an untrusted" 92 + " Wi-Fi network through WifiDppConfiguratorActivity.") 93 .that(poll(() -> isActivityVisible(activityName))) 94 .isFalse(); 95 } 96 } catch (Exception e) { 97 assume().that(e).isNull(); 98 } 99 } 100 withDisallowAddWifiConfigRestriction( DevicePolicyManager devicePolicyManager, ComponentName componentName)101 private AutoCloseable withDisallowAddWifiConfigRestriction( 102 DevicePolicyManager devicePolicyManager, ComponentName componentName) throws Exception { 103 // Return if 'DISALLOW_ADD_WIFI_CONFIG' restriction is already set 104 final BooleanSupplier userRestriction = 105 () -> 106 devicePolicyManager 107 .getUserRestrictions(componentName) 108 .getBoolean(DISALLOW_ADD_WIFI_CONFIG); 109 if (userRestriction.getAsBoolean()) { 110 return () -> {}; 111 } 112 113 // Set 'DISALLOW_ADD_WIFI_CONFIG' restriction 114 devicePolicyManager.addUserRestriction(componentName, DISALLOW_ADD_WIFI_CONFIG); 115 assume().withMessage("Failed to set 'DISALLOW_ADD_WIFI_CONFIG' restriction") 116 .that(userRestriction.getAsBoolean()) 117 .isTrue(); 118 119 // Remove 'DISALLOW_ADD_WIFI_CONFIG' restriction 120 return () -> 121 devicePolicyManager.clearUserRestriction(componentName, DISALLOW_ADD_WIFI_CONFIG); 122 } 123 } 124