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 <algorithm>
17 #include <cstddef>
18 #include <cstdint>
19 #include <iostream>
20 #include <fuzzer/FuzzedDataProvider.h>
21
22 #include "wantparamsfifth_fuzzer.h"
23
24 #define private public
25 #include "want_params.h"
26 #undef private
27 #include "array_wrapper.h"
28 #include "base_interfaces.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 "remote_object_wrapper.h"
36 #include "securec.h"
37 #include "short_wrapper.h"
38 #include "string_wrapper.h"
39 #include "want_params_wrapper.h"
40 #include "zchar_wrapper.h"
41
42 using namespace OHOS::AAFwk;
43
44 namespace OHOS {
45 namespace {
46 constexpr size_t U32_AT_SIZE = 4;
47 constexpr size_t PARAMS_SIZE = 21;
48 constexpr int32_t OTHER = -2;
49 constexpr int32_t ARRAY_SIZE = 5;
50 constexpr size_t FOO_MAX_LEN = 1024;
51 } // namespace
52
GetU32Data(const char * ptr)53 uint32_t GetU32Data(const char* ptr)
54 {
55 // convert fuzz input data to an integer
56 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
57 }
58
59 template <typename T>
GetData(const char * ptr,size_t size)60 typename std::enable_if<std::is_arithmetic<T>::value, T>::type GetData(const char* ptr, size_t size)
61 {
62 if (ptr == nullptr || size > OHOS::FOO_MAX_LEN || size < sizeof(T)) {
63 return static_cast<T>(0);
64 }
65
66 T result = 0;
67 if (memcpy_s(&result, sizeof(T), ptr, std::min(sizeof(T), size)) != 0) {
68 std::cout << "copy failed." << std::endl;
69 return static_cast<T>(0);
70 }
71 return result;
72 }
73
WriteBasicTypesToParcel(Parcel & parcel,const char * data,size_t size,const uint8_t * rowData)74 void WriteBasicTypesToParcel(Parcel& parcel, const char* data, size_t size, const uint8_t* rowData)
75 {
76 FuzzedDataProvider fdp(rowData, size);
77 std::string stringValue = fdp.ConsumeRandomLengthString();
78 bool boolValue = fdp.ConsumeBool();
79 int8_t byteValue = fdp.ConsumeIntegral<int8_t>();
80 char charValue = fdp.ConsumeIntegral<char>();
81 int16_t shortValue = fdp.ConsumeIntegral<int16_t>();
82 int32_t intValue = fdp.ConsumeIntegral<int32_t>();
83 long longValue = fdp.ConsumeIntegral<long>();
84 float floatValue = fdp.ConsumeFloatingPoint<float>();
85 double doubleValue = fdp.ConsumeFloatingPoint<double>();
86
87 parcel.WriteInt32(PARAMS_SIZE);
88 parcel.WriteString16(Str8ToStr16("booleanKey"));
89 parcel.WriteInt32(WantParams::VALUE_TYPE_BOOLEAN);
90 parcel.WriteBool(boolValue);
91 parcel.WriteString16(Str8ToStr16("byteKey"));
92 parcel.WriteInt32(WantParams::VALUE_TYPE_BYTE);
93 parcel.WriteInt8(byteValue);
94 parcel.WriteString16(Str8ToStr16("charKey"));
95 parcel.WriteInt32(WantParams::VALUE_TYPE_CHAR);
96 parcel.WriteInt32(charValue);
97 parcel.WriteString16(Str8ToStr16("shortKey"));
98 parcel.WriteInt32(WantParams::VALUE_TYPE_SHORT);
99 parcel.WriteInt16(shortValue);
100 parcel.WriteString16(Str8ToStr16("intKey"));
101 parcel.WriteInt32(WantParams::VALUE_TYPE_INT);
102 parcel.WriteInt32(intValue);
103 parcel.WriteString16(Str8ToStr16("longKey"));
104 parcel.WriteInt32(WantParams::VALUE_TYPE_LONG);
105 parcel.WriteInt64(longValue);
106 parcel.WriteString16(Str8ToStr16("floatKey"));
107 parcel.WriteInt32(WantParams::VALUE_TYPE_FLOAT);
108 parcel.WriteFloat(floatValue);
109 parcel.WriteString16(Str8ToStr16("doubleKey"));
110 parcel.WriteInt32(WantParams::VALUE_TYPE_DOUBLE);
111 parcel.WriteDouble(doubleValue);
112 parcel.WriteString16(Str8ToStr16("stringKey"));
113 parcel.WriteInt32(WantParams::VALUE_TYPE_STRING);
114 parcel.WriteString16(Str8ToStr16(stringValue));
115 }
116
WriteArrayToParcel(Parcel & parcel,const std::string & key,int32_t type,sptr<IArray> array,std::shared_ptr<WantParams> wantParams)117 void WriteArrayToParcel(
118 Parcel& parcel, const std::string& key, int32_t type, sptr<IArray> array, std::shared_ptr<WantParams> wantParams)
119 {
120 parcel.WriteString16(Str8ToStr16(key));
121 parcel.WriteInt32(type);
122 wantParams->WriteArrayToParcel(parcel, array, 0);
123 }
124
WriteArraysToParcel(Parcel & parcel,const char * data,size_t size,std::shared_ptr<WantParams> wantParams,const uint8_t * rowData)125 void WriteArraysToParcel(
126 Parcel& parcel, const char* data, size_t size, std::shared_ptr<WantParams> wantParams, const uint8_t* rowData)
127 {
128 FuzzedDataProvider fdp(rowData, size);
129 std::string stringValue = fdp.ConsumeRandomLengthString();
130 sptr<IArray> booleanArray = new Array(ARRAY_SIZE, g_IID_IBoolean);
131 sptr<IArray> charArray = new Array(ARRAY_SIZE, g_IID_IChar);
132 sptr<IArray> byteArray = new Array(ARRAY_SIZE, g_IID_IByte);
133 sptr<IArray> shortArray = new Array(ARRAY_SIZE, g_IID_IShort);
134 sptr<IArray> integerArray = new Array(ARRAY_SIZE, g_IID_IInteger);
135 sptr<IArray> longArray = new Array(ARRAY_SIZE, g_IID_ILong);
136 sptr<IArray> floatArray = new Array(ARRAY_SIZE, g_IID_IFloat);
137 sptr<IArray> doubleArray = new Array(ARRAY_SIZE, g_IID_IDouble);
138 sptr<IArray> stringArray = new Array(ARRAY_SIZE, g_IID_IString);
139 sptr<IArray> wantParamsArray = new Array(ARRAY_SIZE, g_IID_IWantParams);
140 sptr<IArray> other = new Array(ARRAY_SIZE, g_IID_IRemoteObjectWrap);
141 for (int32_t i = 0; i < ARRAY_SIZE; i++) {
142 bool boolValue = fdp.ConsumeBool();
143 int8_t byteValue = fdp.ConsumeIntegral<int8_t>();
144 char charValue = fdp.ConsumeIntegral<char>();
145 int16_t shortValue = fdp.ConsumeIntegral<int16_t>();
146 int32_t intValue = fdp.ConsumeIntegral<int32_t>();
147 long longValue = fdp.ConsumeIntegral<long>();
148 float floatValue = fdp.ConsumeFloatingPoint<float>();
149 double doubleValue = fdp.ConsumeFloatingPoint<double>();
150 booleanArray->Set(i, Boolean::Box(boolValue));
151 charArray->Set(i, Char::Box(charValue));
152 byteArray->Set(i, Byte::Box(byteValue));
153 shortArray->Set(i, Short::Box(shortValue));
154 integerArray->Set(i, Integer::Box(intValue));
155 longArray->Set(i, Long::Box(longValue));
156 floatArray->Set(i, Float::Box(floatValue));
157 doubleArray->Set(i, Double::Box(doubleValue));
158 stringArray->Set(i, String::Box(stringValue));
159 other->Set(i, RemoteObjectWrap::Box(nullptr));
160 }
161 WriteArrayToParcel(parcel, "stringArray", WantParams::VALUE_TYPE_STRINGARRAY, stringArray, wantParams);
162 WriteArrayToParcel(parcel, "booleanArray", WantParams::VALUE_TYPE_BOOLEANARRAY, booleanArray, wantParams);
163 WriteArrayToParcel(parcel, "byteArray", WantParams::VALUE_TYPE_BYTEARRAY, byteArray, wantParams);
164 WriteArrayToParcel(parcel, "charArray", WantParams::VALUE_TYPE_CHARARRAY, charArray, wantParams);
165 WriteArrayToParcel(parcel, "shortArray", WantParams::VALUE_TYPE_SHORTARRAY, shortArray, wantParams);
166 WriteArrayToParcel(parcel, "integerArray", WantParams::VALUE_TYPE_INTARRAY, integerArray, wantParams);
167 WriteArrayToParcel(parcel, "longArray", WantParams::VALUE_TYPE_LONGARRAY, longArray, wantParams);
168 WriteArrayToParcel(parcel, "floatArray", WantParams::VALUE_TYPE_FLOATARRAY, floatArray, wantParams);
169 WriteArrayToParcel(parcel, "doubleArray", WantParams::VALUE_TYPE_DOUBLEARRAY, doubleArray, wantParams);
170 WriteArrayToParcel(parcel, "wantParamsArray", WantParams::VALUE_TYPE_WANTPARAMSARRAY, wantParamsArray, wantParams);
171 WriteArrayToParcel(parcel, "other", OTHER, other, wantParams);
172 parcel.WriteInt32(WantParams::VALUE_TYPE_NULL);
173 }
174
DoSomethingInterestingWithMyAPI(const char * data,size_t size,const uint8_t * rowData)175 bool DoSomethingInterestingWithMyAPI(const char* data, size_t size, const uint8_t* rowData)
176 {
177 WantParams wantOther;
178 std::shared_ptr<WantParams> wantParams = std::make_shared<WantParams>(wantOther);
179
180 Parcel parcel;
181 WriteBasicTypesToParcel(parcel, data, size, rowData);
182 WriteArraysToParcel(parcel, data, size, wantParams, rowData);
183
184 auto wantPtr = wantParams->Unmarshalling(parcel, 0);
185 if (wantPtr) {
186 delete wantPtr;
187 wantPtr = nullptr;
188 }
189 return true;
190 }
191 } // namespace OHOS
192
193 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)194 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
195 {
196 /* Run your code on data */
197 if (data == nullptr) {
198 std::cout << "invalid data" << std::endl;
199 return 0;
200 }
201
202 /* Validate the length of size */
203 if (size < OHOS::U32_AT_SIZE) {
204 return 0;
205 }
206
207 char* ch = (char*)malloc(size + 1);
208 if (ch == nullptr) {
209 std::cout << "malloc failed." << std::endl;
210 return 0;
211 }
212
213 (void)memset_s(ch, size + 1, 0x00, size + 1);
214 if (memcpy_s(ch, size, data, size) != EOK) {
215 std::cout << "copy failed." << std::endl;
216 free(ch);
217 ch = nullptr;
218 return 0;
219 }
220
221 OHOS::DoSomethingInterestingWithMyAPI(ch, size, data);
222 free(ch);
223 ch = nullptr;
224 return 0;
225 }
226