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