Skip to content

Commit 3b7fa6a

Browse files
Treehugger Robotandroid-build-merge-worker-robot
authored andcommitted
Merge "CTS test for Android Security b/179042963" into tm-dev am: 6f4b53d am: 9186d11
Original change: https://googleplex-android-review.googlesource.com/c/platform/cts/+/24240210 Change-Id: Ia6d3ee197d6d9d0204bd5922acda00e00bf1d2af Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
2 parents 99ff1e1 + 9186d11 commit 3b7fa6a

6 files changed

Lines changed: 293 additions & 0 deletions

File tree

tests/tests/security/AndroidManifest.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,19 @@
261261
</intent-filter>
262262
</service>
263263

264+
<activity android:name="android.security.cts.CVE_2021_0600.PocActivity" />
265+
266+
<receiver android:name="android.security.cts.CVE_2021_0600.PocDeviceAdminReceiver"
267+
android:permission="android.permission.BIND_DEVICE_ADMIN"
268+
android:exported="true">
269+
<meta-data
270+
android:name="android.app.device_admin"
271+
android:resource="@xml/device_admin_cve_2021_0600" />
272+
<intent-filter>
273+
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
274+
</intent-filter>
275+
</receiver>
276+
264277
<activity android:name="android.security.cts.CVE_2023_20953.PocActivity"
265278
android:exported="true" />
266279

