1 /*
2 * Copyright (c) 2024 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 "napicommonwant_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20
21 #define private public
22 #define protected public
23 #include "napi_common_want.h"
24 #undef protected
25 #undef private
26
27 #include "ability_record.h"
28 #include "array_wrapper.h"
29 #include "bool_wrapper.h"
30 #include "byte_wrapper.h"
31 #include "double_wrapper.h"
32 #include "float_wrapper.h"
33 #include "int_wrapper.h"
34 #include "js_environment.h"
35 #include "js_runtime.h"
36 #include "js_runtime_lite.h"
37 #include "long_wrapper.h"
38 #include "remote_object_wrapper.h"
39 #include "runtime.h"
40 #include "short_wrapper.h"
41 #include "string_wrapper.h"
42 #include "zchar_wrapper.h"
43
44 using namespace OHOS::AAFwk;
45 using namespace OHOS::AppExecFwk;
46 using namespace OHOS::AbilityRuntime;
47
48 namespace OHOS {
49 namespace {
50 constexpr int INPUT_ZERO = 0;
51 constexpr int INPUT_ONE = 1;
52 constexpr int INPUT_THREE = 3;
53 constexpr size_t U32_AT_SIZE = 4;
54 constexpr uint8_t ENABLE = 2;
55 constexpr size_t OFFSET_ZERO = 24;
56 constexpr size_t OFFSET_ONE = 16;
57 constexpr size_t OFFSET_TWO = 8;
58 }
59
GetU32Data(const char * ptr)60 uint32_t GetU32Data(const char* ptr)
61 {
62 // convert fuzz input data to an integer
63 return (ptr[INPUT_ZERO] << OFFSET_ZERO) | (ptr[INPUT_ONE] << OFFSET_ONE) | (ptr[ENABLE] << OFFSET_TWO) |
64 ptr[INPUT_THREE];
65 }
66
GetFuzzAbilityToken()67 sptr<Token> GetFuzzAbilityToken()
68 {
69 sptr<Token> token = nullptr;
70 AbilityRequest abilityRequest;
71 abilityRequest.appInfo.bundleName = "com.example.fuzzTest";
72 abilityRequest.abilityInfo.name = "MainAbility";
73 abilityRequest.abilityInfo.type = AbilityType::DATA;
74 std::shared_ptr<AbilityRecord> abilityRecord = AbilityRecord::CreateAbilityRecord(abilityRequest);
75 if (abilityRecord) {
76 token = abilityRecord->GetToken();
77 }
78 return token;
79 }
80
NapiCommonWantFuzztest1(bool boolParam,std::string & stringParam,int32_t int32Param)81 void NapiCommonWantFuzztest1(bool boolParam, std::string &stringParam, int32_t int32Param)
82 {
83 napi_env env = nullptr;
84 ElementName elementName;
85 elementName.SetDeviceID(stringParam);
86 elementName.SetBundleName(stringParam);
87 elementName.SetAbilityName(stringParam);
88 elementName.SetModuleName(stringParam);
89 WrapElementName(env, elementName); // branch failed
90 napi_value param = nullptr;
91 UnwrapElementName(env, param, elementName); // branch failed
92 AAFwk::WantParams wantParams1;
93 WrapWantParams(env, wantParams1); // branch failed
94 wantParams1.SetParam("intf1", String::Box(stringParam));
95 wantParams1.SetParam("intf2", Long::Box(int32Param));
96 wantParams1.SetParam("intf3", Boolean::Box(boolParam));
97 wantParams1.SetParam("intf4", Integer::Box(int32Param));
98 wantParams1.SetParam("intf5", Float::Box(int32Param));
99 wantParams1.SetParam("intf5", RemoteObjectWrap::Box(nullptr));
100 wantParams1.SetParam("intf6", Char::Box(int32Param));
101 wantParams1.SetParam("intf7", Double::Box(int32Param));
102 wantParams1.SetParam("intf8", Byte::Box(int32Param));
103 std::size_t size = 3; // 3 means arraysize.
104 sptr<IArray> ao = new (std::nothrow) Array(size, g_IID_IBoolean);
105 if (ao != nullptr) {
106 for (std::size_t i = 0; i < size; i++) {
107 ao->Set(i, Boolean::Box(boolParam));
108 }
109 wantParams1.SetParam("intf8", ao);
110 }
111 WrapWantParams(env, wantParams1); // branch failed
112 UnwrapWantParams(env, param, wantParams1); // branch failed
113 BlackListFilter(Want::PARAM_RESV_WINDOW_MODE); // branch
114 BlackListFilter(Want::PARAM_RESV_DISPLAY_ID); // branch
115 BlackListFilter(stringParam); // branch
116 Want want;
117 WrapWant(env, want); // branch
118 UnwrapWant(env, param, want); // branch
119 int resultCode = 0;
120 WrapAbilityResult(env, resultCode, want); // branch
121 UnWrapAbilityResult(env, param, resultCode, want); // branch
122 napi_value jsProValue = nullptr;
123 HandleNapiObject(env, param, jsProValue, stringParam, wantParams1); // branch
124 IsSpecialObject(env, param, stringParam, stringParam, static_cast<napi_valuetype>(int32Param)); // branch
125 HandleFdObject(env, param, stringParam, wantParams1); // branch
126 HandleRemoteObject(env, param, stringParam, wantParams1); // branch
127 CreateJsWant(env, want); // branch
128 CreateJsWantParams(env, wantParams1); // branch
129 }
130
NapiCommonWantFuzztest2(bool boolParam,std::string & stringParam,int32_t int32Param)131 void NapiCommonWantFuzztest2(bool boolParam, std::string &stringParam, int32_t int32Param)
132 {
133 napi_env env = nullptr;
134 AAFwk::WantParams wantParams1;
135 napi_value object = nullptr;
136 InnerWrapJsWantParamsWantParams(env, object, stringParam, wantParams1); // failed
137 std::size_t size = 3; // 3 means arraysize.
138 sptr<IArray> ao = new (std::nothrow) Array(size, g_IID_IBoolean);
139 if (ao != nullptr) {
140 for (std::size_t i = 0; i < size; i++) {
141 ao->Set(i, Boolean::Box(boolParam));
142 }
143 }
144 WrapJsWantParamsArray(env, object, stringParam, ao); // branch
145 }
146
NapiCommonWantFuzztest3(bool boolParam,std::string & stringParam,int32_t int32Param)147 void NapiCommonWantFuzztest3(bool boolParam, std::string &stringParam, int32_t int32Param)
148 {
149 std::shared_ptr<OHOS::JsEnv::JsEnvironment> jsEnv = nullptr;
150 AbilityRuntime::Runtime::Options options;
151 auto err = JsRuntimeLite::GetInstance().CreateJsEnv(options, jsEnv);
152 napi_env env = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
153 ElementName elementName1;
154 elementName1.SetDeviceID(stringParam);
155 elementName1.SetBundleName(stringParam);
156 elementName1.SetAbilityName(stringParam);
157 elementName1.SetModuleName(stringParam);
158 napi_value jsObject = WrapElementName(env, elementName1); // branch
159
160 napi_value param = nullptr;
161 ElementName elementName2;
162 UnwrapElementName(env, param, elementName2); // branch null param
163 ElementName elementName3;
164 UnwrapElementName(env, jsObject, elementName3); // branch not null param
165
166 AAFwk::WantParams wantParams1;
167 WrapWantParams(env, wantParams1);
168 wantParams1.SetParam("intf1", String::Box(stringParam));
169 wantParams1.SetParam("intf2", Long::Box(int32Param));
170 wantParams1.SetParam("intf3", Boolean::Box(boolParam));
171 wantParams1.SetParam("intf4", Integer::Box(int32Param));
172 wantParams1.SetParam("intf5", Float::Box(int32Param));
173 wantParams1.SetParam("intf5", RemoteObjectWrap::Box(nullptr));
174 wantParams1.SetParam("intf6", Char::Box(int32Param));
175 wantParams1.SetParam("intf7", Double::Box(int32Param));
176 wantParams1.SetParam("intf8", Byte::Box(int32Param));
177 std::size_t size = 3; // 3 means arraysize.
178 sptr<IArray> ao = new (std::nothrow) Array(size, g_IID_IBoolean);
179 if (ao != nullptr) {
180 for (std::size_t i = 0; i < size; i++) {
181 ao->Set(i, Boolean::Box(boolParam));
182 }
183 wantParams1.SetParam("intf8", ao);
184 }
185 WrapWantParams(env, wantParams1); // branch null param
186 UnwrapWantParams(env, param, wantParams1); // branch null param
187 UnwrapWantParams(env, jsObject, wantParams1); // branch not null param
188 }
189
NapiCommonWantFuzztest4(bool boolParam,std::string & stringParam,int32_t int32Param)190 void NapiCommonWantFuzztest4(bool boolParam, std::string &stringParam, int32_t int32Param)
191 {
192 napi_value param = nullptr;
193 std::shared_ptr<OHOS::JsEnv::JsEnvironment> jsEnv = nullptr;
194 AbilityRuntime::Runtime::Options options;
195 auto err = JsRuntimeLite::GetInstance().CreateJsEnv(options, jsEnv);
196 napi_env env = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
197 Want want;
198 want.SetElementName(stringParam, stringParam, stringParam, stringParam);
199 WrapWant(env, want); // wrap
200
201 UnwrapWant(env, param, want); // branch null param
202 ElementName elementName1;
203 elementName1.SetDeviceID(stringParam);
204 elementName1.SetBundleName(stringParam);
205 elementName1.SetAbilityName(stringParam);
206 elementName1.SetModuleName(stringParam);
207 napi_value jsObject = WrapElementName(env, elementName1); // branch
208 UnwrapWant(env, jsObject, want); // branch not null param
209
210 int resultCode = 0;
211 napi_value jsonObject1 = WrapAbilityResult(env, resultCode, want); // env not null
212 UnWrapAbilityResult(env, param, resultCode, want); // null param
213 UnWrapAbilityResult(env, jsonObject1, resultCode, want); // null param
214
215 napi_value jsProValue = nullptr;
216 AAFwk::WantParams wantParams1;
217 HandleNapiObject(env, param, jsProValue, stringParam, wantParams1); // param null
218 HandleNapiObject(env, jsObject, jsProValue, stringParam, wantParams1); // param not null jsProValue null.
219
220 IsSpecialObject(env, param, stringParam, stringParam, static_cast<napi_valuetype>(int32Param)); // param null
221 IsSpecialObject(env, jsObject, stringParam, stringParam, static_cast<napi_valuetype>(int32Param)); // param not null
222
223 HandleFdObject(env, param, stringParam, wantParams1); // branch null param
224 HandleRemoteObject(env, param, stringParam, wantParams1); // branch null param
225 CreateJsWant(env, want); // branch
226 CreateJsWantParams(env, wantParams1); // branch
227 napi_value object = nullptr;
228 InnerWrapJsWantParamsWantParams(env, object, stringParam, wantParams1); // branch null object
229 napi_value jsObject2 = nullptr;
230 napi_create_object(env, &jsObject2);
231 InnerWrapJsWantParamsWantParams(env, jsObject2, stringParam, wantParams1); // branch object, key not exist.
232 AAFwk::WantParams wantParams2;
233 wantParams2.SetParam("intf1", String::Box(stringParam));
234 InnerWrapJsWantParamsWantParams(env, jsObject2, "intf1", wantParams2); // branch object, key exist.
235 }
236
NapiCommonWantFuzztest5(bool boolParam,std::string & stringParam,int32_t int32Param)237 void NapiCommonWantFuzztest5(bool boolParam, std::string &stringParam, int32_t int32Param)
238 {
239 napi_value param = nullptr;
240 std::shared_ptr<OHOS::JsEnv::JsEnvironment> jsEnv = nullptr;
241 AbilityRuntime::Runtime::Options options;
242 auto err = JsRuntimeLite::GetInstance().CreateJsEnv(options, jsEnv);
243 napi_env env = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
244 napi_value nullObject = nullptr;
245 std::size_t size = 3; // 3 means arraysize.
246 sptr<IArray> ao1 = new (std::nothrow) Array(size, g_IID_IBoolean);
247 if (ao1 != nullptr) {
248 for (std::size_t i = 0; i < size; i++) {
249 ao1->Set(i, Boolean::Box(boolParam));
250 }
251 }
252 WrapJsWantParamsArray(env, nullObject, stringParam, ao1); // null object.
253 napi_value jsObject1 = nullptr;
254 napi_create_object(env, &jsObject1);
255 WrapJsWantParamsArray(env, jsObject1, stringParam, ao1); // not null object.
256
257 sptr<IArray> ao2 = new (std::nothrow) Array(size, g_IID_IChar);
258 if (ao2 != nullptr) {
259 for (std::size_t i = 0; i < size; i++) {
260 ao2->Set(i, Char::Box(int32Param));
261 }
262 }
263 WrapJsWantParamsArray(env, nullObject, stringParam, ao2); // null object.
264 napi_value jsObject2 = nullptr;
265 napi_create_object(env, &jsObject2);
266 WrapJsWantParamsArray(env, jsObject2, stringParam, ao2); // not null object.
267
268 sptr<IArray> ao3 = new (std::nothrow) Array(size, g_IID_IByte);
269 if (ao3 != nullptr) {
270 for (std::size_t i = 0; i < size; i++) {
271 ao3->Set(i, Byte::Box(int32Param));
272 }
273 }
274 WrapJsWantParamsArray(env, nullObject, stringParam, ao3); // null object.
275 napi_value jsObject3 = nullptr;
276 napi_create_object(env, &jsObject3);
277 WrapJsWantParamsArray(env, jsObject3, stringParam, ao3); // not null object.
278
279 sptr<IArray> ao4 = new (std::nothrow) Array(size, g_IID_IShort);
280 if (ao4 != nullptr) {
281 for (std::size_t i = 0; i < size; i++) {
282 ao4->Set(i, Short::Box(int32Param));
283 }
284 }
285 WrapJsWantParamsArray(env, nullObject, stringParam, ao4); // null object.
286 napi_value jsObject4 = nullptr;
287 napi_create_object(env, &jsObject4);
288 WrapJsWantParamsArray(env, jsObject4, stringParam, ao4); // not null object.
289 }
290
NapiCommonWantFuzztest6(bool boolParam,std::string & stringParam,int32_t int32Param)291 void NapiCommonWantFuzztest6(bool boolParam, std::string &stringParam, int32_t int32Param)
292 {
293 napi_value param = nullptr;
294 std::shared_ptr<OHOS::JsEnv::JsEnvironment> jsEnv = nullptr;
295 AbilityRuntime::Runtime::Options options;
296 auto err = JsRuntimeLite::GetInstance().CreateJsEnv(options, jsEnv);
297 napi_env env = reinterpret_cast<napi_env>(jsEnv->GetNativeEngine());
298 napi_value nullObject = nullptr;
299 std::size_t size = 3; // 3 means arraysize.
300 sptr<IArray> ao1 = new (std::nothrow) Array(size, g_IID_ILong);
301 if (ao1 != nullptr) {
302 for (std::size_t i = 0; i < size; i++) {
303 ao1->Set(i, Long::Box(int32Param));
304 }
305 }
306 WrapJsWantParamsArray(env, nullObject, stringParam, ao1); // null object.
307 napi_value jsObject1 = nullptr;
308 napi_create_object(env, &jsObject1);
309 WrapJsWantParamsArray(env, jsObject1, stringParam, ao1); // not null object.
310
311 sptr<IArray> ao2 = new (std::nothrow) Array(size, g_IID_IFloat);
312 if (ao2 != nullptr) {
313 for (std::size_t i = 0; i < size; i++) {
314 ao2->Set(i, Float::Box(int32Param));
315 }
316 }
317 WrapJsWantParamsArray(env, nullObject, stringParam, ao2); // null object.
318 napi_value jsObject2 = nullptr;
319 napi_create_object(env, &jsObject2);
320 WrapJsWantParamsArray(env, jsObject2, stringParam, ao2); // not null object.
321
322 sptr<IArray> ao3 = new (std::nothrow) Array(size, g_IID_IDouble);
323 if (ao3 != nullptr) {
324 for (std::size_t i = 0; i < size; i++) {
325 ao3->Set(i, Double::Box(int32Param));
326 }
327 }
328 WrapJsWantParamsArray(env, nullObject, stringParam, ao3); // null object.
329 napi_value jsObject3 = nullptr;
330 napi_create_object(env, &jsObject3);
331 WrapJsWantParamsArray(env, jsObject3, stringParam, ao3); // not null object.
332
333 sptr<IArray> ao4 = new (std::nothrow) Array(size, g_IID_IString);
334 if (ao4 != nullptr) {
335 for (std::size_t i = 0; i < size; i++) {
336 ao4->Set(i, String::Box(stringParam));
337 }
338 }
339 WrapJsWantParamsArray(env, nullObject, stringParam, ao4); // null object.
340 napi_value jsObject4 = nullptr;
341 napi_create_object(env, &jsObject4);
342 WrapJsWantParamsArray(env, jsObject4, stringParam, ao4); // not null object.
343 }
344
DoSomethingInterestingWithMyAPI(const char * data,size_t size)345 bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
346 {
347 bool boolParam = *data % ENABLE;
348 std::string stringParam(data, size);
349 int32_t int32Param = static_cast<int32_t>(GetU32Data(data));
350 NapiCommonWantFuzztest1(boolParam, stringParam, int32Param);
351 NapiCommonWantFuzztest2(boolParam, stringParam, int32Param);
352 NapiCommonWantFuzztest3(boolParam, stringParam, int32Param);
353 NapiCommonWantFuzztest4(boolParam, stringParam, int32Param);
354 NapiCommonWantFuzztest5(boolParam, stringParam, int32Param);
355 NapiCommonWantFuzztest6(boolParam, stringParam, int32Param);
356 return true;
357 }
358 }
359
360 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)361 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
362 {
363 /* Run your code on data */
364 if (data == nullptr) {
365 return 0;
366 }
367
368 /* Validate the length of size */
369 if (size < OHOS::U32_AT_SIZE) {
370 return 0;
371 }
372
373 char* ch = static_cast<char*>(malloc(size + 1));
374 if (ch == nullptr) {
375 std::cout << "malloc failed." << std::endl;
376 return 0;
377 }
378
379 (void)memset_s(ch, size + 1, 0x00, size + 1);
380 if (memcpy_s(ch, size, data, size) != EOK) {
381 std::cout << "copy failed." << std::endl;
382 free(ch);
383 ch = nullptr;
384 return 0;
385 }
386
387 OHOS::DoSomethingInterestingWithMyAPI(ch, size);
388 free(ch);
389 ch = nullptr;
390 return 0;
391 }
392
393