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