Skip to content

Commit 45ae9c4

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "CTS test for Android Security b/244154558" into rvc-dev
2 parents 1f41177 + 13851ac commit 45ae9c4

11 files changed

Lines changed: 600 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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;
18+
19+
import static org.junit.Assume.assumeNoException;
20+
21+
import android.platform.test.annotations.AsbSecurityTest;
22+
23+
import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
24+
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
25+
26+
import org.junit.Test;
27+
import org.junit.runner.RunWith;
28+
29+
@RunWith(DeviceJUnit4ClassRunner.class)
30+
public class CVE_2023_20944 extends NonRootSecurityTestCase {
31+
32+
// b/244154558
33+
// Vulnerable module : services.jar
34+
// Vulnerable module : Not applicable
35+
// Is Play Managed : No
36+
@AsbSecurityTest(cveBugId = 244154558)
37+
@Test
38+
public void testPocCVE_2023_20944() {
39+
try {
40+
final String testPkg = "android.security.cts.CVE_2023_20944_test";
41+
42+
// Install the test and target apps
43+
installPackage("CVE-2023-20944-test.apk");
44+
installPackage("CVE-2023-20944-target.apk");
45+
46+
// Run the test "testCVE_2023_20944"
47+
runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_20944");
48+
} catch (Exception e) {
49+
assumeNoException(e);
50+
}
51+
}
52+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
18+
package {
19+
default_applicable_licenses: ["Android-Apache-2.0"],
20+
}
21+
22+
android_test_helper_app {
23+
name: "CVE-2023-20944-target",
24+
defaults: [
25+
"cts_support_defaults",
26+
],
27+
srcs: [
28+
"target-app/src/**/*.java",
29+
],
30+
test_suites: [
31+
"sts",
32+
],
33+
manifest: "target-app/AndroidManifest.xml",
34+
sdk_version: "current",
35+
}
36+
37+
android_test_helper_app {
38+
name: "CVE-2023-20944-test",
39+
defaults: [
40+
"cts_support_defaults",
41+
],
42+
srcs: [
43+
"test-app/src/**/*.java",
44+
],
45+
test_suites: [
46+
"sts",
47+
],
48+
static_libs: [
49+
"androidx.test.core",
50+
"androidx.test.rules",
51+
],
52+
manifest: "test-app/AndroidManifest.xml",
53+
resource_dirs: [
54+
"res",
55+
"test-app/res",
56+
],
57+
platform_apis: true,
58+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
<resources>
19+
<string name="accountType">android.security.cts.CVE_2023_20944_test.account</string>
20+
<string name="actionTarget">actionTarget</string>
21+
<string name="activityName">android.accounts.ChooseTypeAndAccountActivity</string>
22+
<string name="activityTarget">android.security.cts.CVE_2023_20944_target.TargetActivity</string>
23+
<string name="allowableAccountTypes">allowableAccountTypes</string>
24+
<string name="bcastActionTarget">CVE_2023_20944_TargetActivity</string>
25+
<string name="launchTaskId">android.activity.launchTaskId</string>
26+
<string name="msgFail">Device is vulnerable to b/244154558 !!</string>
27+
<string name="noExceptionMsg">no exception</string>
28+
<string name="pkgName">android</string>
29+
<string name="pkgTarget">android.security.cts.CVE_2023_20944_target</string>
30+
<string name="pocCrashedMsg">PocActivity crashed with exception: %s</string>
31+
<string name="pocFailedMsg">pocActivity failed</string>
32+
<string name="spannableString">AAAAAAAAAAAA\n</string>
33+
<string name="status">status</string>
34+
<string name="targetFailMsg">TargetActivity did not launch successfully</string>
35+
<string name="taskId">taskId</string>
36+
<string name="taskOverlay">android.activity.taskOverlay</string>
37+
</resources>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright (C) 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+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
19+
package="android.security.cts.CVE_2023_20944_target">
20+
<application>
21+
<activity android:name=".TargetActivity"
22+
android:exported="true" />
23+
</application>
24+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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_20944_target;
18+
19+
import android.app.Activity;
20+
import android.content.Intent;
21+
22+
public class TargetActivity extends Activity {
23+
24+
@Override
25+
protected void onResume() {
26+
try {
27+
super.onResume();
28+
sendBroadcast(new Intent(getString(R.string.bcastActionTarget))
29+
.putExtra(getString(R.string.actionTarget), true)
30+
.putExtra(getString(R.string.taskId), getTaskId()));
31+
} catch (Exception ignored) {
32+
// ignoring exceptions here
33+
}
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
19+
package="android.security.cts.CVE_2023_20944_test">
20+
<application>
21+
<activity android:name=".PocActivity" />
22+
<activity android:name=".HijackActivity" />
23+
<service android:name=".PocAuthService"
24+
android:exported="false">
25+
<intent-filter>
26+
<action android:name="android.accounts.AccountAuthenticator" />
27+
</intent-filter>
28+
<meta-data
29+
android:name="android.accounts.AccountAuthenticator"
30+
android:resource="@xml/authenticator" />
31+
</service>
32+
</application>
33+
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
34+
android:targetPackage="android.security.cts.CVE_2023_20944_test" />
35+
</manifest>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
19+
android:accountType="android.security.cts.CVE_2023_20944_test.account" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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_20944_test;
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.ActivityManager;
26+
import android.app.IActivityTaskManager;
27+
import android.app.UiAutomation;
28+
import android.content.BroadcastReceiver;
29+
import android.content.Context;
30+
import android.content.Intent;
31+
import android.content.IntentFilter;
32+
import android.os.ServiceManager;
33+
34+
import androidx.test.runner.AndroidJUnit4;
35+
36+
import org.junit.Test;
37+
import org.junit.runner.RunWith;
38+
39+
import java.util.concurrent.Semaphore;
40+
import java.util.concurrent.TimeUnit;
41+
import java.util.List;
42+
43+
@RunWith(AndroidJUnit4.class)
44+
public class DeviceTest {
45+
private String mPocActivityStatus;
46+
private int mTaskId;
47+
48+
@Test
49+
public void testCVE_2023_20944() {
50+
try {
51+
final int waitMs = 5000;
52+
final int waitPerIter = 200;
53+
Context context = getInstrumentation().getContext();
54+
UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
55+
uiAutomation.adoptShellPermissionIdentity();
56+
57+
// Registering a receiver here to wait for a broadcast from TargetActivity
58+
final Semaphore targetReturn = new Semaphore(0);
59+
final Semaphore pocReturn = new Semaphore(0);
60+
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
61+
@Override
62+
public void onReceive(Context context, Intent intent) {
63+
try {
64+
if ((intent.getBooleanExtra(context.getString(R.string.actionTarget), false)
65+
&& (mTaskId = intent.getIntExtra(context.getString(R.string.taskId),
66+
-1)) != -1)) {
67+
targetReturn.release();
68+
}
69+
if ((mPocActivityStatus = intent
70+
.getStringExtra(context.getString(R.string.status))) != null) {
71+
pocReturn.release();
72+
}
73+
} catch (Exception ignored) {
74+
// ignore any exceptions
75+
}
76+
}
77+
};
78+
IntentFilter filter = new IntentFilter(context.getString(R.string.bcastActionTarget));
79+
context.registerReceiver(broadcastReceiver, filter);
80+
81+
// Start TargetActivity
82+
Intent targetIntent = new Intent(Intent.ACTION_MAIN);
83+
final String pkgTarget = context.getString(R.string.pkgTarget);
84+
targetIntent.setClassName(pkgTarget, context.getString(R.string.activityTarget));
85+
targetIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
86+
context.startActivity(targetIntent);
87+
assumeTrue(context.getString(R.string.targetFailMsg),
88+
targetReturn.tryAcquire(waitMs, TimeUnit.MILLISECONDS));
89+
90+
// Start PocActivity which in turn starts the ChooseTypeAndAccountActivity
91+
Intent intent = new Intent(context, PocActivity.class);
92+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
93+
context.startActivity(intent);
94+
assumeTrue(context.getString(R.string.pocFailedMsg),
95+
pocReturn.tryAcquire(waitMs, TimeUnit.MILLISECONDS));
96+
assumeTrue(context.getString(R.string.pocCrashedMsg, mPocActivityStatus),
97+
mPocActivityStatus.equals(context.getString(R.string.noExceptionMsg)));
98+
99+
// Failing the test if the taskId received from the target activity matches with the
100+
// list of running taskId and topActivity has HijackActivity in the same taskId.
101+
IActivityTaskManager iActivityTaskManager = IActivityTaskManager.Stub
102+
.asInterface(ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE));
103+
long start = System.currentTimeMillis();
104+
while (!(iActivityTaskManager.getAllStackInfos().toString()
105+
.contains(HijackActivity.class.getName()))
106+
&& System.currentTimeMillis() - start < waitMs) {
107+
Thread.sleep(waitPerIter);
108+
}
109+
boolean isDeviceVulnerable = false;
110+
List<ActivityManager.StackInfo> runningTasks = iActivityTaskManager.getAllStackInfos();
111+
for (ActivityManager.StackInfo runningTaskInfo : runningTasks) {
112+
for (int i = 0; i < runningTaskInfo.taskIds.length; ++i) {
113+
if (mTaskId == runningTaskInfo.taskIds[i] && runningTaskInfo.topActivity
114+
.getClassName().equals(HijackActivity.class.getName())) {
115+
isDeviceVulnerable = true;
116+
break;
117+
}
118+
}
119+
}
120+
assertFalse(context.getString(R.string.msgFail), isDeviceVulnerable);
121+
} catch (Exception e) {
122+
assumeNoException(e);
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)