• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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