diff options
Diffstat (limited to 'hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java')
-rw-r--r-- | hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java | 164 |
1 files changed, 92 insertions, 72 deletions
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java index f98690625e9..9a94ef953c1 100644 --- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java +++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/DeviceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 The Android Open Source Project + * Copyright (C) 2022 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. @@ -14,17 +14,20 @@ * limitations under the License. */ -package android.security.cts.cve_2021_0954; +package android.security.cts.CVE_2021_0954; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; + +import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeTrue; -import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.pm.PackageManager; import android.provider.Settings; import androidx.test.runner.AndroidJUnit4; @@ -32,90 +35,107 @@ import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.Until; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.IOException; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; @RunWith(AndroidJUnit4.class) public class DeviceTest { - private static final String TEST_PKG = "android.security.cts.cve_2021_0954"; - private static final String TEST_VULNERABLE_PKG = "android"; - private static final String TEST_VULNERABLE_ACTIVITY = - "com.android.internal.app.ResolverActivity"; - private static final int LAUNCH_TIMEOUT_MS = 20000; - private static final String vulnerableActivityName = "ResolverActivity"; - private UiDevice mDevice; - String activityDump = ""; - - private void startOverlayService() { - Context context = getApplicationContext(); - assertNotNull(context); - Intent intent = new Intent(context, PocService.class); - assertNotNull(intent); - - if (Settings.canDrawOverlays(getApplicationContext())) { - context.startService(intent); - } else { - try { - context.startService(intent); - } catch (Exception e) { - throw new RuntimeException("Unable to start the overlay service", e); - } - } + private Context mContext = getApplicationContext(); + private static final int TIMEOUT_MS = 10000; + + private boolean hasFeature(String feature) { + return mContext.getPackageManager().hasSystemFeature(feature); } - public void startVulnerableActivity() { - Context context = getApplicationContext(); - Intent intent = new Intent(); - intent.setClassName(TEST_VULNERABLE_PKG, TEST_VULNERABLE_ACTIVITY); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - context.startActivity(intent); - } catch (ActivityNotFoundException e) { - assumeNoException("Activity not found on device", e); - } + private boolean isAuto() { + return hasFeature(PackageManager.FEATURE_AUTOMOTIVE); } - @Before - public void setUp() throws Exception { - mDevice = UiDevice.getInstance(getInstrumentation()); + String getStringRes(int key) { + return mContext.getResources().getString(key); + } - /* Start the vulnerable activity */ - startVulnerableActivity(); - if (!mDevice.wait(Until.hasObject(By.res("android:id/contentPanel") - .clazz("android.widget.ScrollView").pkg("android")), LAUNCH_TIMEOUT_MS)) { - return; - } + String getStringResWithArg(int key, String arg) { + return mContext.getResources().getString(key, arg); + } - /* Start the overlay service */ - startOverlayService(); + int getIntegerRes(int key) { + return mContext.getResources().getInteger(key); } @Test - public void testVulnerableActivityPresence() { - Pattern overlayTextPattern = Pattern.compile("OverlayButton", Pattern.CASE_INSENSITIVE); - if (!mDevice.wait(Until.hasObject(By.text(overlayTextPattern)), LAUNCH_TIMEOUT_MS)) { - return; - } - - /* - * Check if the currently running activity is the vulnerable activity, if not abort the test - */ + public void testOverlayButtonPresence() { try { - activityDump = mDevice.executeShellCommand("dumpsys activity"); - } catch (IOException e) { - throw new RuntimeException("Could not execute dumpsys activity command"); - } - Pattern activityPattern = - Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n"); - if (!activityPattern.matcher(activityDump).find()) { - return; + UiDevice device = UiDevice.getInstance(getInstrumentation()); + + /* Start the overlay service */ + assumeTrue(getStringRes(R.string.canNotDrawOverlaysMsg), + Settings.canDrawOverlays(mContext)); + Intent intent = new Intent(mContext, PocService.class); + mContext.startService(intent); + + /* Wait for a result from overlay service */ + SharedPreferences sharedPrefs = mContext.getSharedPreferences( + getStringRes(R.string.sharedPreferences), Context.MODE_PRIVATE); + final Semaphore preferenceChanged = new Semaphore(0); + OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (key.equals(getStringRes(R.string.resultKey))) { + preferenceChanged.release(); + } + } + }; + sharedPrefs.registerOnSharedPreferenceChangeListener(listener); + assumeTrue(preferenceChanged.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS)); + int result = sharedPrefs.getInt(getStringRes(R.string.resultKey), + getIntegerRes(R.integer.assumptionFailure)); + String message = sharedPrefs.getString(getStringRes(R.string.messageKey), + getStringRes(R.string.defaultSemaphoreMsg)); + assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure)); + + /* Wait for the UI of overlay window to appear */ + Pattern overlayTextPattern = Pattern.compile( + mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE); + assumeTrue(mContext.getString(R.string.overlayUiScreenError), + device.wait(Until.hasObject(By.text(overlayTextPattern)), TIMEOUT_MS)); + + /* Start the vulnerable activity */ + intent = new Intent(); + String vulActivity = getStringRes(R.string.vulClass); + String vulPkg = getStringRes(R.string.vulPkg); + if (isAuto()) { + vulActivity = getStringRes(R.string.vulClassAuto); + vulPkg = getStringRes(R.string.vulPkgAuto); + } + intent.setClassName(vulPkg, vulActivity); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + + /* Wait until the object of overlay window is gone */ + boolean overlayDisallowed = + device.wait(Until.gone(By.pkg(mContext.getPackageName())), TIMEOUT_MS); + + /* + * Check if the currently running activity is the vulnerable activity, if not abort the + * test + */ + String activityDump = device.executeShellCommand( + getStringResWithArg(R.string.cmdDumpsysActivity, vulActivity)); + Pattern activityPattern = Pattern.compile(getStringRes(R.string.mResumedTrue)); + assumeTrue(getStringRes(R.string.vulActivityNotRunningError), + activityPattern.matcher(activityDump).find()); + + /* Failing the test as fix is not present */ + assertTrue(getStringResWithArg(R.string.overlayErrorMessage, vulActivity), + overlayDisallowed); + } catch (Exception e) { + assumeNoException(e); } - String message = "Device is vulnerable to b/143559931 hence any app with " - + "SYSTEM_ALERT_WINDOW can overlay the ResolverActivity screen"; - assertNull(message, mDevice.findObject(By.text(overlayTextPattern))); } } |