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 42using namespace OHOS::AAFwk; 43using namespace OHOS::AppExecFwk; 44using namespace OHOS::AbilityRuntime; 45 46namespace OHOS { 47namespace { 48constexpr int INPUT_ZERO = 0; 49constexpr int INPUT_ONE = 1; 50constexpr int INPUT_THREE = 3; 51constexpr size_t FOO_MAX_LEN = 1024; 52constexpr size_t U32_AT_SIZE = 4; 53constexpr uint8_t ENABLE = 2; 54constexpr size_t OFFSET_ZERO = 24; 55constexpr size_t OFFSET_ONE = 16; 56constexpr size_t OFFSET_TWO = 8; 57} 58 59uint32_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 66sptr<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 80void 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 130void 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 146void 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 189void 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 236void 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 290void 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 344bool 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 */ 360extern "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 = (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