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 "distributedwantparams_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <fuzzer/FuzzedDataProvider.h>
21 #include <iostream>
22
23 #include "array_wrapper.h"
24 #include "bool_wrapper.h"
25 #include "byte_wrapper.h"
26 #include "distributed_want_params.h"
27 #include "distributed_want_params_wrapper.h"
28 #include "double_wrapper.h"
29 #include "float_wrapper.h"
30 #include "int_wrapper.h"
31 #include "long_wrapper.h"
32 #include "securec.h"
33 #include "short_wrapper.h"
34 #include "string_wrapper.h"
35 #include "zchar_wrapper.h"
36
37 using namespace OHOS::AAFwk;
38 using namespace OHOS::DistributedSchedule;
39
40 namespace OHOS {
41 namespace {
42 constexpr size_t FOO_MAX_LEN = 1024;
43 constexpr size_t U32_AT_SIZE = 4;
44 constexpr int32_t POS_0 = 0;
45 constexpr int32_t POS_1 = 1;
46 constexpr int32_t POS_2 = 2;
47 constexpr int32_t POS_3 = 3;
48 constexpr int32_t OFFSET_24 = 24;
49 constexpr int32_t OFFSET_16 = 16;
50 constexpr int32_t OFFSET_8 = 8;
51 constexpr int32_t MID_HALF = 2;
52 constexpr size_t MAX_TEST_STRING_LEN = 32;
53
CalculateMid(size_t size)54 inline size_t CalculateMid(size_t size)
55 {
56 return size / MID_HALF;
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[POS_0] << OFFSET_24) | (ptr[POS_1] << OFFSET_16) | (ptr[POS_2] << OFFSET_8) | ptr[POS_3];
63 }
64
DoSomethingInterestingWithMyApiDistributedWantParams001(const uint8_t * data,size_t size)65 bool DoSomethingInterestingWithMyApiDistributedWantParams001(const uint8_t* data, size_t size)
66 {
67 if (data == nullptr || size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
68 return false;
69 }
70
71 DistributedWantParams wantOther;
72 FuzzedDataProvider fdp(data, size);
73 std::string key = fdp.ConsumeRandomLengthString();
74 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
75 sptr<AAFwk::IArray> array = new (std::nothrow) AAFwk::Array(0, DistributedSchedule::g_IID_IDistributedWantParams);
76 wantParams->SetParam(key, array);
77 IArray *iarray = IArray::Query(array);
78 sptr<IArray> destAO = nullptr;
79 wantParams->NewArrayData(iarray, destAO);
80 sptr<IInterface> stringIt = String::Box(key);
81 wantParams->Remove(key);
82 wantParams->SetParam(key, stringIt);
83 wantParams->KeySet();
84 wantParams->HasParam(key);
85 wantParams->IsEmpty();
86 wantParams->GetParams();
87 return true;
88 }
89
DoSomethingInterestingWithMyApiDistributedWantParams002(const uint8_t * data,size_t size)90 bool DoSomethingInterestingWithMyApiDistributedWantParams002(const uint8_t* data, size_t size)
91 {
92 if (data == nullptr || size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
93 return false;
94 }
95
96 DistributedWantParams wantOther;
97 FuzzedDataProvider fdp(data, size);
98 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
99 Parcel parcel;
100 IArray* ao = nullptr;
101 wantParams->WriteArrayToParcelChar(parcel, ao);
102 wantParams->WriteArrayToParcelShort(parcel, ao);
103 wantParams->WriteArrayToParcelString(parcel, ao);
104 wantParams->WriteArrayToParcelBool(parcel, ao);
105 wantParams->WriteArrayToParcelByte(parcel, ao);
106 wantParams->WriteArrayToParcelInt(parcel, ao);
107 wantParams->WriteArrayToParcelLong(parcel, ao);
108 wantParams->WriteArrayToParcelFloat(parcel, ao);
109 wantParams->WriteArrayToParcelDouble(parcel, ao);
110 long longValue = static_cast<long>(GetU32Data(reinterpret_cast<const char*>(data)));
111 sptr<IInterface> longIt = Long::Box(longValue);
112 wantParams->WriteToParcelLong(parcel, longIt);
113 float floatValue = static_cast<float>(GetU32Data(reinterpret_cast<const char*>(data)));
114 sptr<IInterface> floatIt = Float::Box(floatValue);
115 wantParams->WriteToParcelFloat(parcel, floatIt);
116
117 sptr<IArray> array;
118 wantParams->ReadFromParcelArrayChar(parcel, array);
119 wantParams->ReadFromParcelArrayShort(parcel, array);
120 wantParams->ReadFromParcelArrayString(parcel, array);
121 wantParams->ReadFromParcelArrayBool(parcel, array);
122 wantParams->ReadFromParcelArrayByte(parcel, array);
123 wantParams->ReadFromParcelArrayInt(parcel, array);
124 wantParams->ReadFromParcelArrayLong(parcel, array);
125 wantParams->ReadFromParcelArrayFloat(parcel, array);
126 wantParams->ReadFromParcelArrayDouble(parcel, array);
127 std::string key = fdp.ConsumeRandomLengthString();
128 wantParams->ReadFromParcelLong(parcel, key);
129 wantParams->ReadFromParcelFloat(parcel, key);
130
131 wantParams->ReadArrayToParcel(parcel, GetU32Data(reinterpret_cast<const char*>(data)) % OFFSET_16, array);
132 return true;
133 }
134
DoSomethingInterestingWithMyApiDistributedWant003(const uint8_t * data,size_t size)135 bool DoSomethingInterestingWithMyApiDistributedWant003(const uint8_t* data, size_t size)
136 {
137 if (data == nullptr || size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
138 return false;
139 }
140
141 DistributedWantParams wantOther;
142 FuzzedDataProvider fdp(data, size);
143 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
144 Parcel parcel;
145 std::string key = fdp.ConsumeRandomLengthString();
146 int8_t byteValue = static_cast<int8_t>(GetU32Data(reinterpret_cast<const char*>(data)));
147 sptr<IInterface> byteIt = Byte::Box(byteValue);
148 wantParams->WriteToParcelByte(parcel, byteIt);
149 sptr<IInterface> stringIt = String::Box(key);
150 wantParams->WriteToParcelString(parcel, stringIt);
151 bool boolValue = static_cast<bool>(GetU32Data(reinterpret_cast<const char*>(data)) > FOO_MAX_LEN);
152 sptr<IInterface> boolIt = Boolean::Box(boolValue);
153 wantParams->WriteToParcelBool(parcel, boolIt);
154 char charValue = *data;
155 sptr<IInterface> charIt = Char::Box(charValue);
156 wantParams->WriteToParcelChar(parcel, charIt);
157 short shortValue = static_cast<short>(GetU32Data(reinterpret_cast<const char*>(data)));
158 sptr<IInterface> shortIt = Short::Box(shortValue);
159 wantParams->WriteToParcelShort(parcel, shortIt);
160 double doubleValue = static_cast<double>(GetU32Data(reinterpret_cast<const char*>(data)));
161 sptr<IInterface> doubleIt = Double::Box(doubleValue);
162 wantParams->WriteToParcelDouble(parcel, doubleIt);
163 int32_t intValue = static_cast<int32_t>(GetU32Data(reinterpret_cast<const char*>(data)));
164 sptr<IInterface> intIt = Integer::Box(intValue);
165 wantParams->WriteToParcelInt(parcel, intIt);
166 wantParams->WriteToParcelFD(parcel, wantOther);
167 wantParams->WriteToParcelRemoteObject(parcel, wantOther);
168
169 int type = static_cast<int>(GetU32Data(reinterpret_cast<const char*>(data)));
170 wantParams->ReadFromParcelInt8(parcel, key);
171 wantParams->ReadFromParcelString(parcel, key);
172 wantParams->ReadFromParcelBool(parcel, key);
173 wantParams->ReadFromParcelChar(parcel, key);
174 wantParams->ReadFromParcelShort(parcel, key);
175 wantParams->ReadFromParcelDouble(parcel, key);
176 wantParams->ReadFromParcelInt(parcel, key);
177 wantParams->ReadFromParcelFD(parcel, key);
178 wantParams->ReadFromParcelRemoteObject(parcel, key);
179 wantParams->ReadFromParcelWantParamWrapper(parcel, key, type);
180
181 wantParams->WriteToParcelByte(parcel, byteIt);
182 wantParams->ReadFromParcel(parcel);
183
184 DistributedUnsupportedData uData;
185 wantParams->cachedUnsupportedData_.emplace_back(std::move(uData));
186 wantParams->DoMarshalling(parcel);
187 wantParams->cachedUnsupportedData_.clear();
188 return true;
189 }
190
DoSomethingInterestingWithMyApiDistributedWantParams004(const uint8_t * data,size_t size)191 bool DoSomethingInterestingWithMyApiDistributedWantParams004(const uint8_t* data, size_t size)
192 {
193 if (data == nullptr || size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
194 return false;
195 }
196
197 DistributedWantParams wantOther;
198 FuzzedDataProvider fdp(data, size);
199 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
200
201 std::string value = fdp.ConsumeRandomLengthString();
202 sptr<IInterface> stringObj =
203 DistributedWantParams::GetInterfaceByType(DistributedWantParams::VALUE_TYPE_STRING, value);
204 wantParams->CompareInterface(stringObj, stringObj, DistributedWantParams::VALUE_TYPE_STRING);
205
206 std::string keyStr = "12345667";
207 wantParams->SetParam(keyStr, String::Box(value));
208 Parcel in;
209 wantParams->Marshalling(in);
210 std::shared_ptr<DistributedWantParams> wantParamsNew(DistributedWantParams::Unmarshalling(in));
211
212 wantParams->ToWantParams();
213 return true;
214 }
215
DistributedWantParamWrapperEqualsFuzzTest(const uint8_t * data,size_t size)216 bool DistributedWantParamWrapperEqualsFuzzTest(const uint8_t* data, size_t size)
217 {
218 if (data == nullptr || size == 0) {
219 return false;
220 }
221 size_t mid = CalculateMid(size);
222
223 DistributedWantParams wantOther;
224 std::shared_ptr<DistributedWantParams> wantParams1 = std::make_shared<DistributedWantParams>(wantOther);
225 std::string key1(reinterpret_cast<const char*>(data), mid);
226 std::string value1(reinterpret_cast<const char*>(data + mid), size - mid);
227 wantParams1->SetParam(key1, String::Box(value1));
228
229 std::shared_ptr<DistributedWantParams> wantParams2 = std::make_shared<DistributedWantParams>(wantOther);
230 std::string key2(reinterpret_cast<const char*>(data + mid), size - mid);
231 std::string value2(reinterpret_cast<const char*>(data), mid);
232 wantParams2->SetParam(key2, String::Box(value2));
233
234 DistributedWantParamWrapper wrapper1(*wantParams1);
235 DistributedWantParamWrapper wrapper2(*wantParams2);
236
237 bool result = wrapper1.Equals(wrapper2);
238
239 return result;
240 }
241
DistributedWantParamWrapperFindMatchingBraceFuzzTest(const uint8_t * data,size_t size)242 bool DistributedWantParamWrapperFindMatchingBraceFuzzTest(const uint8_t* data, size_t size)
243 {
244 if (data == nullptr || size == 0) {
245 return false;
246 }
247 FuzzedDataProvider fdp(data, size);
248 std::string inputStr = fdp.ConsumeRandomLengthString();
249
250 size_t startPos = size > 0 ? data[0] % size : 0;
251
252 DistributedWantParams wantOther;
253 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
254 DistributedWantParamWrapper wrapper(*wantParams);
255 size_t result = wrapper.FindMatchingBrace(inputStr, startPos);
256
257 return result >= startPos && result <= inputStr.size();
258 }
259
DistributedWantParamWrapperBoxFuzzTest(const uint8_t * data,size_t size)260 bool DistributedWantParamWrapperBoxFuzzTest(const uint8_t* data, size_t size)
261 {
262 if (data == nullptr || size == 0) {
263 return false;
264 }
265 size_t mid = CalculateMid(size);
266 std::string key(reinterpret_cast<const char*>(data), mid);
267 std::string value(reinterpret_cast<const char*>(data + mid), size - mid);
268
269 DistributedWantParams wantParams;
270 wantParams.SetParam(key, String::Box(value));
271 auto boxedObject = DistributedWantParamWrapper::Box(std::move(wantParams));
272 if (boxedObject == nullptr) {
273 return false;
274 }
275 return true;
276 }
277
DistributedWantParamWrapperGerTypedIdFuzzTest(const uint8_t * data,size_t size)278 bool DistributedWantParamWrapperGerTypedIdFuzzTest(const uint8_t* data, size_t size)
279 {
280 if (data == nullptr || size == 0) {
281 return false;
282 }
283 FuzzedDataProvider fdp(data, size);
284 std::string inputStr = fdp.ConsumeRandomLengthString();
285
286 size_t startPos = 0;
287
288 DistributedWantParams wantOther;
289 std::shared_ptr<DistributedWantParams> wantParams = std::make_shared<DistributedWantParams>(wantOther);
290 DistributedWantParamWrapper wrapper(*wantParams);
291 int typeId = wrapper.GerTypedId(inputStr, startPos);
292
293 return typeId >= 0;
294 }
295
DistributedWantParamQueryFuzzTest(const uint8_t * data,size_t size)296 void DistributedWantParamQueryFuzzTest(const uint8_t* data, size_t size)
297 {
298 if (data == nullptr || size == 0) {
299 return;
300 }
301 size_t testSize = (size < MAX_TEST_STRING_LEN) ? size : MAX_TEST_STRING_LEN;
302 std::string testStr(reinterpret_cast<const char*>(data), testSize);
303 sptr<AAFwk::IInterface> iIt = String::Box(testStr);
304
305 DistributedWantParams::ArrayQueryToStr(iIt);
306 DistributedWantParams::DistributedWantParamsQueryToStr(iIt);
307 DistributedWantParams::BooleanQueryEquals(iIt);
308 DistributedWantParams::ByteQueryEquals(iIt);
309 DistributedWantParams::CharQueryEquals(iIt);
310 DistributedWantParams::ArrayQueryEquals(iIt);
311 DistributedWantParams::DistributedWantParamsQueryEquals(iIt);
312 DistributedWantParams::ShortQueryEquals(iIt);
313 DistributedWantParams::IntegerQueryEquals(iIt);
314 DistributedWantParams::LongQueryEquals(iIt);
315 DistributedWantParams::FloatQueryEquals(iIt);
316 DistributedWantParams::DoubleQueryEquals(iIt);
317 DistributedWantParams::GetNumberDataType(iIt);
318 DistributedWantParams::BooleanQueryToStr(iIt);
319 DistributedWantParams::ByteQueryToStr(iIt);
320 DistributedWantParams::CharQueryToStr(iIt);
321 DistributedWantParams::ShortQueryToStr(iIt);
322 DistributedWantParams::IntegerQueryToStr(iIt);
323 DistributedWantParams::LongQueryToStr(iIt);
324 DistributedWantParams::FloatQueryToStr(iIt);
325 DistributedWantParams::DoubleQueryToStr(iIt);
326 }
327
DistributedUnsupportedDataCopyAssignFuzzTest(const uint8_t * data,size_t size)328 void DistributedUnsupportedDataCopyAssignFuzzTest(const uint8_t* data, size_t size)
329 {
330 if (data == nullptr || size < U32_AT_SIZE) {
331 return;
332 }
333 FuzzedDataProvider fdp(data, size);
334
335 DistributedUnsupportedData lhs;
336 DistributedUnsupportedData rhs;
337
338 std::string keyStr = fdp.ConsumeRandomLengthString();
339 rhs.key = std::u16string(keyStr.begin(), keyStr.end());
340 rhs.type = fdp.ConsumeIntegral<int>();
341 rhs.size = fdp.ConsumeIntegralInRange<int>(POS_1, FOO_MAX_LEN);
342 rhs.buffer = new uint8_t[rhs.size];
343 std::vector<uint8_t> buf = fdp.ConsumeBytes<uint8_t>(rhs.size);
344 if (memcpy_s(rhs.buffer, rhs.size, buf.data(), buf.size()) != 0) {
345 delete[] rhs.buffer;
346 rhs.buffer = nullptr;
347 return;
348 }
349
350 lhs = rhs;
351 }
352
DistributedUnsupportedDataMoveAssignFuzzTest(const uint8_t * data,size_t size)353 void DistributedUnsupportedDataMoveAssignFuzzTest(const uint8_t* data, size_t size)
354 {
355 if (data == nullptr || size < U32_AT_SIZE) {
356 return;
357 }
358 FuzzedDataProvider fdp(data, size);
359
360 DistributedUnsupportedData lhs;
361 DistributedUnsupportedData rhs;
362
363 std::string keyStr = fdp.ConsumeRandomLengthString();
364 rhs.key = std::u16string(keyStr.begin(), keyStr.end());
365 rhs.type = fdp.ConsumeIntegral<int>();
366 rhs.size = fdp.ConsumeIntegralInRange<int>(POS_1, FOO_MAX_LEN);
367 rhs.buffer = new uint8_t[rhs.size];
368 std::vector<uint8_t> buf = fdp.ConsumeBytes<uint8_t>(rhs.size);
369 if (memcpy_s(rhs.buffer, rhs.size, buf.data(), buf.size()) != 0) {
370 delete[] rhs.buffer;
371 rhs.buffer = nullptr;
372 return;
373 }
374
375 lhs = std::move(rhs);
376 }
377
378 }
379
380 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)381 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
382 {
383 OHOS::DoSomethingInterestingWithMyApiDistributedWantParams001(data, size);
384 OHOS::DoSomethingInterestingWithMyApiDistributedWantParams002(data, size);
385 OHOS::DoSomethingInterestingWithMyApiDistributedWant003(data, size);
386 OHOS::DoSomethingInterestingWithMyApiDistributedWantParams004(data, size);
387 OHOS::DistributedWantParamWrapperEqualsFuzzTest(data, size);
388 OHOS::DistributedWantParamWrapperFindMatchingBraceFuzzTest(data, size);
389 OHOS::DistributedWantParamWrapperBoxFuzzTest(data, size);
390 OHOS::DistributedWantParamWrapperGerTypedIdFuzzTest(data, size);
391 OHOS::DistributedWantParamQueryFuzzTest(data, size);
392 OHOS::DistributedUnsupportedDataCopyAssignFuzzTest(data, size);
393 OHOS::DistributedUnsupportedDataMoveAssignFuzzTest(data, size);
394 return 0;
395 }
396