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