1 /******************************************************************************
2 *
3 * Copyright (C) 2021 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 #include "VehicleManager_fuzzer.h"
22 #include <utils/SystemClock.h>
23 #include <vhal_v2_0/Obd2SensorStore.h>
24 #include <vhal_v2_0/WatchdogClient.h>
25
26 namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
27
28 using ::aidl::android::automotive::watchdog::TimeoutLength;
29 using ::android::elapsedRealtimeNano;
30 using ::android::Looper;
31 using ::android::sp;
32 using ::android::hardware::hidl_handle;
33 using ::android::hardware::hidl_string;
34 using ::android::hardware::hidl_vec;
35 using ::android::hardware::automotive::vehicle::V2_0::DiagnosticFloatSensorIndex;
36 using ::android::hardware::automotive::vehicle::V2_0::DiagnosticIntegerSensorIndex;
37 using ::android::hardware::automotive::vehicle::V2_0::kCustomComplexProperty;
38 using ::android::hardware::automotive::vehicle::V2_0::kVehicleProperties;
39 using ::android::hardware::automotive::vehicle::V2_0::MockedVehicleCallback;
40 using ::android::hardware::automotive::vehicle::V2_0::Obd2SensorStore;
41 using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
42 using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
43 using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
44 using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
45 using ::android::hardware::automotive::vehicle::V2_0::VehicleAreaConfig;
46 using ::android::hardware::automotive::vehicle::V2_0::VehicleHal;
47 using ::android::hardware::automotive::vehicle::V2_0::VehicleHalManager;
48 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
49 using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
50 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyAccess;
51 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyChangeMode;
52 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
53 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyType;
54 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
55 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
56 using ::android::hardware::automotive::vehicle::V2_0::VmsMessageType;
57 using ::android::hardware::automotive::vehicle::V2_0::WatchdogClient;
58 using ::android::hardware::automotive::vehicle::V2_0::vms::createAvailabilityRequest;
59 using ::android::hardware::automotive::vehicle::V2_0::vms::createBaseVmsMessage;
60 using ::android::hardware::automotive::vehicle::V2_0::vms::createPublisherIdRequest;
61 using ::android::hardware::automotive::vehicle::V2_0::vms::createStartSessionMessage;
62 using ::android::hardware::automotive::vehicle::V2_0::vms::createSubscriptionsRequest;
63 using ::android::hardware::automotive::vehicle::V2_0::vms::getAvailableLayers;
64 using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForAvailabilityState;
65 using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForSubscriptionsState;
66 using ::android::hardware::automotive::vehicle::V2_0::vms::hasServiceNewlyStarted;
67 using ::android::hardware::automotive::vehicle::V2_0::vms::isAvailabilitySequenceNumberNewer;
68 using ::android::hardware::automotive::vehicle::V2_0::vms::isSequenceNumberNewer;
69 using ::android::hardware::automotive::vehicle::V2_0::vms::isValidVmsMessage;
70 using ::android::hardware::automotive::vehicle::V2_0::vms::parseData;
71 using ::android::hardware::automotive::vehicle::V2_0::vms::parseMessageType;
72 using ::android::hardware::automotive::vehicle::V2_0::vms::parsePublisherIdResponse;
73 using ::android::hardware::automotive::vehicle::V2_0::vms::parseStartSessionMessage;
74 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayer;
75 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerAndPublisher;
76 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
77 using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
78
79 constexpr const char kCarMake[] = "Default Car";
80 constexpr VehicleProperty kVehicleProp[] = {VehicleProperty::INVALID,
81 VehicleProperty::HVAC_FAN_SPEED,
82 VehicleProperty::INFO_MAKE,
83 VehicleProperty::DISPLAY_BRIGHTNESS,
84 VehicleProperty::INFO_FUEL_CAPACITY,
85 VehicleProperty::HVAC_SEAT_TEMPERATURE};
86 constexpr DiagnosticIntegerSensorIndex kDiagnosticIntIndex[] = {
87 DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
88 DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON,
89 DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT,
90 DiagnosticIntegerSensorIndex::FUEL_TYPE};
91 constexpr DiagnosticFloatSensorIndex kDiagnosticFloatIndex[] = {
92 DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD,
93 DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1,
94 DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1,
95 DiagnosticFloatSensorIndex::THROTTLE_POSITION};
96 constexpr size_t kVehiclePropArrayLength = std::size(kVehicleProp);
97 constexpr size_t kIntSensorArrayLength = std::size(kDiagnosticIntIndex);
98 constexpr size_t kFloatSensorArrayLength = std::size(kDiagnosticFloatIndex);
99 constexpr VmsMessageType kAvailabilityMessageType[] = {VmsMessageType::AVAILABILITY_CHANGE,
100 VmsMessageType::AVAILABILITY_RESPONSE};
101 constexpr VmsMessageType kSubscriptionMessageType[] = {VmsMessageType::SUBSCRIPTIONS_CHANGE,
102 VmsMessageType::SUBSCRIPTIONS_RESPONSE};
103
get(const VehiclePropValue & requestedPropValue,StatusCode * outStatus)104 MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
105 const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
106 VehiclePropValuePtr pValue = nullptr;
107 if (outStatus == nullptr) {
108 return pValue;
109 }
110 auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
111 int32_t areaId = requestedPropValue.areaId;
112 *outStatus = StatusCode::OK;
113
114 switch (property) {
115 case VehicleProperty::INFO_MAKE:
116 pValue = getValuePool()->obtainString(kCarMake);
117 break;
118 case VehicleProperty::INFO_FUEL_CAPACITY:
119 if (mFuelCapacityAttemptsLeft-- > 0) {
120 *outStatus = StatusCode::TRY_AGAIN;
121 } else {
122 pValue = getValuePool()->obtainFloat(42.42);
123 }
124 break;
125 default:
126 if (requestedPropValue.prop == kCustomComplexProperty) {
127 pValue = getValuePool()->obtainComplex();
128 pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
129 pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
130 pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
131 pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
132 pValue->value.stringValue = kCarMake;
133 break;
134 }
135 auto key = makeKey(toInt(property), areaId);
136 pValue = getValuePool()->obtain(mValues[key]);
137 }
138
139 if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
140 pValue->prop = toInt(property);
141 pValue->areaId = areaId;
142 pValue->timestamp = elapsedRealtimeNano();
143 }
144
145 return pValue;
146 }
147
process(const uint8_t * data,size_t size)148 void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
149 mFuzzedDataProvider = new FuzzedDataProvider(data, size);
150 invokeDebug();
151 invokePropConfigs();
152 invokeSubscribe();
153 invokeSetAndGetValues();
154 invokeObd2SensorStore();
155 invokeVmsUtils();
156 invokeVehiclePropStore();
157 invokeWatchDogClient();
158 }
159
invokeDebug()160 void VehicleHalManagerFuzzer::invokeDebug() {
161 hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
162 {"--help", "--list", "--get", "--set", "", "invalid"});
163 hidl_handle fd = {};
164 fd.setTo(native_handle_create(/*numFds=*/1, /*numInts=*/0), /*shouldOwn=*/true);
165
166 mManager->debug(fd, {});
167 mManager->debug(fd, {debugOption});
168 }
169
invokePropConfigs()170 void VehicleHalManagerFuzzer::invokePropConfigs() {
171 int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
172 int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
173
174 hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
175
176 mManager->getPropConfigs(properties,
177 []([[maybe_unused]] StatusCode status,
178 [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
179
180 mManager->getPropConfigs({toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength])},
181 []([[maybe_unused]] StatusCode status,
182 [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
183
184 mManager->getAllPropConfigs(
185 []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
186 }
187
invokeSubscribe()188 void VehicleHalManagerFuzzer::invokeSubscribe() {
189 int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
190 int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
191 int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
192
193 const auto prop1 = toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength]);
194 sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
195
196 hidl_vec<SubscribeOptions> options = {
197 SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
198
199 mManager->subscribe(cb, options);
200
201 auto unsubscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
202 unsubscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
203
204 mHal->sendPropEvent(std::move(unsubscribedValue));
205 cb->getReceivedEvents();
206 cb->waitForExpectedEvents(0);
207
208 auto subscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
209 subscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
210 subscribedValue->value.int32Values[0] = INT32_MAX;
211
212 cb->reset();
213 VehiclePropValue actualValue(*subscribedValue.get());
214 mHal->sendPropEvent(std::move(subscribedValue));
215 cb->waitForExpectedEvents(1);
216 mManager->unsubscribe(cb, prop1);
217
218 sp<MockedVehicleCallback> cb2 = new MockedVehicleCallback();
219
220 hidl_vec<SubscribeOptions> options2 = {
221 SubscribeOptions{
222 .propId = toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
223 .flags = SubscribeFlags::EVENTS_FROM_CAR},
224 };
225
226 mManager->subscribe(cb2, options2);
227
228 mHal->sendHalError(StatusCode::TRY_AGAIN,
229 toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
230 /*areaId=*/0);
231 }
232
invokeSetAndGetValues()233 void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
234 uint32_t vehicleProp1 =
235 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
236 uint32_t vehicleProp2 =
237 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
238 uint32_t vehicleProp3 =
239 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
240
241 invokeGet(kCustomComplexProperty, 0);
242 invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
243 invokeGet(toInt(kVehicleProp[vehicleProp1]), 0);
244
245 auto expectedValue = mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
246 mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>());
247 mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
248 mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool());
249 expectedValue->prop = toInt(kVehicleProp[vehicleProp2]);
250 expectedValue->areaId = 0;
251
252 mManager->set(*expectedValue.get());
253 invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
254 expectedValue->prop = toInt(kVehicleProp[vehicleProp3]);
255 mManager->set(*expectedValue.get());
256 expectedValue->prop = toInt(VehicleProperty::INVALID);
257 mManager->set(*expectedValue.get());
258 }
259
invokeObd2SensorStore()260 void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
261 uint32_t diagnosticIntIndex =
262 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kIntSensorArrayLength - 1);
263 int32_t diagnosticIntValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
264 uint32_t diagnosticFloatIndex =
265 mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kFloatSensorArrayLength - 1);
266 float diagnosticFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
267
268 std::unique_ptr<Obd2SensorStore> sensorStore(
269 new Obd2SensorStore(kIntSensorArrayLength, kFloatSensorArrayLength));
270 if (sensorStore) {
271 sensorStore->setIntegerSensor(kDiagnosticIntIndex[diagnosticIntIndex], diagnosticIntValue);
272 sensorStore->setFloatSensor(kDiagnosticFloatIndex[diagnosticFloatIndex],
273 diagnosticFloatValue);
274 sensorStore->getIntegerSensors();
275 sensorStore->getFloatSensors();
276 sensorStore->getSensorsBitmask();
277 static std::vector<std::string> sampleDtcs = {"P0070",
278 "P0102"
279 "P0123"};
280 for (auto&& dtc : sampleDtcs) {
281 auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
282 sensorStore->fillPropValue(dtc, freezeFrame.get());
283 freezeFrame->prop = static_cast<int>(VehicleProperty::OBD2_FREEZE_FRAME);
284 }
285 }
286 }
287
invokeVmsUtils()288 void VehicleHalManagerFuzzer::invokeVmsUtils() {
289 bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
290 bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
291 int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
292
293 VmsLayer layer(1, 0, 2);
294 auto message = createSubscribeMessage(layer);
295 isValidVmsMessage(*message);
296 message = createUnsubscribeMessage(layer);
297
298 VmsOffers offers = {intValue, {VmsLayerOffering(VmsLayer(1, 0, 2))}};
299 message = createOfferingMessage(offers);
300 std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2), VmsLayer(3, 0, 3)};
301 std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
302 offers = {intValue, offering};
303 message = createOfferingMessage(offers);
304
305 message = createAvailabilityRequest();
306 message = createSubscriptionsRequest();
307
308 std::string bytes = "placeholder";
309 const VmsLayerAndPublisher layer_and_publisher(VmsLayer(2, 0, 1), intValue);
310 message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
311 parseData(*message);
312 createSubscribeToPublisherMessage(layer_and_publisher);
313 createUnsubscribeToPublisherMessage(layer_and_publisher);
314
315 std::string pub_bytes = "pub_id";
316 message = createPublisherIdRequest(pub_bytes);
317 message = createBaseVmsMessage(2);
318 message->value.int32Values =
319 hidl_vec<int32_t>{toInt(VmsMessageType::PUBLISHER_ID_RESPONSE), intValue};
320 parsePublisherIdResponse(*message);
321
322 message->value.int32Values =
323 hidl_vec<int32_t>{toInt(kSubscriptionMessageType[subscriptionMsgType]), intValue};
324 getSequenceNumberForSubscriptionsState(*message);
325
326 message->value.int32Values = hidl_vec<int32_t>{toInt(kSubscriptionMessageType[0]), intValue};
327 isSequenceNumberNewer(*message, intValue + 1);
328 invokeGetSubscribedLayers(kSubscriptionMessageType[subscriptionMsgType]);
329
330 message->value.int32Values =
331 hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), 0};
332 hasServiceNewlyStarted(*message);
333 message = createStartSessionMessage(intValue, intValue + 1);
334 parseMessageType(*message);
335
336 message->value.int32Values =
337 hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
338 isAvailabilitySequenceNumberNewer(*message, intValue + 1);
339
340 message->value.int32Values =
341 hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
342 getSequenceNumberForAvailabilityState(*message);
343 message = createBaseVmsMessage(3);
344 int new_service_id;
345 message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
346 parseStartSessionMessage(*message, -1, 0, &new_service_id);
347 }
348
invokeGet(int32_t property,int32_t areaId)349 void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
350 VehiclePropValue requestedValue{};
351 requestedValue.prop = property;
352 requestedValue.areaId = areaId;
353 mActualValue = VehiclePropValue{}; // reset previous values
354
355 StatusCode refStatus;
356 VehiclePropValue refValue;
357 mManager->get(requestedValue,
358 [&refStatus, &refValue](StatusCode status, const VehiclePropValue& value) {
359 refStatus = status;
360 refValue = value;
361 });
362
363 mActualValue = refValue;
364 mActualStatusCode = refStatus;
365 }
366
invokeGetSubscribedLayers(VmsMessageType type)367 void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType type) {
368 VmsOffers offers = {123,
369 {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
370 VmsLayerOffering(VmsLayer(2, 0, 1))}};
371 auto message = createBaseVmsMessage(16);
372 message->value.int32Values = hidl_vec<int32_t>{toInt(type),
373 1234, // sequence number
374 2, // number of layers
375 1, // number of associated layers
376 1, // layer 1
377 0, 1,
378 4, // layer 2
379 1, 1,
380 2, // associated layer
381 0, 1,
382 2, // number of publisher IDs
383 111, // publisher IDs
384 123};
385 isValidVmsMessage(*message);
386 getSubscribedLayers(*message, offers);
387 getAvailableLayers(*message);
388 }
389
invokeVehiclePropStore()390 void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
391 bool shouldWriteStatus = mFuzzedDataProvider->ConsumeBool();
392 int32_t vehicleProp = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
393 auto store = std::make_unique<VehiclePropertyStore>();
394 VehiclePropConfig config{
395 .prop = vehicleProp,
396 .access = VehiclePropertyAccess::READ,
397 .changeMode = VehiclePropertyChangeMode::STATIC,
398 .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
399 };
400 store->registerProperty(config);
401 VehiclePropValue propValue{};
402 propValue.prop = vehicleProp;
403 propValue.areaId = 0;
404 store->writeValue(propValue, shouldWriteStatus);
405 store->readAllValues();
406 store->getAllConfigs();
407 store->getConfigOrNull(vehicleProp);
408 store->readValuesForProperty(vehicleProp);
409 store->readValueOrNull(propValue);
410 store->readValueOrNull(propValue.prop, propValue.areaId, 0);
411 store->removeValuesForProperty(vehicleProp);
412 store->removeValue(propValue);
413 store->getConfigOrDie(vehicleProp);
414 }
415
invokeWatchDogClient()416 void VehicleHalManagerFuzzer::invokeWatchDogClient() {
417 auto service = new VehicleHalManager(mHal.get());
418 sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
419 if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, service);
420 watchdogClient->initialize()) {
421 watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
422 watchdogClient->prepareProcessTermination();
423 }
424 delete service;
425 }
426
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)427 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
428 VehicleHalManagerFuzzer vmFuzzer;
429 vmFuzzer.process(data, size);
430 return 0;
431 }
432
433 } // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
434