xref: /aosp_15_r20/system/libhidl/fuzzer/libHidlBase_parcel_fuzzer.cpp (revision 8222fbe171c3d6fadfe95119c180cf3010c392a8)
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