• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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_2022_20143;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assume.assumeNoException;
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.app.AutomaticZenRule;
24 import android.app.Instrumentation;
25 import android.app.NotificationManager;
26 import android.app.UiAutomation;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.net.Uri;
30 import android.platform.test.annotations.AsbSecurityTest;
31 import androidx.test.InstrumentationRegistry;
32 import androidx.test.runner.AndroidJUnit4;
33 
34 import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.util.ArrayList;
40 
41 @RunWith(AndroidJUnit4.class)
42 public class CVE_2022_20143 extends StsExtraBusinessLogicTestCase {
43 
44     @AsbSecurityTest(cveBugId = 220735360)
45     @Test
testPocCVE_2022_20143()46     public void testPocCVE_2022_20143() {
47         final int ruleLimitPerPackage = 200;
48         final int timeoutDuration = 5000;
49         final int waitDuration = 100;
50         Instrumentation instrumentation;
51         Context context;
52         NotificationManager notificationManager = null;
53         String packageName = null;
54         UiAutomation uiautomation = null;
55         boolean isVulnerable = true;
56         boolean notificationPolicyAccessGranted = false;
57         int automaticZenRules = 0;
58         ArrayList<String> ruleIds = new ArrayList<>();
59         try {
60             instrumentation = InstrumentationRegistry.getInstrumentation();
61             context = instrumentation.getContext();
62             notificationManager = context.getSystemService(NotificationManager.class);
63             packageName = context.getPackageName();
64             uiautomation = instrumentation.getUiAutomation();
65             uiautomation.executeShellCommand("cmd notification allow_dnd " + packageName);
66             long startTime = System.currentTimeMillis();
67             while (System.currentTimeMillis() - startTime < timeoutDuration) {
68                 // busy wait until notification policy access is granted
69                 if (notificationManager.isNotificationPolicyAccessGranted()) {
70                     notificationPolicyAccessGranted = true;
71                     break;
72                 }
73                 Thread.sleep(waitDuration);
74             }
75             // storing the number of automaticZenRules present before test run
76             automaticZenRules = notificationManager.getAutomaticZenRules().size();
77             ComponentName component =
78                     new ComponentName(packageName, PocActivity.class.getCanonicalName());
79             for (int i = 0; i < ruleLimitPerPackage; ++i) {
80                 Uri conditionId = Uri.parse("condition://android/" + i);
81                 AutomaticZenRule rule = new AutomaticZenRule("ZenRuleName" + i, null, component,
82                         conditionId, null, NotificationManager.INTERRUPTION_FILTER_ALL, true);
83                 String id = notificationManager.addAutomaticZenRule(rule);
84                 ruleIds.add(id);
85             }
86         } catch (Exception e) {
87             if (e instanceof IllegalArgumentException) {
88                 isVulnerable = false; // expected with fix
89             } else {
90                 assumeNoException(e);
91             }
92         } finally {
93             try {
94                 if (notificationPolicyAccessGranted) {
95                     /* retrieving the total number of automaticZenRules added by test so that the */
96                     /* test fails only if all automaticZenRules were added successfully */
97                     automaticZenRules =
98                             notificationManager.getAutomaticZenRules().size() - automaticZenRules;
99                     for (String id : ruleIds) {
100                         notificationManager.removeAutomaticZenRule(id);
101                     }
102                     uiautomation
103                             .executeShellCommand("cmd notification disallow_dnd " + packageName);
104                 }
105                 boolean allZenRulesAdded = ruleLimitPerPackage == automaticZenRules;
106                 assumeTrue("Notification policy access not granted",
107                         notificationPolicyAccessGranted);
108                 assertFalse(
109                         "Vulnerable to b/220735360!! System can be corrupted by adding many"
110                                 + " AutomaticZenRules via NotificationManager#addAutomaticZenRule",
111                         isVulnerable && allZenRulesAdded);
112             } catch (Exception e) {
113                 assumeNoException(e);
114             }
115         }
116     }
117 }
118