[RESTRICT AUTOMERGE] CTS test for Android Security b/37239013

Bug: 37239013
Bug: 72456628
Test: Ran the new testcase on android-8.0.0_r21 with/without patch

Merged-in: I12a6f34a21e55370972a5cf96595273a5ea6facc
Change-Id: I12a6f34a21e55370972a5cf96595273a5ea6facc
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 7324837..c4f4154 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -146,6 +146,7 @@
         <!--__________________-->
         <!-- Bulletin 2017-07 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-0697->/data/local/tmp/CVE-2017-0697"/>
         <option name="push" value="CVE-2017-0678->/data/local/tmp/CVE-2017-0678"/>
         <option name="push" value="CVE-2016-2109->/data/local/tmp/CVE-2016-2109"/>
 
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/securityPatch/CVE-2017-0697/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/Android.mk
new file mode 100644
index 0000000..48f8633
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/Android.mk
@@ -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.
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2017-0697
+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
+
+# 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-2017-0697/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/poc.cpp
new file mode 100644
index 0000000..9b5e629
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0697/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 <media/IMediaHTTPService.h>
+#include "include/MPEG4Extractor.h"
+#include <media/stagefright/MetaData.h>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include <media/stagefright/DataSource.h>
+#include "../includes/common.h"
+
+using namespace android;
+#define PSSH_BOX_SIZE      1048576
+#define MAX_ENTRIES        1024
+void check_memleak(void);
+bool track_malloc = false;
+
+#define ALLOCATED_STATE      1
+#define FREED_STATE          2
+
+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) {
+    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 (track_malloc == false) {
+        return real_malloc(size);
+    }
+    if (size != PSSH_BOX_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(int argc, char* argv[]) {
+    if (argc < 2) {
+        return EXIT_SUCCESS;
+    }
+
+    sp < DataSource > dataSource = DataSource::CreateFromURI(NULL, argv[1]);
+    if (dataSource == nullptr) {
+        return EXIT_SUCCESS;
+    }
+
+    MPEG4Extractor *extractor = new MPEG4Extractor(dataSource);
+    track_malloc = true;
+    extractor->getMetaData();
+    track_malloc = false;
+
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index 10bcc5d..dcbbe15 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -51,6 +51,17 @@
      ******************************************************************************/
 
     /**
+     * b/37239013
+     * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+     */
+    @SecurityTest(minPatchLevel = "2017-07")
+    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/36554207
      * Vulnerability Behaviour: SIGSEGV in self
      **/