diff options
Diffstat (limited to 'hostsidetests/securitybulletin/test-apps/CVE-2023-20944/test-app/src/android/security/cts/CVE_2023_20944_test/DeviceTest.java')
-rw-r--r-- | hostsidetests/securitybulletin/test-apps/CVE-2023-20944/test-app/src/android/security/cts/CVE_2023_20944_test/DeviceTest.java | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20944/test-app/src/android/security/cts/CVE_2023_20944_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20944/test-app/src/android/security/cts/CVE_2023_20944_test/DeviceTest.java new file mode 100644 index 00000000000..a0c7a241de5 --- /dev/null +++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20944/test-app/src/android/security/cts/CVE_2023_20944_test/DeviceTest.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts.CVE_2023_20944_test; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeTrue; + +import android.app.ActivityTaskManager; +import android.app.IActivityTaskManager; +import android.app.UiAutomation; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.ServiceManager; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public class DeviceTest { + private String mPocActivityStatus; + private int mTaskId; + + @Test + public void testCVE_2023_20944() { + try { + final int waitMs = 5000; + final int waitPerIter = 200; + Context context = getInstrumentation().getContext(); + UiAutomation uiAutomation = getInstrumentation().getUiAutomation(); + uiAutomation.adoptShellPermissionIdentity(); + + // Registering a receiver here to wait for a broadcast from TargetActivity + final Semaphore targetReturn = new Semaphore(0); + final Semaphore pocReturn = new Semaphore(0); + BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + try { + if ((intent.getBooleanExtra(context.getString(R.string.actionTarget), false) + && (mTaskId = intent.getIntExtra(context.getString(R.string.taskId), + -1)) != -1)) { + targetReturn.release(); + } + if ((mPocActivityStatus = intent + .getStringExtra(context.getString(R.string.status))) != null) { + pocReturn.release(); + } + } catch (Exception ignored) { + // ignore any exceptions + } + } + }; + IntentFilter filter = new IntentFilter(context.getString(R.string.bcastActionTarget)); + context.registerReceiver(broadcastReceiver, filter); + + // Start TargetActivity + Intent targetIntent = new Intent(Intent.ACTION_MAIN); + final String pkgTarget = context.getString(R.string.pkgTarget); + targetIntent.setClassName(pkgTarget, context.getString(R.string.activityTarget)); + targetIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(targetIntent); + assumeTrue(context.getString(R.string.targetFailMsg), + targetReturn.tryAcquire(waitMs, TimeUnit.MILLISECONDS)); + + // Start PocActivity which in turn starts the ChooseTypeAndAccountActivity + Intent intent = new Intent(context, PocActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + assumeTrue(context.getString(R.string.pocFailedMsg), + pocReturn.tryAcquire(waitMs, TimeUnit.MILLISECONDS)); + assumeTrue(context.getString(R.string.pocCrashedMsg, mPocActivityStatus), + mPocActivityStatus.equals(context.getString(R.string.noExceptionMsg))); + + // Failing the test if the taskId received from the target activity matches with the + // list of running taskId and topActivity has HijackActivity in the same taskId. + IActivityTaskManager iActivityTaskManager = IActivityTaskManager.Stub + .asInterface(ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE)); + long start = System.currentTimeMillis(); + while (!(iActivityTaskManager.getAllRootTaskInfos().toString() + .contains(HijackActivity.class.getName())) + && System.currentTimeMillis() - start < waitMs) { + Thread.sleep(waitPerIter); + } + boolean isDeviceVulnerable = false; + List<ActivityTaskManager.RootTaskInfo> runningTasks = + iActivityTaskManager.getAllRootTaskInfos(); + for (ActivityTaskManager.RootTaskInfo runningTaskInfo : runningTasks) { + for (int i = 0; i < runningTaskInfo.childTaskIds.length; ++i) { + if (mTaskId == runningTaskInfo.childTaskIds[i] && runningTaskInfo.topActivity + .getClassName().equals(HijackActivity.class.getName())) { + isDeviceVulnerable = true; + break; + } + } + } + assertFalse(context.getString(R.string.msgFail), isDeviceVulnerable); + } catch (Exception e) { + assumeNoException(e); + } + } +} |