• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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