• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cm_fuzz_test_common.h"
17 
18 #include "cm_ipc_client_serialization.h"
19 #include "message_parcel.h"
20 
21 namespace CmFuzzTest {
GetUintFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,uint32_t * outVal)22 bool GetUintFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, uint32_t *outVal)
23 {
24     if (*remSize < sizeof(uint32_t)) {
25         return false;
26     }
27 
28     (void)memcpy_s(outVal, sizeof(uint32_t), srcData + *offset, sizeof(uint32_t));
29     *remSize -= sizeof(uint32_t);
30     *offset += sizeof(uint32_t);
31 
32     return true;
33 }
34 
GetCmBlobFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CmBlob * outBlob)35 bool GetCmBlobFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CmBlob *outBlob)
36 {
37     if (GetUintFromBuffer(srcData, remSize, offset, &(outBlob->size)) != true) {
38         return false;
39     }
40 
41     if (*remSize < outBlob->size) {
42         return false;
43     }
44     outBlob->data = srcData + *offset;
45     *remSize -= outBlob->size;
46     *offset += outBlob->size;
47 
48     return true;
49 }
50 
GetCertListFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CertList * outList)51 bool GetCertListFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CertList *outList)
52 {
53     if (GetUintFromBuffer(srcData, remSize, offset, &(outList->certsCount)) != true) {
54         return false;
55     }
56 
57     if (outList->certsCount > (*remSize / sizeof(struct CertAbstract))) {
58         return false;
59     }
60     outList->certAbstract = reinterpret_cast<struct CertAbstract *>(srcData + *offset);
61 
62     return true;
63 }
64 
GetCertInfoFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CertInfo * outInfo)65 bool GetCertInfoFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CertInfo *outInfo)
66 {
67     if (*remSize < sizeof(struct CertInfo)) {
68         return false;
69     }
70 
71     outInfo = reinterpret_cast<struct CertInfo *>(srcData + *offset);
72     *remSize -= sizeof(struct CertInfo);
73     *offset += sizeof(struct CertInfo);
74 
75     if (*remSize < outInfo->certInfo.size) {
76         return false;
77     }
78 
79     outInfo->certInfo.data = const_cast<uint8_t *>(srcData + *offset);
80     return true;
81 }
82 
CopyMyData(const uint8_t * data,const size_t size,const uint32_t minSize,uint8_t ** myData)83 bool CopyMyData(const uint8_t *data, const size_t size, const uint32_t minSize, uint8_t **myData)
84 {
85     if (data == nullptr|| static_cast<uint32_t>(size) < minSize) {
86         return false;
87     }
88 
89     uint8_t *tempData = static_cast<uint8_t *>(CmMalloc(sizeof(uint8_t) * size));
90     if (tempData == nullptr) {
91         return false;
92     }
93     (void)memcpy_s(tempData, size, data, size);
94 
95     *myData = tempData;
96     return true;
97 }
98 
99 constexpr uint32_t PARAM_COUNT_ONE = 1;
100 constexpr uint32_t PARAM_COUNT_TWO = 2;
101 constexpr uint32_t PARAM_COUNT_THREE = 3;
102 constexpr uint32_t PARAM_COUNT_FOUR = 4;
103 
104 struct CmFuzzerCodeParams {
105     CertManagerInterfaceCode code;
106     uint32_t paramCnt;
107     struct CmParam params[PARAM_COUNT_FOUR];
108 };
109 
110 constexpr struct CmFuzzerCodeParams g_codeParams[] = {
111     {   CM_MSG_GET_CERTIFICATE_LIST,
112         PARAM_COUNT_ONE,
113         {
114             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 }
115         }
116     },
117     {   CM_MSG_GET_CERTIFICATE_INFO,
118         PARAM_COUNT_TWO,
119         {
120             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
121             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
122         }
123     },
124     {   CM_MSG_SET_CERTIFICATE_STATUS,
125         PARAM_COUNT_THREE,
126         {
127             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
128             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
129             { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
130         }
131     },
132     {   CM_MSG_INSTALL_APP_CERTIFICATE,
133         PARAM_COUNT_FOUR,
134         {
135             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
136             { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
137             { .tag = CM_TAG_PARAM2_BUFFER, .blob = { 0, nullptr } },
138             { .tag = CM_TAG_PARAM3_UINT32, .uint32Param = 0 },
139         }
140     },
141     {   CM_MSG_UNINSTALL_APP_CERTIFICATE,
142         PARAM_COUNT_TWO,
143         {
144             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
145             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
146         }
147     },
148     {   CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE,
149         0,
150         {
151         }
152     },
153     {   CM_MSG_GET_APP_CERTIFICATE_LIST,
154         PARAM_COUNT_ONE,
155         {
156             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
157         }
158     },
159     {   CM_MSG_GET_APP_CERTIFICATE,
160         PARAM_COUNT_TWO,
161         {
162             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
163             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
164         }
165     },
166     {   CM_MSG_GRANT_APP_CERT,
167         PARAM_COUNT_TWO,
168         {
169             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
170             { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
171         }
172     },
173     {   CM_MSG_GET_AUTHED_LIST,
174         PARAM_COUNT_ONE,
175         {
176             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
177         }
178     },
179     {   CM_MSG_CHECK_IS_AUTHED_APP,
180         PARAM_COUNT_ONE,
181         {
182             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
183         }
184     },
185     {   CM_MSG_REMOVE_GRANT_APP,
186         PARAM_COUNT_TWO,
187         {
188             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
189             { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
190         }
191     },
192     {   CM_MSG_INIT,
193         PARAM_COUNT_TWO,
194         {
195             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
196             { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
197         }
198     },
199     {   CM_MSG_UPDATE,
200         PARAM_COUNT_TWO,
201         {
202             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
203             { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
204         }
205     },
206     {   CM_MSG_FINISH,
207         PARAM_COUNT_TWO,
208         {
209             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
210             { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
211         }
212     },
213     {   CM_MSG_ABORT,
214         PARAM_COUNT_ONE,
215         {
216             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
217         }
218     },
219     {   CM_MSG_GET_USER_CERTIFICATE_LIST,
220         PARAM_COUNT_ONE,
221         {
222             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
223         }
224     },
225     {   CM_MSG_GET_USER_CERTIFICATE_INFO,
226         PARAM_COUNT_TWO,
227         {
228             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
229             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
230         }
231     },
232     {   CM_MSG_SET_USER_CERTIFICATE_STATUS,
233         PARAM_COUNT_THREE,
234         {
235             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
236             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
237             { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
238         }
239     },
240     {   CM_MSG_INSTALL_USER_CERTIFICATE,
241         PARAM_COUNT_TWO,
242         {
243             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
244             { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
245         }
246     },
247     {   CM_MSG_UNINSTALL_USER_CERTIFICATE,
248         PARAM_COUNT_ONE,
249         {
250             { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
251         }
252     },
253     {   CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE,
254         0,
255         {
256         }
257     },
258 };
259 
ConstructParamSet(uint8_t * srcData,uint32_t * remainSize,uint32_t * offset,CertManagerInterfaceCode code,struct CmParamSet ** paramSetOut)260 bool ConstructParamSet(uint8_t *srcData, uint32_t *remainSize,
261     uint32_t *offset, CertManagerInterfaceCode code, struct CmParamSet **paramSetOut)
262 {
263     struct CmParam params[PARAM_COUNT_FOUR] = {};
264     uint32_t paramCnt = 0;
265     for (uint32_t i = 0; i < (sizeof(g_codeParams) / sizeof(g_codeParams[0])); ++i) {
266         if (code == g_codeParams[i].code) {
267             (void)memcpy_s(params, (sizeof(struct CmParam) * g_codeParams[i].paramCnt),
268                 g_codeParams[i].params, (sizeof(struct CmParam) * g_codeParams[i].paramCnt));
269             paramCnt = g_codeParams[i].paramCnt;
270             break;
271         }
272     }
273 
274     for (uint32_t i = 0; i < paramCnt; ++i) {
275         switch (GetTagType(static_cast<enum CmTag>(params[i].tag))) {
276             case CM_TAG_TYPE_BYTES:
277                 if (!GetCmBlobFromBuffer(srcData, remainSize, offset, &(params[i].blob))) {
278                     return false;
279                 }
280                 break;
281             case CM_TAG_TYPE_UINT:
282                 if (!GetUintFromBuffer(srcData, remainSize, offset, &(params[i].uint32Param))) {
283                     return false;
284                 }
285                 break;
286             case CM_TAG_TYPE_BOOL:
287                 uint32_t tmp;
288                 if (!GetUintFromBuffer(srcData, remainSize, offset, &tmp)) {
289                     return false;
290                 }
291                 params[i].boolParam = (tmp % i == 0 ? true : false);
292                 break;
293             default:
294                 break;
295         }
296     }
297 
298     if (CmParamsToParamSet(params, paramCnt, paramSetOut) != CM_SUCCESS) {
299         return false;
300     }
301 
302     return true;
303 }
304 
IpcServiceApiFuzzerTest(const uint8_t * data,const size_t size,CertManagerInterfaceCode code,bool isParamsetToBlob,void (* ipcServiceApi)(const struct CmBlob *,struct CmBlob *,const struct CmContext *))305 bool IpcServiceApiFuzzerTest(const uint8_t *data, const size_t size, CertManagerInterfaceCode code,
306     bool isParamsetToBlob, void (*ipcServiceApi)(const struct CmBlob *, struct CmBlob *, const struct CmContext *))
307 {
308     uint32_t minSize = sizeof(struct CmBlob) + sizeof(struct CmBlob);
309     uint8_t *myData = nullptr;
310     if (!CopyMyData(data, size, minSize, &myData)) {
311         return false;
312     }
313 
314     uint32_t remSize = static_cast<uint32_t>(size);
315     uint32_t offset = 0;
316 
317     struct CmBlob paramSetBlob = { 0, nullptr };
318     struct CmParamSet *paramSet = nullptr;
319     if (isParamsetToBlob) {
320         if (ConstructParamSet(myData, &remSize, &offset, code, &paramSet) != true) {
321             CmFree(myData);
322             return false;
323         }
324         paramSetBlob = { paramSet->paramSetSize, reinterpret_cast<uint8_t *>(paramSet) };
325     } else {
326         if (GetCmBlobFromBuffer(myData, &remSize, &offset, &paramSetBlob) != true) {
327             CmFree(myData);
328             return false;
329         }
330     }
331 
332     struct CmBlob outData = { 0, nullptr };
333     if (GetCmBlobFromBuffer(myData, &remSize, &offset, &outData) != true) {
334         CmFree(myData);
335         CmFreeParamSet(&paramSet);
336         return false;
337     }
338 
339     OHOS::MessageParcel context;
340     (void)ipcServiceApi(&paramSetBlob, &outData, reinterpret_cast<struct CmContext *>(&context));
341 
342     CmFree(myData);
343     CmFreeParamSet(&paramSet);
344     return true;
345 }
346 }
347