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