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 "wantparamsfour_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <iostream>
21
22 #define private public
23 #include "want_params.h"
24 #undef private
25 #include "array_wrapper.h"
26 #include "base_interfaces.h"
27 #include "bool_wrapper.h"
28 #include "byte_wrapper.h"
29 #include "double_wrapper.h"
30 #include "float_wrapper.h"
31 #include "int_wrapper.h"
32 #include "long_wrapper.h"
33 #include "remote_object_wrapper.h"
34 #include "securec.h"
35 #include "short_wrapper.h"
36 #include "string_wrapper.h"
37 #include "want_params_wrapper.h"
38 #include "zchar_wrapper.h"
39
40 using namespace OHOS::AAFwk;
41
42 namespace OHOS {
43 namespace {
44 constexpr size_t U32_AT_SIZE = 4;
45 constexpr size_t BOOLEAN_TO_STRING = 10;
46 constexpr int32_t ARRAY_SIZE = 5;
47 }
48
GetU32Data(const char * ptr)49 uint32_t GetU32Data(const char* ptr)
50 {
51 // convert fuzz input data to an integer
52 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
53 }
54
DoCoverageUnsupportedDataAndWantParams()55 void DoCoverageUnsupportedDataAndWantParams()
56 {
57 std::vector<UnsupportedData> cachedUnsupportedData;
58 UnsupportedData data1;
59 cachedUnsupportedData.push_back(data1);
60 UnsupportedData data2(std::move(data1));
61 cachedUnsupportedData.push_back(data2);
62 UnsupportedData data3;
63 cachedUnsupportedData.push_back(data3);
64 UnsupportedData data4 = data3;
65 cachedUnsupportedData.push_back(data4);
66 data3 = data4;
67 data4 = std::move(data3);
68 WantParams wantOther;
69 std::shared_ptr<WantParams> wantParams = std::make_shared<WantParams>(std::move(wantOther));
70 wantParams->SetCachedUnsupportedData(cachedUnsupportedData);
71 wantParams->GetCachedUnsupportedData(cachedUnsupportedData);
72 }
73
ConvertBasicDataTypes(const char * data,size_t size,std::map<std::string,sptr<IInterface>> & params)74 void ConvertBasicDataTypes(const char* data, size_t size, std::map<std::string, sptr<IInterface>>& params)
75 {
76 std::string stringValue(data, size);
77 bool boolValue = static_cast<bool>(GetU32Data(data));
78 uint8_t byteValue = static_cast<uint8_t>(GetU32Data(data));
79 char charValue = static_cast<char>(GetU32Data(data));
80 int16_t shortValue = static_cast<int16_t>(GetU32Data(data));
81 int32_t intValue = static_cast<int32_t>(GetU32Data(data));
82 long longValue = static_cast<long>(GetU32Data(data));
83 float floatValue = static_cast<float>(GetU32Data(data));
84 double doubleValue = static_cast<double>(GetU32Data(data));
85
86 params["string"] = String::Box(stringValue);
87 params["boolean"] = Boolean::Box(boolValue);
88 params["byte"] = Byte::Box(byteValue);
89 params["char"] = Char::Box(charValue);
90 params["short"] = Short::Box(shortValue);
91 params["integer"] = Integer::Box(intValue);
92 params["long"] = Long::Box(longValue);
93 params["float"] = Float::Box(floatValue);
94 params["double"] = Double::Box(doubleValue);
95 }
96
CreateArrays(const char * data,size_t size,std::map<std::string,sptr<IInterface>> & params)97 void CreateArrays(const char* data, size_t size, std::map<std::string, sptr<IInterface>>& params)
98 {
99 sptr<IArray> booleanArray = new Array(ARRAY_SIZE, g_IID_IBoolean);
100 sptr<IArray> charArray = new Array(ARRAY_SIZE, g_IID_IChar);
101 sptr<IArray> byteArray = new Array(ARRAY_SIZE, g_IID_IByte);
102 sptr<IArray> shortArray = new Array(ARRAY_SIZE, g_IID_IShort);
103 sptr<IArray> integerArray = new Array(ARRAY_SIZE, g_IID_IInteger);
104 sptr<IArray> longArray = new Array(ARRAY_SIZE, g_IID_ILong);
105 sptr<IArray> floatArray = new Array(ARRAY_SIZE, g_IID_IFloat);
106 sptr<IArray> doubleArray = new Array(ARRAY_SIZE, g_IID_IDouble);
107 sptr<IArray> stringArray = new Array(ARRAY_SIZE, g_IID_IString);
108 sptr<IArray> wantParamsArray = new Array(ARRAY_SIZE, g_IID_IWantParams);
109 sptr<IArray> other = new Array(ARRAY_SIZE, g_IID_IRemoteObjectWrap);
110
111 std::string stringValue(data, size);
112 for (int32_t i = 0; i < ARRAY_SIZE; i++) {
113 booleanArray->Set(i, Boolean::Box(static_cast<bool>(GetU32Data(data))));
114 charArray->Set(i, Char::Box(static_cast<char>(GetU32Data(data))));
115 byteArray->Set(i, Byte::Box(static_cast<int8_t>(GetU32Data(data))));
116 shortArray->Set(i, Short::Box(static_cast<int16_t>(GetU32Data(data))));
117 integerArray->Set(i, Integer::Box(static_cast<int32_t>(GetU32Data(data))));
118 longArray->Set(i, Long::Box(static_cast<long>(GetU32Data(data))));
119 floatArray->Set(i, Float::Box(static_cast<float>(GetU32Data(data))));
120 doubleArray->Set(i, Double::Box(static_cast<double>(GetU32Data(data))));
121 stringArray->Set(i, String::Box(stringValue));
122 other->Set(i, RemoteObjectWrap::Box(nullptr));
123 }
124
125 params["booleanArray"] = booleanArray;
126 params["charArray"] = charArray;
127 params["byteArray"] = byteArray;
128 params["shortArray"] = shortArray;
129 params["integerArray"] = integerArray;
130 params["longArray"] = longArray;
131 params["floatArray"] = floatArray;
132 params["doubleArray"] = doubleArray;
133 params["stringArray"] = stringArray;
134 params["wantParamsArray"] = wantParamsArray;
135 params["other"] = other;
136 }
137
HandleWantParams(std::map<std::string,sptr<IInterface>> & params)138 void HandleWantParams(std::map<std::string, sptr<IInterface>>& params)
139 {
140 WantParams source;
141 source.params_ = params;
142 WantParams dest(source);
143 sptr<IArray> destNull = nullptr;
144 if (source == dest) {}
145 dest.NewArrayData(static_cast<IArray*>(params["booleanArray"].GetRefPtr()), destNull);
146
147 Parcel parcel;
148 UnsupportedData unsupportedData;
149 dest.cachedUnsupportedData_.push_back(unsupportedData);
150 dest.DoMarshalling(parcel, 0);
151
152 WantParams paramsClose(dest);
153 WantParams paramsRemove(dest);
154 WantParams paramsDup(dest);
155 paramsClose.CloseAllFd();
156 paramsRemove.RemoveAllFd();
157 paramsDup.DupAllFd();
158 }
159
DoCoverageNewArrayData(const char * data,size_t size)160 void DoCoverageNewArrayData(const char* data, size_t size)
161 {
162 std::map<std::string, sptr<IInterface>> params;
163 ConvertBasicDataTypes(data, size, params);
164 CreateArrays(data, size, params);
165 HandleWantParams(params);
166 }
167
DoCoverageGetInterfaceByType()168 void DoCoverageGetInterfaceByType()
169 {
170 std::string stringValue = std::to_string(BOOLEAN_TO_STRING);
171 WantParams params;
172 for (size_t i = 0; i < BOOLEAN_TO_STRING; i++) {
173 params.GetInterfaceByType(i, stringValue);
174 }
175 params.GetInterfaceByType(WantParams::VALUE_TYPE_ARRAY, stringValue);
176 }
177
DoCoverageWriteToParce(const char * data,size_t size)178 void DoCoverageWriteToParce(const char* data, size_t size)
179 {
180 Parcel parcel;
181 std::string stringValue(data, size);
182 bool boolValue = static_cast<bool>(GetU32Data(data));
183 int intValue = static_cast<int>(GetU32Data(data));
184 long longValue = static_cast<long>(GetU32Data(data));
185 sptr<IInterface> stringIt = String::Box(stringValue);
186 sptr<IInterface> boolIt = Boolean::Box(boolValue);
187 sptr<IInterface> intIt = Integer::Box(intValue);
188 sptr<IInterface> longIt = Long::Box(longValue);
189 WantParams params;
190 params.WriteToParcelString(parcel, stringIt);
191 params.WriteToParcelBool(parcel, boolIt);
192 params.WriteToParcelInt(parcel, intIt);
193 params.WriteToParcelLong(parcel, longIt);
194 }
195
DoSomethingInterestingWithMyAPI(const char * data,size_t size)196 bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
197 {
198 DoCoverageUnsupportedDataAndWantParams();
199 DoCoverageNewArrayData(data, size);
200 DoCoverageGetInterfaceByType();
201 DoCoverageWriteToParce(data, size);
202 return true;
203 }
204 }
205
206 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)207 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
208 {
209 /* Run your code on data */
210 if (data == nullptr) {
211 std::cout << "invalid data" << std::endl;
212 return 0;
213 }
214
215 /* Validate the length of size */
216 if (size < OHOS::U32_AT_SIZE) {
217 return 0;
218 }
219
220 char* ch = (char *)malloc(size + 1);
221 if (ch == nullptr) {
222 std::cout << "malloc failed." << std::endl;
223 return 0;
224 }
225
226 (void)memset_s(ch, size + 1, 0x00, size + 1);
227 if (memcpy_s(ch, size, data, size) != EOK) {
228 std::cout << "copy failed." << std::endl;
229 free(ch);
230 ch = nullptr;
231 return 0;
232 }
233
234 OHOS::DoSomethingInterestingWithMyAPI(ch, size);
235 free(ch);
236 ch = nullptr;
237 return 0;
238 }
239