• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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