1 /*
2  * Copyright (C) 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 <cstdio>
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <iostream>
20 #include "mindspore_fuzzer.h"
21 #include "../data.h"
22 #include "include/c_api/context_c.h"
23 #include "include/c_api/model_c.h"
24 #include "../../utils/model_utils.h"
25 #include "context_c_fuzzer.h"
26 
MSPreparedModelFuzzTest(const uint8_t* data, size_t size)27 bool MSPreparedModelFuzzTest(const uint8_t* data, size_t size) {
28     if (data == nullptr) {
29         return false;
30     }
31 
32     OH_AI_ContextHandle context = OH_AI_ContextCreate();
33     if (context == nullptr) {
34         printf("create context failed.\n");
35         return false;
36     }
37     OH_AI_ContextSetThreadNum(context, 4);
38 
39     OH_AI_DeviceInfoHandle cpuDeviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);
40     if (cpuDeviceInfo == NULL) {
41         printf("OH_AI_DeviceInfoCreate failed.\n");
42         OH_AI_ContextDestroy(&context);
43         return false;
44     }
45     OH_AI_ContextAddDeviceInfo(context, cpuDeviceInfo);
46 
47     OH_AI_ModelHandle model = OH_AI_ModelCreate();
48     if (model == nullptr) {
49         printf("create model failed.\n");
50         return false;
51     }
52 
53     OH_AI_ContextDestroy(&context);
54     OH_AI_ModelDestroy(&model);
55     return true;
56 }
57 
MSContextFuzzTest_Null(const uint8_t* data, size_t size)58 bool MSContextFuzzTest_Null(const uint8_t* data, size_t size) {
59     OH_AI_ContextHandle context = nullptr;
60 
61     OH_AI_ContextSetThreadNum(context, 4);
62     auto retThreadNum = OH_AI_ContextGetThreadNum(context);
63     if (retThreadNum != 0) {
64         printf("OH_AI_ContextGetThreadNum failed.\n");
65         return false;
66     }
67 
68     OH_AI_ContextSetThreadAffinityMode(context, 1);
69     auto ret = OH_AI_ContextGetThreadAffinityMode(context);
70     if (ret != 0) {
71         printf("OH_AI_ContextGetThreadAffinityMode failed.\n");
72         return false;
73     }
74 
75     OH_AI_ContextSetThreadAffinityCoreList(context, nullptr, 0);
76     auto retCoreList = OH_AI_ContextGetThreadAffinityCoreList(context, nullptr);
77     if (retCoreList != 0) {
78         printf("OH_AI_ContextGetThreadAffinityCoreList failed.\n");
79         return false;
80     }
81 
82     OH_AI_ContextSetEnableParallel(context, true);
83     auto retParallel = OH_AI_ContextGetEnableParallel(context);
84     if (retParallel != false) {
85         printf("OH_AI_ContextGetEnableParallel failed.\n");
86         return false;
87     }
88 
89 
90     OH_AI_DeviceInfoHandle deviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);
91     if (deviceInfo == nullptr) {
92         printf("OH_AI_DeviceInfoCreate cpu failed.\n");
93         return false;
94     }
95     OH_AI_DeviceInfoDestroy(&deviceInfo);
96 
97     deviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_INVALID);
98     if (deviceInfo != nullptr) {
99         printf("OH_AI_DeviceInfoCreate failed.\n");
100         return false;
101     }
102     OH_AI_ContextAddDeviceInfo(context, deviceInfo);
103     OH_AI_DeviceInfoSetProvider(deviceInfo, nullptr);
104     auto retProvider = OH_AI_DeviceInfoGetProvider(deviceInfo);
105     if (retProvider != nullptr) {
106         printf("OH_AI_DeviceInfoGetProvider failed.\n");
107         return false;
108     }
109 
110     OH_AI_DeviceInfoSetProviderDevice(deviceInfo, nullptr);
111     auto retProDevice = OH_AI_DeviceInfoGetProviderDevice(deviceInfo);
112     if (retProDevice != nullptr) {
113         printf("OH_AI_DeviceInfoGetProviderDevice failed.\n");
114         return false;
115     }
116     auto deviceType = OH_AI_DeviceInfoGetDeviceType(deviceInfo);
117     if (deviceType != OH_AI_DEVICETYPE_INVALID) {
118         printf("OH_AI_DeviceInfoGetDeviceType failed.\n");
119         return false;
120     }
121 
122     OH_AI_DeviceInfoSetEnableFP16(deviceInfo, true);
123     auto retEnableFp16 = OH_AI_DeviceInfoGetEnableFP16(deviceInfo);
124     if (retEnableFp16 != false) {
125         printf("OH_AI_DeviceInfoGetEnableFP16 failed.\n");
126         return false;
127     }
128     OH_AI_DeviceInfoSetFrequency(deviceInfo, 1);
129     auto retFrequency = OH_AI_DeviceInfoGetFrequency(deviceInfo);
130     if (retFrequency != -1) {
131         printf("OH_AI_DeviceInfoGetFrequency failed.\n");
132         return false;
133     }
134 
135     OH_AI_DeviceInfoSetDeviceId(deviceInfo, 1);
136     auto retDeviceId = OH_AI_DeviceInfoGetDeviceId(deviceInfo);
137     if (retDeviceId != 0) {
138         printf("OH_AI_DeviceInfoGetDeviceId failed.\n");
139         return false;
140     }
141     OH_AI_DeviceInfoSetPerformanceMode(deviceInfo, OH_AI_PERFORMANCE_HIGH);
142     auto retPerMode = OH_AI_DeviceInfoGetPerformanceMode(deviceInfo);
143     if (retPerMode != OH_AI_PERFORMANCE_NONE) {
144         printf("OH_AI_DeviceInfoGetPerformanceMode failed.\n");
145         return false;
146     }
147     OH_AI_DeviceInfoSetPriority(deviceInfo, OH_AI_PRIORITY_HIGH);
148     auto retPriority = OH_AI_DeviceInfoGetPriority(deviceInfo);
149     if (retPriority != OH_AI_PRIORITY_NONE) {
150         printf("OH_AI_DeviceInfoGetPriority failed.\n");
151         return false;
152     }
153     auto retExt = OH_AI_DeviceInfoAddExtension(deviceInfo, nullptr, nullptr, 0);
154     if (retExt != OH_AI_STATUS_LITE_NULLPTR) {
155         printf("OH_AI_DeviceInfoAddExtension failed.\n");
156         return false;
157     }
158     return true;
159 }
160 
MSTensorFuzzTest_Null(const uint8_t* data, size_t size)161 bool MSTensorFuzzTest_Null(const uint8_t* data, size_t size) {
162     OH_AI_TensorHandle tensor = OH_AI_TensorCreate(nullptr, OH_AI_DATATYPE_NUMBERTYPE_FLOAT32, nullptr, 0, nullptr, 0);
163     OH_AI_TensorDestroy(&tensor);
164 
165     auto retClone = OH_AI_TensorClone(tensor);
166     if (retClone != nullptr) {
167         printf("OH_AI_TensorClone failed.\n");
168         return false;
169     }
170     OH_AI_TensorSetName(tensor, nullptr);
171     auto retGetName = OH_AI_TensorGetName(tensor);
172     if (retGetName != nullptr) {
173         printf("OH_AI_TensorGetName failed.\n");
174         return false;
175     }
176     OH_AI_TensorSetDataType(tensor, OH_AI_DATATYPE_NUMBERTYPE_INT64);
177     auto retGetDataType = OH_AI_TensorGetDataType(tensor);
178     if (retGetDataType != OH_AI_DATATYPE_UNKNOWN) {
179         printf("OH_AI_TensorGetDataType failed.\n");
180         return false;
181     }
182     OH_AI_TensorSetShape(tensor, nullptr, 0);
183     auto retGetShape = OH_AI_TensorGetShape(tensor, nullptr);
184     if (retGetShape != nullptr) {
185         printf("OH_AI_TensorGetShape failed.\n");
186         return false;
187     }
188     OH_AI_TensorSetFormat(tensor, OH_AI_FORMAT_KHWC);
189     auto retGetFormat = OH_AI_TensorGetFormat(tensor);
190     if (retGetFormat != OH_AI_FORMAT_NHWC) {
191         printf("OH_AI_TensorGetFormat failed.\n");
192         return false;
193     }
194     OH_AI_TensorSetData(tensor, nullptr);
195     auto retSetUserData = OH_AI_TensorSetUserData(tensor, nullptr, 0);
196     if (retSetUserData != OH_AI_STATUS_LITE_NULLPTR) {
197         printf("OH_AI_TensorSetUserData failed.\n");
198         return false;
199     }
200     auto retGetData = OH_AI_TensorGetData(tensor);
201     if (retGetData != nullptr) {
202         printf("OH_AI_TensorGetData failed.\n");
203         return false;
204     }
205     auto retMutaData = OH_AI_TensorGetMutableData(tensor);
206     if (retMutaData != nullptr) {
207         printf("OH_AI_TensorGetMutableData failed.\n");
208         return false;
209     }
210     auto retEleNum = OH_AI_TensorGetElementNum(tensor);
211     if (retEleNum != 0) {
212         printf("OH_AI_TensorGetElementNum failed.\n");
213         return false;
214     }
215     auto retDataSize = OH_AI_TensorGetDataSize(tensor);
216     if (retDataSize != 0) {
217         printf("OH_AI_TensorGetDataSize failed.\n");
218         return false;
219     }
220     return true;
221 }
222 
MSModelFuzzTest_Null(const uint8_t* data, size_t size)223 bool MSModelFuzzTest_Null(const uint8_t* data, size_t size) {
224     OH_AI_ModelHandle model = OH_AI_ModelCreate();
225     if (model == nullptr) {
226         printf("create model failed.\n");
227         return false;
228     }
229     OH_AI_ModelDestroy(&model);
230     OH_AI_ModelSetWorkspace(model, nullptr, 0);
231     OH_AI_ModelCalcWorkspaceSize(model);
232     auto ret = OH_AI_ModelBuild(model, nullptr, 0, OH_AI_MODELTYPE_MINDIR, nullptr);
233     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
234         printf("OH_AI_ModelBuild failed.\n");
235         return false;
236     }
237     ret = OH_AI_ModelBuildFromFile(model, nullptr, OH_AI_MODELTYPE_MINDIR, nullptr);
238     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
239         printf("OH_AI_ModelBuildFromFile failed.\n");
240         return false;
241     }
242     ret = OH_AI_ModelResize(model, {0, nullptr}, nullptr, 0);
243     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
244         printf("OH_AI_ModelResize failed.\n");
245         return false;
246     }
247     OH_AI_TensorHandleArray outputs = {0, nullptr};
248     ret = OH_AI_ModelPredict(model, {0, nullptr}, &outputs, nullptr, nullptr);
249     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
250         printf("OH_AI_ModelPredict failed.\n");
251         return false;
252     }
253     OH_AI_ModelRunStep(model, nullptr, nullptr);
254     OH_AI_ModelExportWeight(model, nullptr);
255     auto retInputs = OH_AI_ModelGetInputs(model);
256     if (retInputs.handle_list != nullptr) {
257         printf("OH_AI_ModelGetInputs failed.\n");
258         return false;
259     }
260     auto retOutputs = OH_AI_ModelGetOutputs(model);
261     if (retOutputs.handle_list != nullptr) {
262         printf("OH_AI_ModelGetOutputs failed.\n");
263         return false;
264     }
265     OH_AI_ModelGetInputByTensorName(model, nullptr);
266     OH_AI_ModelGetOutputByTensorName(model, nullptr);
267     auto trainCfg = OH_AI_TrainCfgCreate();
268     if (trainCfg == nullptr) {
269         printf("OH_AI_TrainCfgCreate failed.\n");
270         return false;
271     }
272     OH_AI_TrainCfgDestroy(&trainCfg);
273     auto retLossName = OH_AI_TrainCfgGetLossName(trainCfg, nullptr);
274     if (retLossName != nullptr) {
275         printf("OH_AI_TrainCfgGetLossName failed.\n");
276         return false;
277     }
278     OH_AI_TrainCfgSetLossName(trainCfg, nullptr, 0);
279     auto retOptLevel = OH_AI_TrainCfgGetOptimizationLevel(trainCfg);
280     if (retOptLevel != OH_AI_KO0) {
281         printf("OH_AI_TrainCfgGetOptimizationLevel failed.\n");
282         return false;
283     }
284     OH_AI_TrainCfgSetOptimizationLevel(trainCfg, OH_AI_KAUTO);
285     ret = OH_AI_TrainModelBuild(model, nullptr, 0, OH_AI_MODELTYPE_MINDIR, nullptr, trainCfg);
286     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
287         printf("OH_AI_TrainModelBuild failed.\n");
288         return false;
289     }
290     ret = OH_AI_TrainModelBuildFromFile(model, nullptr, OH_AI_MODELTYPE_MINDIR, nullptr, trainCfg);
291     if (ret != OH_AI_STATUS_LITE_NULLPTR) {
292         printf("OH_AI_TrainModelBuildFromFile failed.\n");
293         return false;
294     }
295     ret = OH_AI_ModelSetLearningRate(model, 0.0f);
296     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
297         printf("OH_AI_ModelSetLearningRate failed.\n");
298         return false;
299     }
300     OH_AI_ModelGetLearningRate(model);
301     ret = OH_AI_RunStep(model, nullptr, nullptr);
302     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
303         printf("OH_AI_RunStep failed.\n");
304         return false;
305     }
306     auto retGetWeights = OH_AI_ModelGetWeights(model);
307     if (retGetWeights.handle_list != nullptr) {
308         printf("OH_AI_ModelGetWeights failed.\n");
309         return false;
310     }
311     ret = OH_AI_ModelUpdateWeights(model, {0, nullptr});
312     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
313         printf("OH_AI_ModelUpdateWeights failed.\n");
314         return false;
315     }
316     auto retTrainMode = OH_AI_ModelGetTrainMode(model);
317     if (retTrainMode != false) {
318         printf("OH_AI_ModelGetTrainMode failed.\n");
319         return false;
320     }
321     ret = OH_AI_ModelSetTrainMode(model, true);
322     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
323         printf("OH_AI_ModelSetTrainMode failed.\n");
324         return false;
325     }
326     ret = OH_AI_ModelSetupVirtualBatch(model, 0, 0.0f, 0.0f);
327     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
328         printf("OH_AI_ModelSetupVirtualBatch failed.\n");
329         return false;
330     }
331     ret = OH_AI_ExportModel(model, OH_AI_MODELTYPE_MINDIR, nullptr, OH_AI_UNKNOWN_QUANT_TYPE, true, nullptr, 0);
332     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
333         printf("OH_AI_ExportModel failed.\n");
334         return false;
335     }
336     ret = OH_AI_ExportModelBuffer(model, OH_AI_MODELTYPE_MINDIR, nullptr, nullptr, OH_AI_FULL_QUANT, true, nullptr, 0);
337     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
338         printf("OH_AI_ExportModelBuffer failed.\n");
339         return false;
340     }
341     ret = OH_AI_ExportWeightsCollaborateWithMicro(model, OH_AI_MODELTYPE_MINDIR, nullptr, true, true, nullptr, 0);
342     if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
343         printf("OH_AI_ExportWeightsCollaborateWithMicro failed.\n");
344         return false;
345     }
346     return true;
347 }
348 
349 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)350 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
351 {
352     if (data == nullptr) {
353         LOGE("Pass data is nullptr.");
354         return 0;
355     }
356 
357     if (size < 4) {
358         LOGE("Pass size is too small.");
359         return 0;
360     }
361 
362     MSPreparedModelFuzzTest(data, size);
363     MSModelFuzzTest_Null(data, size);
364     MSContextFuzzTest_Null(data, size);
365     MSTensorFuzzTest_Null(data, size);
366     return 0;
367 }