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