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 #include "cm_test_common.h"
18 #include "cm_test_common.h"
19
20 #include "cm_ipc_client_serialization.h"
21 #include "message_parcel.h"
22 #include "nativetoken_kit.h"
23 #include "token_setproc.h"
24 #include "accesstoken_kit.h"
25 #include <unistd.h>
26
27 namespace CmFuzzTest {
28 constexpr uint32_t NUM_10 = 10;
29 constexpr uint32_t NUM_9 = 9;
30
GetUintFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,uint32_t * outVal)31 bool GetUintFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, uint32_t *outVal)
32 {
33 if (*remSize < sizeof(uint32_t)) {
34 return false;
35 }
36
37 (void)memcpy_s(outVal, sizeof(uint32_t), srcData + *offset, sizeof(uint32_t));
38 *remSize -= sizeof(uint32_t);
39 *offset += sizeof(uint32_t);
40
41 return true;
42 }
43
GetCmBlobFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CmBlob * outBlob)44 bool GetCmBlobFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CmBlob *outBlob)
45 {
46 if (GetUintFromBuffer(srcData, remSize, offset, &(outBlob->size)) != true) {
47 return false;
48 }
49
50 if (*remSize < outBlob->size) {
51 return false;
52 }
53 outBlob->data = srcData + *offset;
54 *remSize -= outBlob->size;
55 *offset += outBlob->size;
56
57 return true;
58 }
59
GetCertListFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CertList * outList)60 bool GetCertListFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CertList *outList)
61 {
62 if (GetUintFromBuffer(srcData, remSize, offset, &(outList->certsCount)) != true) {
63 return false;
64 }
65
66 if (outList->certsCount > (*remSize / sizeof(struct CertAbstract))) {
67 return false;
68 }
69 outList->certAbstract = reinterpret_cast<struct CertAbstract *>(srcData + *offset);
70
71 return true;
72 }
73
GetCertInfoFromBuffer(uint8_t * srcData,uint32_t * remSize,uint32_t * offset,struct CertInfo * outInfo)74 bool GetCertInfoFromBuffer(uint8_t *srcData, uint32_t *remSize, uint32_t *offset, struct CertInfo *outInfo)
75 {
76 if (*remSize < sizeof(struct CertInfo)) {
77 return false;
78 }
79
80 outInfo = reinterpret_cast<struct CertInfo *>(srcData + *offset);
81 *remSize -= sizeof(struct CertInfo);
82 *offset += sizeof(struct CertInfo);
83
84 if (*remSize < outInfo->certInfo.size) {
85 return false;
86 }
87
88 outInfo->certInfo.data = const_cast<uint8_t *>(srcData + *offset);
89 return true;
90 }
91
TenPercentChanceOfBeingTrue(uint8_t * srcData,uint32_t * remSize,uint32_t * offset)92 bool TenPercentChanceOfBeingTrue(uint8_t *srcData, uint32_t *remSize, uint32_t *offset)
93 {
94 if (srcData == nullptr || remSize == nullptr || offset == nullptr) {
95 return false;
96 }
97
98 uint32_t randomNum = 0;
99 if (!GetUintFromBuffer(srcData, remSize, offset, &randomNum)) {
100 return false;
101 }
102 return (randomNum %= NUM_10) == NUM_9;
103 }
104
CopyMyData(const uint8_t * data,const size_t size,const uint32_t minSize,uint8_t ** myData)105 bool CopyMyData(const uint8_t *data, const size_t size, const uint32_t minSize, uint8_t **myData)
106 {
107 if (data == nullptr|| static_cast<uint32_t>(size) < minSize) {
108 return false;
109 }
110
111 uint8_t *tempData = static_cast<uint8_t *>(CmMalloc(sizeof(uint8_t) * size));
112 if (tempData == nullptr) {
113 return false;
114 }
115 (void)memcpy_s(tempData, size, data, size);
116
117 *myData = tempData;
118 return true;
119 }
120
121 constexpr uint32_t PARAM_COUNT_ONE = 1;
122 constexpr uint32_t PARAM_COUNT_TWO = 2;
123 constexpr uint32_t PARAM_COUNT_THREE = 3;
124 constexpr uint32_t PARAM_COUNT_FOUR = 4;
125
126 struct CmFuzzerCodeParams {
127 CertManagerInterfaceCode code;
128 uint32_t paramCnt;
129 struct CmParam params[PARAM_COUNT_FOUR];
130 };
131
132 constexpr struct CmFuzzerCodeParams g_codeParams[] = {
133 { CM_MSG_GET_CERTIFICATE_LIST,
134 PARAM_COUNT_ONE,
135 {
136 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 }
137 }
138 },
139 { CM_MSG_GET_CERTIFICATE_INFO,
140 PARAM_COUNT_TWO,
141 {
142 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
143 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
144 }
145 },
146 { CM_MSG_SET_CERTIFICATE_STATUS,
147 PARAM_COUNT_THREE,
148 {
149 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
150 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
151 { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
152 }
153 },
154 { CM_MSG_INSTALL_APP_CERTIFICATE,
155 PARAM_COUNT_FOUR,
156 {
157 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
158 { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
159 { .tag = CM_TAG_PARAM2_BUFFER, .blob = { 0, nullptr } },
160 { .tag = CM_TAG_PARAM3_UINT32, .uint32Param = 0 },
161 }
162 },
163 { CM_MSG_UNINSTALL_APP_CERTIFICATE,
164 PARAM_COUNT_TWO,
165 {
166 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
167 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
168 }
169 },
170 { CM_MSG_UNINSTALL_ALL_APP_CERTIFICATE,
171 0,
172 {
173 }
174 },
175 { CM_MSG_GET_APP_CERTIFICATE_LIST,
176 PARAM_COUNT_ONE,
177 {
178 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
179 }
180 },
181 { CM_MSG_GET_CALLING_APP_CERTIFICATE_LIST,
182 PARAM_COUNT_ONE,
183 {
184 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
185 }
186 },
187 { CM_MSG_GET_APP_CERTIFICATE,
188 PARAM_COUNT_TWO,
189 {
190 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
191 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
192 }
193 },
194 { CM_MSG_GRANT_APP_CERT,
195 PARAM_COUNT_TWO,
196 {
197 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
198 { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
199 }
200 },
201 { CM_MSG_GET_AUTHED_LIST,
202 PARAM_COUNT_ONE,
203 {
204 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
205 }
206 },
207 { CM_MSG_CHECK_IS_AUTHED_APP,
208 PARAM_COUNT_ONE,
209 {
210 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
211 }
212 },
213 { CM_MSG_REMOVE_GRANT_APP,
214 PARAM_COUNT_TWO,
215 {
216 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
217 { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
218 }
219 },
220 { CM_MSG_INIT,
221 PARAM_COUNT_TWO,
222 {
223 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
224 { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
225 }
226 },
227 { CM_MSG_UPDATE,
228 PARAM_COUNT_TWO,
229 {
230 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
231 { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
232 }
233 },
234 { CM_MSG_FINISH,
235 PARAM_COUNT_TWO,
236 {
237 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
238 { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
239 }
240 },
241 { CM_MSG_ABORT,
242 PARAM_COUNT_ONE,
243 {
244 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
245 }
246 },
247 { CM_MSG_GET_USER_CERTIFICATE_LIST,
248 PARAM_COUNT_ONE,
249 {
250 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
251 }
252 },
253 { CM_MSG_GET_USER_CERTIFICATE_INFO,
254 PARAM_COUNT_TWO,
255 {
256 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
257 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
258 }
259 },
260 { CM_MSG_SET_USER_CERTIFICATE_STATUS,
261 PARAM_COUNT_THREE,
262 {
263 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
264 { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = 0 },
265 { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = 0 },
266 }
267 },
268 { CM_MSG_INSTALL_USER_CERTIFICATE,
269 PARAM_COUNT_TWO,
270 {
271 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
272 { .tag = CM_TAG_PARAM1_BUFFER, .blob = { 0, nullptr } },
273 }
274 },
275 { CM_MSG_UNINSTALL_USER_CERTIFICATE,
276 PARAM_COUNT_ONE,
277 {
278 { .tag = CM_TAG_PARAM0_BUFFER, .blob = { 0, nullptr } },
279 }
280 },
281 { CM_MSG_UNINSTALL_ALL_USER_CERTIFICATE,
282 0,
283 {
284 }
285 },
286 };
287
ConstructParamSet(uint8_t * srcData,uint32_t * remainSize,uint32_t * offset,CertManagerInterfaceCode code,struct CmParamSet ** paramSetOut)288 bool ConstructParamSet(uint8_t *srcData, uint32_t *remainSize,
289 uint32_t *offset, CertManagerInterfaceCode code, struct CmParamSet **paramSetOut)
290 {
291 struct CmParam params[PARAM_COUNT_FOUR] = {};
292 uint32_t paramCnt = 0;
293 for (uint32_t i = 0; i < (sizeof(g_codeParams) / sizeof(g_codeParams[0])); ++i) {
294 if (code == g_codeParams[i].code) {
295 (void)memcpy_s(params, (sizeof(struct CmParam) * g_codeParams[i].paramCnt),
296 g_codeParams[i].params, (sizeof(struct CmParam) * g_codeParams[i].paramCnt));
297 paramCnt = g_codeParams[i].paramCnt;
298 break;
299 }
300 }
301
302 for (uint32_t i = 0; i < paramCnt; ++i) {
303 switch (GetTagType(static_cast<enum CmTag>(params[i].tag))) {
304 case CM_TAG_TYPE_BYTES:
305 if (!GetCmBlobFromBuffer(srcData, remainSize, offset, &(params[i].blob))) {
306 return false;
307 }
308 break;
309 case CM_TAG_TYPE_UINT:
310 if (!GetUintFromBuffer(srcData, remainSize, offset, &(params[i].uint32Param))) {
311 return false;
312 }
313 break;
314 case CM_TAG_TYPE_BOOL:
315 uint32_t tmp;
316 if (!GetUintFromBuffer(srcData, remainSize, offset, &tmp)) {
317 return false;
318 }
319 params[i].boolParam = (tmp % i == 0 ? true : false);
320 break;
321 default:
322 break;
323 }
324 }
325
326 if (CmParamsToParamSet(params, paramCnt, paramSetOut) != CM_SUCCESS) {
327 return false;
328 }
329
330 return true;
331 }
332
IpcServiceApiFuzzerTest(const uint8_t * data,const size_t size,CertManagerInterfaceCode code,bool isParamsetToBlob,void (* ipcServiceApi)(const struct CmBlob *,struct CmBlob *,const struct CmContext *))333 bool IpcServiceApiFuzzerTest(const uint8_t *data, const size_t size, CertManagerInterfaceCode code,
334 bool isParamsetToBlob, void (*ipcServiceApi)(const struct CmBlob *, struct CmBlob *, const struct CmContext *))
335 {
336 uint32_t minSize = sizeof(struct CmBlob) + sizeof(struct CmBlob);
337 uint8_t *myData = nullptr;
338 if (!CopyMyData(data, size, minSize, &myData)) {
339 return false;
340 }
341
342 uint32_t remSize = static_cast<uint32_t>(size);
343 uint32_t offset = 0;
344
345 struct CmBlob paramSetBlob = { 0, nullptr };
346 struct CmParamSet *paramSet = nullptr;
347 if (isParamsetToBlob) {
348 if (ConstructParamSet(myData, &remSize, &offset, code, ¶mSet) != true) {
349 CmFree(myData);
350 return false;
351 }
352 paramSetBlob = { paramSet->paramSetSize, reinterpret_cast<uint8_t *>(paramSet) };
353 } else {
354 if (GetCmBlobFromBuffer(myData, &remSize, &offset, ¶mSetBlob) != true) {
355 CmFree(myData);
356 return false;
357 }
358 }
359
360 struct CmBlob outData = { 0, nullptr };
361 if (GetCmBlobFromBuffer(myData, &remSize, &offset, &outData) != true) {
362 CmFree(myData);
363 CmFreeParamSet(¶mSet);
364 return false;
365 }
366
367 OHOS::MessageParcel context;
368 (void)ipcServiceApi(¶mSetBlob, &outData, reinterpret_cast<struct CmContext *>(&context));
369
370 CmFree(myData);
371 CmFreeParamSet(¶mSet);
372 return true;
373 }
374 }
375