• 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 #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, &paramSet) != 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, &paramSetBlob) != 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(&paramSet);
364         return false;
365     }
366 
367     OHOS::MessageParcel context;
368     (void)ipcServiceApi(&paramSetBlob, &outData, reinterpret_cast<struct CmContext *>(&context));
369 
370     CmFree(myData);
371     CmFreeParamSet(&paramSet);
372     return true;
373 }
374 }
375