1 /* 2 * Copyright (C) 2023 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_2023_21256; 18 19 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 20 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assume.assumeNoException; 23 import static org.junit.Assume.assumeTrue; 24 25 import android.app.Instrumentation; 26 import android.app.UiAutomation; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.content.pm.ResolveInfo; 31 import android.os.UserHandle; 32 import android.provider.Settings; 33 34 import androidx.test.runner.AndroidJUnit4; 35 import androidx.test.uiautomator.By; 36 import androidx.test.uiautomator.UiDevice; 37 import androidx.test.uiautomator.Until; 38 39 import com.android.bedstead.nene.utils.Poll; 40 import com.android.internal.app.PlatLogoActivity; 41 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 45 import java.time.Duration; 46 import java.util.regex.Pattern; 47 48 @RunWith(AndroidJUnit4.class) 49 public class DeviceTest { 50 private UiDevice mUiDevice; 51 52 @Test testSettingsHomePageActivityFromWorkProfile()53 public void testSettingsHomePageActivityFromWorkProfile() { 54 UiAutomation uiAutomation = null; 55 try { 56 final long timeoutMs = 10_000L; 57 Instrumentation instrumentation = getInstrumentation(); 58 uiAutomation = instrumentation.getUiAutomation(); 59 mUiDevice = UiDevice.getInstance(instrumentation); 60 Context context = instrumentation.getContext(); 61 String defaultSettingsPkg = "com.android.settings"; 62 String platLogoActivityName = PlatLogoActivity.class.getName(); 63 String dumpsysActivityCmd = "dumpsys activity " + platLogoActivityName; 64 65 // Retrieve Settings app's package name 66 uiAutomation.adoptShellPermissionIdentity( 67 android.Manifest.permission.INTERACT_ACROSS_USERS); 68 ResolveInfo info = 69 context.getPackageManager() 70 .resolveActivityAsUser( 71 new Intent(Settings.ACTION_SETTINGS), 72 PackageManager.MATCH_SYSTEM_ONLY, 73 UserHandle.USER_SYSTEM); 74 if (info != null && info.activityInfo != null) { 75 defaultSettingsPkg = info.activityInfo.packageName; 76 } 77 78 // Attempt to launch PlatLogoActivity using Settings app 79 Intent intent = 80 Intent.createChooser( 81 new Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY) 82 .setClassName( 83 defaultSettingsPkg, 84 defaultSettingsPkg 85 + ".homepage.SettingsHomepageActivity") 86 .putExtra( 87 Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, 88 new Intent(Intent.ACTION_CHOOSER) 89 .toUri(Intent.URI_INTENT_SCHEME)) 90 .putExtra( 91 Intent.EXTRA_INTENT, 92 new Intent() 93 .setClassName("android", platLogoActivityName)) 94 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 95 "chooserTitle"); 96 context.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 97 98 // Click Settings from ChooserActivity 99 String settingsText = "Settings"; 100 assumeTrue(mUiDevice.wait(Until.hasObject(By.text(settingsText)), timeoutMs)); 101 mUiDevice.findObject(By.text(settingsText)).click(); 102 103 Pattern resumedTruePattern = 104 Pattern.compile(".*mResumed=true.*", Pattern.CASE_INSENSITIVE); 105 106 // Wait for dumpsys result to update 107 Poll.forValue( 108 () -> 109 resumedTruePattern 110 .matcher(mUiDevice.executeShellCommand(dumpsysActivityCmd)) 111 .find()) 112 .toBeEqualTo(true) 113 .timeout(Duration.ofMillis(timeoutMs)) 114 .await(); 115 116 // Fail test if PlatLogoActivity was launched 117 assertFalse( 118 "Device is vulnerable to b/250589026, Unexported activities can be launched" 119 + "using ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY from a workProfile", 120 resumedTruePattern 121 .matcher(mUiDevice.executeShellCommand(dumpsysActivityCmd)) 122 .find()); 123 } catch (Exception e) { 124 assumeNoException(e); 125 } finally { 126 try { 127 uiAutomation.dropShellPermissionIdentity(); 128 mUiDevice.pressHome(); 129 } catch (Exception e) { 130 // Ignore exceptions as the test has finished 131 } 132 } 133 } 134 } 135