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