1 /*
2 * Copyright (c) 2023 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 "parcel_fuzzer.h"
17
18 #include "fuzz_log.h"
19 #include "fuzzer/FuzzedDataProvider.h"
20 #include "parcel.h"
21 #include "securec.h"
22 #include "string_ex.h"
23
24 using namespace std;
25
26 namespace OHOS {
27 const uint8_t MAX_BUFFER_SIZE = 255;
28 const uint8_t MAX_STRING_LENGTH = 255;
29 const uint8_t MAX_VECTOR_SIZE = 10;
30 const int MAX_OPERATIONS_GENERAL = 500;
31 const int MAX_OPERATIONS_UNALIGNED = 100;
32 const int MAX_OPERATIONS_OTHER = 15;
33
34 enum Group {
35 GENERAL_GROUP = 0,
36 UNALIGNED_GROUP = 1,
37 OTHER_GROUP = 2,
38 };
39
40 #define PARCEL_NO_INPUT_WITH_RETURN(T, FUN) \
41 [](FuzzedDataProvider*, Parcel& p) { \
42 FUZZ_LOGI("%{public}s", #FUN); \
43 T t = p.FUN(); \
44 (void)t; \
45 }
46
47 #define PARCEL_INT_INPUT_WITH_BOOL_RETURN(T, FUN) \
48 [](FuzzedDataProvider* d, Parcel& p) { \
49 FUZZ_LOGI("%{public}s", #FUN); \
50 T data = d->ConsumeIntegral<T>(); \
51 bool t = p.FUN(data); \
52 (void)t; \
53 }
54
55 #define PARCEL_REF_INPUT_WITH_BOOL_RETURN(T, FUN) \
56 [](FuzzedDataProvider*, Parcel& p) { \
57 FUZZ_LOGI("%{public}s", #FUN); \
58 T out {}; \
59 bool t = p.FUN(out); \
60 (void)t; \
61 }
62
63 #define PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(T, FUN) \
64 [](FuzzedDataProvider* d, Parcel& p) { \
65 FUZZ_LOGI("%{public}s", #FUN); \
66 size_t n = d->ConsumeIntegralInRange<size_t>(1, MAX_VECTOR_SIZE); \
67 void* buf = malloc(n * sizeof(T)); \
68 size_t wb = d->ConsumeData(buf, n * sizeof(T)); \
69 auto* tmp = static_cast<const T*>(buf); \
70 std::vector<T> data(tmp, tmp + wb / sizeof(T)); \
71 bool t = p.FUN(data); \
72 (void)t; \
73 free(buf); \
74 }
75
76 #define PARCEL_POINT_INPUT_WITH_BOOL_RETURN(T, FUN) \
77 [](FuzzedDataProvider*, Parcel& p) { \
78 FUZZ_LOGI("%{public}s", #FUN); \
79 vector<T> out; \
80 bool t = p.FUN(&out); \
81 (void)t; \
82 }
83
84 class TestParcelable : public virtual Parcelable {
85 public:
86 TestParcelable() = default;
TestParcelable(bool asRemote)87 explicit TestParcelable(bool asRemote)
88 {
89 asRemote_ = asRemote;
90 };
91 ~TestParcelable() = default;
92
93 bool Marshalling(Parcel& parcel) const override;
94 static TestParcelable* Unmarshalling(Parcel& parcel);
95 static bool Marshalling(Parcel& parcel, const sptr<TestParcelable>& object);
96
97 public:
98 int32_t int32Write_ = -0x12345678;
99 int32_t int32Read_;
100 };
101
Marshalling(Parcel & parcel) const102 bool TestParcelable::Marshalling(Parcel& parcel) const
103 {
104 bool result = parcel.WriteInt32(this->int32Write_);
105 return result;
106 }
107
Unmarshalling(Parcel & parcel)108 TestParcelable* TestParcelable::Unmarshalling(Parcel& parcel)
109 {
110 auto* read = new TestParcelable();
111 read->int32Read_ = parcel.ReadInt32();
112 return read;
113 }
114
Marshalling(Parcel & parcel,const sptr<TestParcelable> & object)115 bool TestParcelable::Marshalling(Parcel& parcel, const sptr<TestParcelable>& object)
116 {
117 bool result = parcel.WriteInt32(object->int32Write_);
118 return result;
119 }
120
121 class RemoteObject : public virtual Parcelable {
122 public:
RemoteObject()123 RemoteObject()
124 {
125 asRemote_ = true;
126 };
127 bool Marshalling(Parcel& parcel) const override;
128 static sptr<RemoteObject> Unmarshalling(Parcel& parcel);
129 };
130
Marshalling(Parcel & parcel) const131 bool RemoteObject::Marshalling(Parcel& parcel) const
132 {
133 parcel_flat_binder_object flat;
134 flat.hdr.type = 0xff;
135 flat.flags = 0x7f;
136 flat.binder = 0;
137 flat.handle = (uint32_t)(-1);
138 flat.cookie = reinterpret_cast<uintptr_t>(this);
139 bool status = parcel.WriteBuffer(&flat, sizeof(parcel_flat_binder_object));
140 if (!status) {
141 return false;
142 }
143 return true;
144 }
145
Unmarshalling(Parcel & parcel)146 sptr<RemoteObject> RemoteObject::Unmarshalling(Parcel& parcel)
147 {
148 const uint8_t* buffer = parcel.ReadBuffer(sizeof(parcel_flat_binder_object), false);
149 if (buffer == nullptr) {
150 return nullptr;
151 }
152 sptr<RemoteObject> obj = new RemoteObject();
153 return obj;
154 }
155
156 const std::vector<std::function<void(FuzzedDataProvider*, Parcel&)>> operations = {
157 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetDataSize),
158 PARCEL_NO_INPUT_WITH_RETURN(uintptr_t, GetData),
159 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetOffsetsSize),
160 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetWritableBytes),
161 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetReadableBytes),
162 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetDataCapacity),
163 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetMaxCapacity),
164
__anon90ce765f0102() 165 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
166 FUZZ_LOGI("WriteBool");
167 bool booltest = dataProvider->ConsumeBool();
168 parcel.WriteBool(booltest);
169 },
170
171 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int8_t, WriteInt8),
172 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int16_t, WriteInt16),
173 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int32_t, WriteInt32),
174 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int64_t, WriteInt64),
175 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint8_t, WriteUint8),
176 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint16_t, WriteUint16),
177 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint32_t, WriteUint32),
178 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint64_t, WriteUint64),
179 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uintptr_t, WritePointer),
180
__anon90ce765f0202() 181 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
182 FUZZ_LOGI("WriteFloat");
183 float floattest = dataProvider->ConsumeFloatingPoint<float>();
184 parcel.WriteFloat(floattest);
185 },
186
__anon90ce765f0302() 187 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
188 FUZZ_LOGI("WriteDouble");
189 double doubletest = dataProvider->ConsumeFloatingPoint<double>();
190 parcel.WriteDouble(doubletest);
191 },
192
__anon90ce765f0402() 193 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
194 FUZZ_LOGI("WriteBuffer");
195 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
196 void* buffer = malloc(bufferSize);
197 size_t writtenBytes = dataProvider->ConsumeData(buffer, bufferSize);
198 parcel.WriteBuffer(buffer, writtenBytes);
199 free(buffer);
200 },
201
__anon90ce765f0502() 202 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
203 FUZZ_LOGI("WriteBufferAddTerminator");
204 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
205 void* buffer = malloc(bufferSize);
206 size_t writtenBytes = dataProvider->ConsumeData(buffer, bufferSize);
207 const size_t maxTypeSize = 4; // max type size is 4 bytes.
208 if (writtenBytes == 0) {
209 free(buffer);
210 return;
211 }
212 size_t typeSize = dataProvider->ConsumeIntegralInRange<size_t>(0, maxTypeSize);
213 parcel.WriteBufferAddTerminator(buffer, writtenBytes, typeSize);
214 free(buffer);
215 },
216
__anon90ce765f0602() 217 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
218 FUZZ_LOGI("WriteUnpadBuffer");
219 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
220 void* buffer = malloc(bufferSize);
221 size_t writtenBytes = dataProvider->ConsumeData(buffer, bufferSize);
222 parcel.WriteUnpadBuffer(buffer, writtenBytes);
223 free(buffer);
224 },
225
__anon90ce765f0702() 226 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
227 FUZZ_LOGI("WriteCString");
228 string teststr = dataProvider->ConsumeRandomLengthString(MAX_STRING_LENGTH);
229 parcel.WriteCString(teststr.c_str());
230 },
231
__anon90ce765f0802() 232 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
233 FUZZ_LOGI("WriteString");
234 string teststr = dataProvider->ConsumeRandomLengthString(MAX_STRING_LENGTH);
235 parcel.WriteString(teststr);
236 },
237
__anon90ce765f0902() 238 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
239 FUZZ_LOGI("WriteString16");
240 string utf8 = dataProvider->ConsumeRandomLengthString(MAX_STRING_LENGTH);
241 u16string utf16 = Str8ToStr16(utf8);
242 parcel.WriteString16(utf16);
243 },
244
__anon90ce765f0a02() 245 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
246 FUZZ_LOGI("WriteString16WithLength");
247 string utf8 = dataProvider->ConsumeRandomLengthString(MAX_STRING_LENGTH);
248 u16string utf16 = Str8ToStr16(utf8);
249 char16_t* value = utf16.data();
250 parcel.WriteString16WithLength(value, utf16.length());
251 },
252
__anon90ce765f0b02() 253 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
254 FUZZ_LOGI("WriteString8WithLength");
255 string utf8 = dataProvider->ConsumeRandomLengthString(MAX_STRING_LENGTH);
256 char* value = utf8.data();
257 parcel.WriteString8WithLength(value, utf8.length());
258 },
259
__anon90ce765f0c02() 260 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
261 FUZZ_LOGI("WriteParcelable");
262 bool remoteFlag = dataProvider->ConsumeBool();
263 TestParcelable parcelableWrite(remoteFlag);
264 parcel.WriteParcelable(&parcelableWrite);
265 },
266
__anon90ce765f0d02() 267 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
268 FUZZ_LOGI("WriteStrongParcelable");
269 bool remoteFlag = dataProvider->ConsumeBool();
270 sptr<TestParcelable> parcelableWrite = new TestParcelable(remoteFlag);
271 parcel.WriteStrongParcelable(parcelableWrite);
272 },
273
__anon90ce765f0e02() 274 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
275 FUZZ_LOGI("WriteRemoteObject");
276 RemoteObject obj;
277 parcel.WriteRemoteObject(&obj);
278 },
279
__anon90ce765f0f02() 280 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
281 FUZZ_LOGI("WriteObject");
282 bool remoteFlag = dataProvider->ConsumeBool();
283 sptr<TestParcelable> parcelableWrite = new TestParcelable(remoteFlag);
284 parcel.WriteObject(parcelableWrite);
285 },
286
__anon90ce765f1002() 287 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
288 FUZZ_LOGI("ParseFrom");
289 void* buffer = nullptr;
290 size_t testdataSize = parcel.GetDataSize();
291 if (testdataSize > 0) {
292 buffer = malloc(testdataSize);
293 memcpy_s(buffer, testdataSize, reinterpret_cast<const uint8_t*>(parcel.GetData()), testdataSize);
294 }
295 Parcel parcel2(nullptr);
296 parcel2.ParseFrom(reinterpret_cast<uintptr_t>(buffer), testdataSize);
297 },
298
299 PARCEL_NO_INPUT_WITH_RETURN(bool, ReadBool),
300 PARCEL_NO_INPUT_WITH_RETURN(int8_t, ReadInt8),
301 PARCEL_NO_INPUT_WITH_RETURN(int16_t, ReadInt16),
302 PARCEL_NO_INPUT_WITH_RETURN(int32_t, ReadInt32),
303 PARCEL_NO_INPUT_WITH_RETURN(int64_t, ReadInt64),
304 PARCEL_NO_INPUT_WITH_RETURN(uint8_t, ReadUint8),
305 PARCEL_NO_INPUT_WITH_RETURN(uint16_t, ReadUint16),
306 PARCEL_NO_INPUT_WITH_RETURN(uint32_t, ReadUint32),
307 PARCEL_NO_INPUT_WITH_RETURN(uint64_t, ReadUint64),
308 PARCEL_NO_INPUT_WITH_RETURN(float, ReadFloat),
309 PARCEL_NO_INPUT_WITH_RETURN(double, ReadDouble),
310 PARCEL_NO_INPUT_WITH_RETURN(uintptr_t, ReadPointer),
311
312 PARCEL_REF_INPUT_WITH_BOOL_RETURN(bool, ReadBool),
313 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int8_t, ReadInt8),
314 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int16_t, ReadInt16),
315 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int32_t, ReadInt32),
316 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int64_t, ReadInt64),
317 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint8_t, ReadUint8),
318 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint16_t, ReadUint16),
319 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint32_t, ReadUint32),
320 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint64_t, ReadUint64),
321 PARCEL_REF_INPUT_WITH_BOOL_RETURN(float, ReadFloat),
322 PARCEL_REF_INPUT_WITH_BOOL_RETURN(double, ReadDouble),
323
__anon90ce765f1102() 324 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
325 FUZZ_LOGI("ReadUnpadBuffer");
326 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
327 parcel.ReadUnpadBuffer(bufferSize);
328 },
329
330 PARCEL_NO_INPUT_WITH_RETURN(const char*, ReadCString),
331 PARCEL_NO_INPUT_WITH_RETURN(string, ReadString),
332 PARCEL_REF_INPUT_WITH_BOOL_RETURN(string, ReadString),
333 PARCEL_NO_INPUT_WITH_RETURN(u16string, ReadString16),
334 PARCEL_REF_INPUT_WITH_BOOL_RETURN(u16string, ReadString16),
335
__anon90ce765f1202() 336 [](FuzzedDataProvider*, Parcel& parcel) {
337 FUZZ_LOGI("ReadString16WithLength");
338 int32_t strlen = 0;
339 parcel.ReadString16WithLength(strlen);
340 },
341
__anon90ce765f1302() 342 [](FuzzedDataProvider*, Parcel& parcel) {
343 FUZZ_LOGI("ReadString8WithLength");
344 int32_t strlen = 0;
345 parcel.ReadString8WithLength(strlen);
346 },
347
348 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetReadPosition),
349 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetWritePosition),
350
351 PARCEL_NO_INPUT_WITH_RETURN(sptr<TestParcelable>, ReadParcelable<TestParcelable>),
352 PARCEL_NO_INPUT_WITH_RETURN(sptr<TestParcelable>, ReadStrongParcelable<TestParcelable>),
353 PARCEL_NO_INPUT_WITH_RETURN(bool, CheckOffsets),
354 PARCEL_NO_INPUT_WITH_RETURN(sptr<TestParcelable>, ReadObject<TestParcelable>),
355
__anon90ce765f1402() 356 [](FuzzedDataProvider*, Parcel& parcel) {
357 FUZZ_LOGI("SetAllocator");
358 parcel.SetAllocator(new DefaultAllocator());
359 },
360
__anon90ce765f1502() 361 [](FuzzedDataProvider*, Parcel& parcel) {
362 FUZZ_LOGI("InjectOffsets");
363 Parcel parcel2(nullptr);
364 parcel2.InjectOffsets(parcel.GetObjectOffsets(), parcel.GetOffsetsSize());
365 },
366
__anon90ce765f1602() 367 [](FuzzedDataProvider*, Parcel& parcel) {
368 FUZZ_LOGI("FlushBuffer");
369 parcel.FlushBuffer();
370 },
371
372 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(int8_t, WriteInt8Vector),
373 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(int32_t, WriteInt32Vector),
374 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(int64_t, WriteInt64Vector),
375 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(uint8_t, WriteUInt8Vector),
376 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(uint16_t, WriteUInt16Vector),
377 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(uint32_t, WriteUInt32Vector),
378 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(uint64_t, WriteUInt64Vector),
379 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(float, WriteFloatVector),
380 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(double, WriteDoubleVector),
381
__anon90ce765f1702() 382 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
383 FUZZ_LOGI("WriteStringVector");
384 size_t vectorSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_VECTOR_SIZE);
385 std::vector<string> testdata(vectorSize);
386 for (size_t i = 0; i < vectorSize; i++) {
387 size_t strlen = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_STRING_LENGTH);
388 std::vector<char> vec = dataProvider->ConsumeBytesWithTerminator<char>(strlen);
389 testdata[i] = vec.data();
390 }
391 parcel.WriteStringVector(testdata);
392 },
393
__anon90ce765f1802() 394 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
395 FUZZ_LOGI("WriteString16Vector");
396 size_t vectorSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_VECTOR_SIZE);
397 std::vector<u16string> testdata(vectorSize);
398 for (size_t i = 0; i < vectorSize; i++) {
399 size_t strlen = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_STRING_LENGTH);
400 std::vector<char> vec = dataProvider->ConsumeBytesWithTerminator<char>(strlen);
401 string str = vec.data();
402 testdata[i] = Str8ToStr16(str);
403 }
404 parcel.WriteString16Vector(testdata);
405 },
406
407 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(int32_t, ReadInt32Vector),
408 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(int64_t, ReadInt64Vector),
409 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(uint32_t, ReadUInt32Vector),
410 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(uint64_t, ReadUInt64Vector),
411 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(float, ReadFloatVector),
412 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(double, ReadDoubleVector),
413 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(string, ReadStringVector),
414 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(u16string, ReadString16Vector),
415 };
416
417 const std::vector<std::function<void(FuzzedDataProvider*, Parcel&)>> unaligned_operations = {
418 // error call ReadDouble after following methods, will crash with "signal SIGBUS: illegal alignment".
__anon90ce765f1902() 419 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
420 FUZZ_LOGI("ReadBuffer");
421 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
422 parcel.ReadBuffer(bufferSize);
423 },
424
__anon90ce765f1a02() 425 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
426 FUZZ_LOGI("SkipBytes");
427 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
428 parcel.SkipBytes(bufferSize);
429 },
430
__anon90ce765f1b02() 431 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
432 FUZZ_LOGI("RewindRead");
433 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
434 parcel.RewindRead(bufferSize);
435 },
436
437 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(bool, ReadBoolVector),
438 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(int8_t, ReadInt8Vector),
439 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(int16_t, ReadInt16Vector),
440 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(uint8_t, ReadUInt8Vector),
441 PARCEL_POINT_INPUT_WITH_BOOL_RETURN(uint16_t, ReadUInt16Vector),
442
443 PARCEL_NO_INPUT_WITH_RETURN(bool, ReadBoolUnaligned),
444 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int8_t, ReadInt8Unaligned),
445 PARCEL_REF_INPUT_WITH_BOOL_RETURN(int16_t, ReadInt16Unaligned),
446 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint8_t, ReadUint8Unaligned),
447 PARCEL_REF_INPUT_WITH_BOOL_RETURN(uint16_t, ReadUint16Unaligned),
448
449 // error call WriteDouble/WriteFloat after RewindWrite, will crash with "signal SIGBUS: illegal alignment".
__anon90ce765f1c02() 450 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
451 FUZZ_LOGI("RewindWrite");
452 size_t bufferSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
453 parcel.RewindWrite(bufferSize);
454 },
__anon90ce765f1d02() 455 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
456 FUZZ_LOGI("WriteBoolVector");
457 size_t vectorSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_VECTOR_SIZE);
458 std::vector<uint8_t> data = dataProvider->ConsumeBytes<uint8_t>(vectorSize);
459 if (data.size() > 0) {
460 std::vector<bool> testdata(data.size());
461 for (size_t i = 0; i < testdata.size(); i++) {
462 testdata[i] = 1 & data[i];
463 }
464 parcel.WriteBoolVector(testdata);
465 }
466 },
467
468 PARCEL_WRITE_VECTOR_WITH_BOOL_RETURN(int16_t, WriteInt16Vector),
469
__anon90ce765f1e02() 470 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
471 FUZZ_LOGI("WriteBoolUnaligned");
472 bool booltest = dataProvider->ConsumeBool();
473 parcel.WriteBoolUnaligned(booltest);
474 },
475
476 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int8_t, WriteInt8Unaligned),
477 PARCEL_INT_INPUT_WITH_BOOL_RETURN(int16_t, WriteInt16Unaligned),
478 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint8_t, WriteUint8Unaligned),
479 PARCEL_INT_INPUT_WITH_BOOL_RETURN(uint16_t, WriteUint16Unaligned),
480 };
481
482 const std::vector<std::function<void(FuzzedDataProvider*, Parcel&)>> other_operations = {
483 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetDataSize),
484 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetDataCapacity),
485 PARCEL_NO_INPUT_WITH_RETURN(size_t, GetMaxCapacity),
486
487 // cannot call randomly with other operations.
__anon90ce765f1f02() 488 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
489 FUZZ_LOGI("SetDataCapacity");
490 size_t capacity = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
491 parcel.SetDataCapacity(capacity);
492 },
493
__anon90ce765f2002() 494 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
495 FUZZ_LOGI("SetDataSize");
496 size_t dataSize = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
497 parcel.SetDataSize(dataSize);
498 },
499
__anon90ce765f2102() 500 [](FuzzedDataProvider* dataProvider, Parcel& parcel) {
501 FUZZ_LOGI("SetMaxCapacity");
502 size_t maxCapacity = dataProvider->ConsumeIntegralInRange<size_t>(1, MAX_BUFFER_SIZE);
503 parcel.SetMaxCapacity(maxCapacity);
504 },
505 };
506
ParcelTestFunc(const uint8_t * data,size_t size,FuzzedDataProvider * dataProvider)507 void ParcelTestFunc(const uint8_t* data, size_t size, FuzzedDataProvider* dataProvider)
508 {
509 FUZZ_LOGI("ParcelTestFunc start");
510 uint8_t opSet = dataProvider->ConsumeIntegralInRange<uint8_t>(GENERAL_GROUP, OTHER_GROUP);
511 uint8_t maxGeneral = operations.size() - 1;
512 uint8_t maxUnaligned = unaligned_operations.size() - 1;
513 uint8_t maxOther = other_operations.size() - 1;
514 Parcel parcel1(nullptr);
515 int opCnt = 0;
516
517 switch (opSet) {
518 case GENERAL_GROUP:
519 while (dataProvider->remaining_bytes() > 0 && opCnt++ < MAX_OPERATIONS_GENERAL) {
520 uint8_t op = dataProvider->ConsumeIntegralInRange<uint8_t>(0, maxGeneral);
521 operations[op](dataProvider, parcel1);
522 }
523 break;
524 case UNALIGNED_GROUP:
525 while (dataProvider->remaining_bytes() > 0 && opCnt++ < MAX_OPERATIONS_UNALIGNED) {
526 uint8_t op = dataProvider->ConsumeIntegralInRange<uint8_t>(0, maxUnaligned);
527 unaligned_operations[op](dataProvider, parcel1);
528 }
529 break;
530 case OTHER_GROUP:
531 while (dataProvider->remaining_bytes() > 0 && opCnt++ < MAX_OPERATIONS_OTHER) {
532 uint8_t op = dataProvider->ConsumeIntegralInRange<uint8_t>(0, maxOther);
533 other_operations[op](dataProvider, parcel1);
534 }
535 break;
536 default:
537 break;
538 }
539 FUZZ_LOGI("ParcelTestFunc end");
540 }
541
542 } // namespace OHOS
543
544 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)545 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
546 {
547 FuzzedDataProvider dataProvider(data, size);
548 OHOS::ParcelTestFunc(data, size, &dataProvider);
549 return 0;
550 }
551