1 /*
2 * Copyright (C) 2022 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 #include "AutomotiveCanV1_0Fuzzer.h"
18
19 namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
20
21 constexpr CanController::InterfaceType kInterfaceType[] = {
22 CanController::InterfaceType::VIRTUAL, CanController::InterfaceType::SOCKETCAN,
23 CanController::InterfaceType::SLCAN, CanController::InterfaceType::INDEXED};
24 constexpr FilterFlag kFilterFlag[] = {FilterFlag::DONT_CARE, FilterFlag::SET, FilterFlag::NOT_SET};
25 constexpr size_t kInterfaceTypeLength = std::size(kInterfaceType);
26 constexpr size_t kFilterFlagLength = std::size(kFilterFlag);
27 constexpr size_t kMaxCharacters = 30;
28 constexpr size_t kMaxPayloadBytes = 64;
29 constexpr size_t kMaxFilters = 20;
30 constexpr size_t kMaxSerialNumber = 1000;
31 constexpr size_t kMaxBuses = 100;
32 constexpr size_t kMaxRepeat = 100;
33
makeBus()34 Bus CanFuzzer::makeBus() {
35 ICanController::BusConfig config = {};
36 if (mBusNames.size() > 0 && mLastInterface < mBusNames.size()) {
37 config.name = mBusNames[mLastInterface++];
38 } else {
39 config.name = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
40 }
41 config.interfaceId.virtualif({mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters)});
42 return Bus(mCanController, config);
43 }
44
getSupportedInterfaceTypes()45 void CanFuzzer::getSupportedInterfaceTypes() {
46 hidl_vec<CanController::InterfaceType> iftypesResult;
47 mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&iftypesResult));
48 }
49
getBusNames()50 hidl_vec<hidl_string> CanFuzzer::getBusNames() {
51 hidl_vec<hidl_string> services = {};
52 if (auto manager = hidl::manager::V1_2::IServiceManager::getService(); manager) {
53 manager->listManifestByInterface(ICanBus::descriptor, hidl_utils::fill(&services));
54 }
55 return services;
56 }
57
invokeUpInterface()58 void CanFuzzer::invokeUpInterface() {
59 CanController::InterfaceType controller;
60 if (mFuzzedDataProvider->ConsumeBool()) {
61 controller = (CanController::InterfaceType)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
62 } else {
63 controller = kInterfaceType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
64 0, kInterfaceTypeLength - 1)];
65 }
66 std::string configName;
67
68 if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
69 (shouldInvokeValidBus) && (mBusNames.size() > 0)) {
70 const size_t busNameIndex =
71 mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
72 configName = mBusNames[busNameIndex];
73 } else {
74 configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
75 }
76 const std::string ifname = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
77
78 ICanController::BusConfig config = {.name = configName};
79
80 if (controller == CanController::InterfaceType::SOCKETCAN) {
81 CanController::BusConfig::InterfaceId::Socketcan socketcan = {};
82 if (const bool shouldPassSerialSocket = mFuzzedDataProvider->ConsumeBool();
83 shouldPassSerialSocket) {
84 socketcan.serialno(
85 {mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
86 } else {
87 socketcan.ifname(ifname);
88 }
89 config.interfaceId.socketcan(socketcan);
90 } else if (controller == CanController::InterfaceType::SLCAN) {
91 CanController::BusConfig::InterfaceId::Slcan slcan = {};
92 if (const bool shouldPassSerialSlcan = mFuzzedDataProvider->ConsumeBool();
93 shouldPassSerialSlcan) {
94 slcan.serialno(
95 {mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
96 } else {
97 slcan.ttyname(ifname);
98 }
99 config.interfaceId.slcan(slcan);
100 } else if (controller == CanController::InterfaceType::VIRTUAL) {
101 config.interfaceId.virtualif({ifname});
102 } else if (controller == CanController::InterfaceType::INDEXED) {
103 CanController::BusConfig::InterfaceId::Indexed indexed;
104 indexed.index = mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
105 config.interfaceId.indexed(indexed);
106 }
107
108 const size_t numInvocations =
109 mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
110 for (size_t i = 0; i < numInvocations; ++i) {
111 mCanController->upInterface(config);
112 }
113 }
114
invokeDownInterface()115 void CanFuzzer::invokeDownInterface() {
116 hidl_string configName;
117 if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
118 (shouldInvokeValidBus) && (mBusNames.size() > 0)) {
119 size_t busNameIndex;
120 if (mBusNames.size() == 1) {
121 busNameIndex = 0;
122 } else {
123 busNameIndex =
124 mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
125 }
126 configName = mBusNames[busNameIndex];
127 } else {
128 configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
129 }
130
131 const size_t numInvocations =
132 mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
133 for (size_t i = 0; i < numInvocations; ++i) {
134 mCanController->downInterface(configName);
135 }
136 }
137
invokeBus()138 void CanFuzzer::invokeBus() {
139 const size_t numBuses = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxBuses);
140 for (size_t i = 0; i < numBuses; ++i) {
141 if (const bool shouldSendMessage = mFuzzedDataProvider->ConsumeBool(); shouldSendMessage) {
142 auto sendingBus = makeBus();
143 CanMessage msg = {.id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>()};
144 uint32_t numPayloadBytes =
145 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxPayloadBytes);
146 hidl_vec<uint8_t> payload(numPayloadBytes);
147 for (uint32_t j = 0; j < numPayloadBytes; ++j) {
148 payload[j] = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
149 }
150 msg.payload = payload;
151 msg.remoteTransmissionRequest = mFuzzedDataProvider->ConsumeBool();
152 msg.isExtendedId = mFuzzedDataProvider->ConsumeBool();
153 sendingBus.send(msg);
154 } else {
155 auto listeningBus = makeBus();
156 uint32_t numFilters =
157 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxFilters);
158 hidl_vec<CanMessageFilter> filterVector(numFilters);
159 for (uint32_t k = 0; k < numFilters; ++k) {
160 filterVector[k].id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
161 filterVector[k].mask = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
162 if (mFuzzedDataProvider->ConsumeBool()) {
163 filterVector[k].rtr =
164 (FilterFlag)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
165 } else {
166 filterVector[k].rtr =
167 kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
168 0, kFilterFlagLength - 1)];
169 }
170 if (mFuzzedDataProvider->ConsumeBool()) {
171 filterVector[k].extendedFormat =
172 (FilterFlag)mFuzzedDataProvider->ConsumeIntegral<uint8_t>();
173 } else {
174 filterVector[k].extendedFormat =
175 kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
176 0, kFilterFlagLength - 1)];
177 }
178 filterVector[k].exclude = mFuzzedDataProvider->ConsumeBool();
179 }
180 auto listener = listeningBus.listen(filterVector);
181 }
182 }
183 }
184
deInit()185 void CanFuzzer::deInit() {
186 mCanController.clear();
187 if (mFuzzedDataProvider) {
188 delete mFuzzedDataProvider;
189 }
190 mBusNames = {};
191 }
192
process(const uint8_t * data,size_t size)193 void CanFuzzer::process(const uint8_t* data, size_t size) {
194 mFuzzedDataProvider = new FuzzedDataProvider(data, size);
195 while (mFuzzedDataProvider->remaining_bytes()) {
196 auto CanFuzzerFunction =
197 mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
198 [&]() { getSupportedInterfaceTypes(); },
199 [&]() { invokeUpInterface(); },
200 [&]() { invokeDownInterface(); },
201 [&]() { invokeBus(); },
202 });
203 CanFuzzerFunction();
204 }
205 }
206
init()207 bool CanFuzzer::init() {
208 mCanController = sp<CanController>::make();
209 if (!mCanController) {
210 return false;
211 }
212 mBusNames = getBusNames();
213 return true;
214 }
215
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)216 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
217 if (size < 1) {
218 return 0;
219 }
220 CanFuzzer canFuzzer;
221 if (canFuzzer.init()) {
222 canFuzzer.process(data, size);
223 }
224 return 0;
225 }
226
227 } // namespace android::hardware::automotive::can::V1_0::implementation::fuzzer
228