1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include <hidl/HidlBinderSupport.h>
19 #include <libHidlBase_fuzzer_helper.h>
20
21 constexpr size_t kMinByte = 0;
22 constexpr size_t kMaxByte = 256;
23 constexpr uint32_t kNumFds = 0;
24 constexpr uint32_t kNumInts = 1;
25 constexpr uint32_t kMinSize = 1;
26 constexpr uint32_t kMaxSize = 1000;
27 constexpr uint32_t kMax = 1024;
28
29 class HidlBaseParcelFuzzer {
30 public:
HidlBaseParcelFuzzer(const uint8_t * data,size_t size)31 HidlBaseParcelFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
32 void process();
33
34 private:
35 void createRandomParcel(Parcel& parcel);
36
37 FuzzedDataProvider mFdp;
38 };
39
createRandomParcel(Parcel & parcel)40 void HidlBaseParcelFuzzer::createRandomParcel(Parcel& parcel) {
41 uint32_t iterCount = mFdp.ConsumeIntegralInRange<uint32_t>(kMin, kMax);
42 for (uint32_t idx = 0; idx < iterCount; ++idx) {
43 auto invokeHidlBaseParcelWriteAPI = mFdp.PickValueInArray<const std::function<void()>>({
44 [&]() {
45 hidl_memory memory;
46 native_handle_t* testNativeHandle = nullptr;
47 if (mFdp.ConsumeBool()) {
48 memory = createHidlMemory(mFdp);
49 } else {
50 hidl_string hidlString = createHidlString(mFdp);
51 testNativeHandle = native_handle_create(
52 mFdp.ConsumeIntegralInRange<uint32_t>(kMin, NATIVE_HANDLE_MAX_FDS),
53 mFdp.ConsumeIntegralInRange<uint32_t>(kMin,
54 NATIVE_HANDLE_MAX_INTS));
55 memory = hidl_memory(hidlString, testNativeHandle,
56 mFdp.ConsumeIntegral<uint64_t>());
57 }
58 writeEmbeddedToParcel(
59 memory, &parcel,
60 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
61 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
62 native_handle_close(testNativeHandle);
63 native_handle_delete(testNativeHandle);
64 },
65 [&]() {
66 MQDescriptorSync<uint8_t> descriptorSync;
67 auto testHandle = native_handle_create(kNumFds, kNumInts);
68 uint32_t size = sizeof(uint8_t);
69 testHandle->data[0] = size;
70 uint32_t bufferSize = mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize);
71 if (mFdp.ConsumeBool()) {
72 std::vector<GrantorDescriptor> grantDescriptor(bufferSize);
73 for (size_t idx = 0; idx < bufferSize; ++idx) {
74 grantDescriptor[idx] = {mFdp.ConsumeIntegral<uint32_t>() /* flags */,
75 mFdp.ConsumeIntegral<uint32_t>() /* fdIndex */,
76 mFdp.ConsumeIntegral<uint32_t>() /* offset */,
77 mFdp.ConsumeIntegral<uint64_t>() /* extent */};
78 }
79 descriptorSync =
80 MQDescriptorSync<uint8_t>{grantDescriptor, testHandle, size};
81 } else {
82 descriptorSync = MQDescriptorSync<uint8_t>{bufferSize, testHandle, size,
83 mFdp.ConsumeBool()};
84 }
85 writeEmbeddedToParcel(
86 descriptorSync, &parcel,
87 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
88 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
89 },
90 [&]() {
91 native_handle_t* testNativeHandle = native_handle_create(
92 mFdp.ConsumeIntegralInRange<uint32_t>(kMin, NATIVE_HANDLE_MAX_FDS),
93 mFdp.ConsumeIntegralInRange<uint32_t>(kMin, NATIVE_HANDLE_MAX_INTS));
94 writeEmbeddedToParcel(
95 testNativeHandle, &parcel,
96 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
97 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
98 native_handle_close(testNativeHandle);
99 native_handle_delete(testNativeHandle);
100 },
101 [&]() {
102 Status status = createStatus(mFdp);
103 writeToParcel(status, &parcel);
104 },
105 [&]() {
106 auto parcelSize = mFdp.ConsumeIntegralInRange<size_t>(kMinByte, kMaxByte);
107 std::vector<uint8_t> data = mFdp.ConsumeBytes<uint8_t>(parcelSize);
108 parcel.write(data.data(), data.size());
109 },
110 });
111 invokeHidlBaseParcelWriteAPI();
112 }
113 }
114
process()115 void HidlBaseParcelFuzzer::process() {
116 Parcel parcel;
117 size_t originalPosition = parcel.dataPosition();
118 createRandomParcel(parcel);
119 parcel.setDataPosition(originalPosition);
120 while (mFdp.remaining_bytes()) {
121 auto invokeHidlBaseParcelAPI = mFdp.PickValueInArray<const std::function<void()>>({
122 [&]() {
123 hidl_memory memory = createHidlMemory(mFdp);
124 readEmbeddedFromParcel(
125 memory, parcel,
126 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
127 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
128 },
129 [&]() {
130 MQDescriptorSync<uint8_t> descriptorSync;
131 readEmbeddedFromParcel(
132 descriptorSync, parcel,
133 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
134 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
135 },
136 [&]() {
137 hidl_handle handle;
138 readEmbeddedFromParcel(
139 handle, parcel,
140 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
141 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
142 },
143 [&]() {
144 hidl_string hidlString = createHidlString(mFdp);
145 readEmbeddedFromParcel(
146 hidlString, parcel,
147 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize),
148 mFdp.ConsumeIntegralInRange<uint32_t>(kMinSize, kMaxSize));
149 },
150 [&]() {
151 Status status = createStatus(mFdp);
152 readFromParcel(&status, parcel);
153 },
154 });
155 invokeHidlBaseParcelAPI();
156 }
157 }
158
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)159 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
160 HidlBaseParcelFuzzer hidlBaseParcelFuzzer(data, size);
161 hidlBaseParcelFuzzer.process();
162 return 0;
163 }
164