• 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 #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, &paramSet) != 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, &paramSetBlob) != 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(&paramSet);
390         return false;
391     }
392 
393     OHOS::MessageParcel context;
394     (void)ipcServiceApi(&paramSetBlob, &outData, reinterpret_cast<struct CmContext *>(&context));
395 
396     CmFree(myData);
397     CmFreeParamSet(&paramSet);
398     return true;
399 }
400 }
401