tests/tests/security/res/values/strings.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,19 @@
4444
<string name="cve_2023_20960_uriStringComponent">component=</string>
4545
<string name="cve_2023_20960_uriStringIntent">intent:#Intent;</string>
4646
<string name="cve_2023_20960_uriStringSuffix">;end</string>
47+
48+
<!-- CVE-2021-0600 -->
49+
<string name="cve_2021_0600_action">CVE_2021_0600_action</string>
50+
<string name="cve_2021_0600_errorCreateCharSeq">Failed to create a charsequence to contain HTML
51+
text</string>
52+
<string name="cve_2021_0600_failMsg">Vulnerable to b/179042963 !!</string>
53+
<string name="cve_2021_0600_intentNotFound">Failed to resolve %1$s</string>
54+
<string name="cve_2021_0600_keyException">exception</string>
55+
<string name="cve_2021_0600_keyHtml">html</string>
56+
<string name="cve_2021_0600_noException">noException</string>
57+
<string name="cve_2021_0600_pattern">.*CVE_2021_0600_EXPN.*</string>
58+
<string name="cve_2021_0600_patternNotFound">UI element with text pattern %1$s not found
59+
</string>
60+
<string name="cve_2021_0600_targetText">CVE_2021_0600_EXPN</string>
61+
<string name="cve_2021_0600_targetTextHtml"><![CDATA[<h1>CVE_2021_0600_EXPN</h1>]]></string>
4762
</resources>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version ="1.0" encoding ="utf-8"?>
2+
<!--
3+
Copyright 2023 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
<device-admin>
19+
<uses-policies />
20+
</device-admin>
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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_2021_0600;
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.content.BroadcastReceiver;
27+
import android.content.Context;
28+
import android.content.Intent;
29+
import android.content.IntentFilter;
30+
import android.graphics.Rect;
31+
import android.platform.test.annotations.AsbSecurityTest;
32+
import android.security.cts.R;
33+
import android.support.test.uiautomator.By;
34+
import android.support.test.uiautomator.BySelector;
35+
import android.support.test.uiautomator.UiDevice;
36+
import android.support.test.uiautomator.UiObject2;
37+
import android.support.test.uiautomator.Until;
38+
39+
import androidx.test.runner.AndroidJUnit4;
40+
41+
import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
42+
43+
import java.util.concurrent.CompletableFuture;
44+
import java.util.concurrent.TimeUnit;
45+
import java.util.regex.Pattern;
46+
47+
import org.junit.Test;
48+
import org.junit.runner.RunWith;
49+
50+
@RunWith(AndroidJUnit4.class)
51+
public class CVE_2021_0600 extends StsExtraBusinessLogicTestCase {
52+
private static final long TIMEOUT_MS = 5000;
53+
private CompletableFuture<String> mPocActivityReturn;
54+
private UiDevice mDevice;
55+
private Context mContext;
56+
57+
// b/179042963
58+
// Vulnerable package : com.android.settings (As per AOSP code)
59+
// Vulnerable app : Settings.apk (As per AOSP code)
60+
@AsbSecurityTest(cveBugId = 179042963)
61+
@Test
62+
public void testPocCVE_2021_0600() {
63+
try {
64+
Instrumentation instrumentation = getInstrumentation();
65+
mDevice = UiDevice.getInstance(instrumentation);
66+
mContext = instrumentation.getContext();
67+
68+
// Registering a broadcast receiver to receive broadcast from PocActivity.
69+
mPocActivityReturn = new CompletableFuture<>();
70+
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
71+
@Override
72+
public void onReceive(Context context, Intent intent) {
73+
try {
74+
mPocActivityReturn.complete(intent.getStringExtra(
75+
mContext.getString(R.string.cve_2021_0600_keyException)));
76+
} catch (Exception e) {
77+
// ignore.
78+
}
79+
}
80+
};
81+
mContext.registerReceiver(broadcastReceiver,
82+
new IntentFilter(mContext.getString(R.string.cve_2021_0600_action)));
83+
84+
// Launch the PocActivity which in turn starts DeviceAdminAdd activity with normal
85+
// text as 'explanation'.
86+
Intent intent = new Intent(mContext, PocActivity.class);
87+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
88+
intent.putExtra(mContext.getString(R.string.cve_2021_0600_keyHtml), false);
89+
mContext.startActivity(intent);
90+
String pocActivityException = mPocActivityReturn.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
91+
assumeTrue(pocActivityException, pocActivityException.trim()
92+
.equals(mContext.getString(R.string.cve_2021_0600_noException)));
93+
94+
// Get the height of the normal text with no formatting. Because width is same both
95+
// with and without fix, height is being used for comparing the with and without
96+
// fix behaviour.
97+
int heightWoHtml = getVulnerableUIHeight();
98+
assumeTrue(heightWoHtml != -1);
99+
100+
// Launch PocActivity again such that DeviceAdminAdd activity starts with formatted text
101+
// this time.
102+
mPocActivityReturn = new CompletableFuture<>();
103+
intent.putExtra(mContext.getString(R.string.cve_2021_0600_keyHtml), true);
104+
mContext.startActivity(intent);
105+
pocActivityException = mPocActivityReturn.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
106+
assumeTrue(pocActivityException, pocActivityException
107+
.equalsIgnoreCase(mContext.getString(R.string.cve_2021_0600_noException)));
108+
109+
// Get the height of HTML text with formatting.
110+
int heightWithHtml = getVulnerableUIHeight();
111+
assumeTrue(heightWithHtml != -1);
112+
113+
// On vulnerable device, the text displayed on the screen will be HTML formatted, so
114+
// there will be considerable increase in height of the text due to <h1> tag, if there
115+
// is at least 20% increase in height, the test will fail.
116+
assertFalse(mContext.getString(R.string.cve_2021_0600_failMsg),
117+
heightWithHtml > 1.2 * heightWoHtml);
118+
} catch (Exception e) {
119+
assumeNoException(e);
120+
}
121+
}
122+
123+
private int getVulnerableUIHeight() {
124+
Pattern pattern = Pattern.compile(mContext.getString(R.string.cve_2021_0600_pattern),
125+
Pattern.CASE_INSENSITIVE);
126+
BySelector selector = By.text(pattern);
127+
assumeTrue(mContext.getString(R.string.cve_2021_0600_patternNotFound, pattern),
128+
mDevice.wait(Until.hasObject(selector), TIMEOUT_MS));
129+
UiObject2 obj = mDevice.findObject(selector);
130+
if (obj != null && obj.getText() != null
131+
&& obj.getText().contains(mContext.getString(R.string.cve_2021_0600_targetText))) {
132+
Rect bounds = obj.getVisibleBounds();
133+
return bounds.bottom - bounds.top;
134+
}
135+
return -1;
136+
}
137+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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_2021_0600;
18+
19+
import static org.junit.Assume.assumeFalse;
20+
import static org.junit.Assume.assumeNotNull;
21+
22+
import android.app.Activity;
23+
import android.app.admin.DevicePolicyManager;
24+
import android.content.ComponentName;
25+
import android.content.Intent;
26+
import android.os.Bundle;
27+
import android.security.cts.R;
28+
import android.text.Html;
29+
30+
// The vulnerable activity ADD_DEVICE_ADMIN can't be started as a new task hence PocActivity is
31+
// created to launch it.
32+
public class PocActivity extends Activity {
33+
34+
@Override
35+
protected void onCreate(Bundle savedInstanceState) {
36+
try {
37+
super.onCreate(savedInstanceState);
38+
39+
// Create an intent to launch DeviceAdminAdd activity.
40+
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
41+
assumeNotNull(getString(R.string.cve_2021_0600_intentNotFound, intent),
42+
intent.resolveActivity(getPackageManager()));
43+
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
44+
new ComponentName(this, PocDeviceAdminReceiver.class));
45+
46+
// For adding an extra 'explanation' to the intent, creating a charsequence object.
47+
CharSequence seq = Html.fromHtml(getString(R.string.cve_2021_0600_targetText));
48+
if (getIntent().getBooleanExtra(getString(R.string.cve_2021_0600_keyHtml), false)) {
49+
seq = Html.fromHtml(getString(R.string.cve_2021_0600_targetTextHtml));
50+
}
51+
52+
// Using Html.fromHtml() causes whitespaces to occur at the start/end of the text which
53+
// are unwanted. Remove the whitespace characters if any at the start and end of the
54+
// charsequence.
55+
int end = seq.length() - 1;
56+
int start = 0;
57+
while ((Character.isWhitespace(seq.charAt(start))) && start < end) {
58+
++start;
59+
}
60+
while ((Character.isWhitespace(seq.charAt(end))) && end > start) {
61+
--end;
62+
}
63+
64+
// Check if the charsequence is valid after trimming the whitespaces.
65+
assumeFalse(getString(R.string.cve_2021_0600_errorCreateCharSeq), start > end);
66+
67+
// Adding the extra 'explanation' and launching the activity.
68+
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
69+
seq.subSequence(start, end + 1));
70+
startActivity(intent);
71+
72+
// Send a broadcast to indicate no exceptions occurred.
73+
sendBroadcast(new Intent(getString(R.string.cve_2021_0600_action)).putExtra(
74+
getString(R.string.cve_2021_0600_keyException),
75+
getString(R.string.cve_2021_0600_noException)));
76+
} catch (Exception e) {
77+
try {
78+
// Send a broadcast to report exception.
79+
sendBroadcast(new Intent(getString(R.string.cve_2021_0600_action))
80+
.putExtra(getString(R.string.cve_2021_0600_keyException), e.getMessage()));
81+
} catch (Exception ignored) {
82+
// ignore.
83+
}
84+
}
85+
}
86+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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_2021_0600;
18+
19+
import android.app.admin.DeviceAdminReceiver;
20+
21+
public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
22+
}

0 commit comments

Comments
 (0)