[RESTRICT AUTOMERGE] CTS test for Android security b/166268541
Bug: 166268541
Bug: 170661600
Test: Ran the new testcase on android-10.0.0_r2 with/without patch
Change-Id: I535d72f369d76c9655c81b4d9bca486fc36f53b5
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/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..8317ca5
--- /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.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/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index 56ec8af..640a02b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -518,6 +518,20 @@
******************************************************************************/
/**
+ * 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
*/