mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 22:04:26 +00:00
Merge "Added vehicleManager_fuzzer" am: e33bc952cf
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1510958 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I21b3033079689c95a0ac26f0ee00bdcda0f8888c
This commit is contained in:
@@ -221,3 +221,29 @@ cc_binary {
|
||||
"android.hardware.automotive.vehicle@2.0-libproto-native",
|
||||
],
|
||||
}
|
||||
|
||||
cc_fuzz {
|
||||
name: "vehicleManager_fuzzer",
|
||||
vendor: true,
|
||||
defaults: ["vhal_v2_0_target_defaults"],
|
||||
whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
|
||||
srcs: [
|
||||
"tests/fuzzer/VehicleManager_fuzzer.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
header_libs: ["libbase_headers"],
|
||||
local_include_dirs: [
|
||||
"common/include",
|
||||
"tests",
|
||||
],
|
||||
fuzz_config: {
|
||||
cc: [
|
||||
"android-media-fuzzing-reports@google.com",
|
||||
],
|
||||
componentid: 533764,
|
||||
},
|
||||
}
|
||||
|
||||
66
automotive/vehicle/2.0/default/tests/fuzzer/README.md
Normal file
66
automotive/vehicle/2.0/default/tests/fuzzer/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Fuzzer for android.hardware.automotive.vehicle@2.0-manager-lib
|
||||
|
||||
## Plugin Design Considerations
|
||||
The fuzzer plugin for android.hardware.automotive.vehicle@2.0-manager-lib is
|
||||
designed based on the understanding of the library and tries to achieve the following:
|
||||
|
||||
##### Maximize code coverage
|
||||
The configuration parameters are not hardcoded, but instead selected based on
|
||||
incoming data. This ensures more code paths are reached by the fuzzer.
|
||||
|
||||
Vehicle Manager supports the following parameters:
|
||||
1. Vehicle Property (parameter name: `vehicleProp`)
|
||||
2. Diagnostic Integer Sensor Index (parameter name: `diagnosticIntIndex`)
|
||||
3. Diagnostic Float Sensor Index (parameter name: `diagnosticFloatIndex`)
|
||||
4. Availability Message Type (parameter name: `availabilityMsgType`)
|
||||
5. Subscription Message Type (parameter name: `subscriptionMsgType`)
|
||||
|
||||
| Parameter| Valid Values| Configured Value|
|
||||
|------------- |-------------| ----- |
|
||||
| `vehicleProp` | 0.`VehicleProperty::INVALID` 1.`VehicleProperty::HVAC_FAN_SPEED` 2.`VehicleProperty::INFO_MAKE` 3.`VehicleProperty::DISPLAY_BRIGHTNESS` 4.`VehicleProperty::INFO_FUEL_CAPACITY` 5.`VehicleProperty::HVAC_SEAT_TEMPERATURE`| Value obtained from FuzzedDataProvider |
|
||||
| `diagnosticIntIndex` | 0.`DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS` 1.`DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON` 2.`DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT` 3.`DiagnosticIntegerSensorIndex::FUEL_TYPE` | Value obtained from FuzzedDataProvider |
|
||||
| `diagnosticFloatIndex` | 0.`DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD` 1.`DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1` 2.`DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1` 3.`DiagnosticFloatSensorIndex::THROTTLE_POSITION` | Value obtained from FuzzedDataProvider |
|
||||
| `availabilityMsgType` | 0.`VmsMessageType::AVAILABILITY_CHANGE` 1.`VmsMessageType::AVAILABILITY_RESPONSE` | Value obtained from FuzzedDataProvider |
|
||||
| `subscriptionMsgType` | 0.`VmsMessageType::SUBSCRIPTIONS_CHANGE` 1.`VmsMessageType::SUBSCRIPTIONS_RESPONSE` | Value obtained from FuzzedDataProvider |
|
||||
|
||||
This also ensures that the plugin is always deterministic for any given input.
|
||||
|
||||
## Build
|
||||
|
||||
This describes steps to build vehicleManager_fuzzer binary.
|
||||
|
||||
### Android
|
||||
|
||||
#### Steps to build
|
||||
Build the fuzzer
|
||||
```
|
||||
$ mm -j$(nproc) vehicleManager_fuzzer
|
||||
```
|
||||
|
||||
#### Steps to run
|
||||
Create a directory CORPUS_DIR
|
||||
```
|
||||
$ adb shell mkdir /data/local/tmp/CORPUS_DIR
|
||||
```
|
||||
|
||||
##### Some Additional steps needed to run the vehicleManager_fuzzer successfully on device
|
||||
|
||||
1. Push the following libraries from /vendor/lib/ and /vendor/lib64/ folders of your workspace to the device's /vendor/lib/ and /vendor/lib64/ :
|
||||
```
|
||||
1.1 android.hardware.automotive.vehicle@2.0.so
|
||||
1.2 carwatchdog_aidl_interface-V2-ndk_platform.so
|
||||
```
|
||||
2. Now, reboot the device using command
|
||||
```
|
||||
$ adb reboot
|
||||
```
|
||||
|
||||
##### To run the fuzzer on device
|
||||
```
|
||||
$ adb sync data
|
||||
$ adb shell LD_LIBRARY_PATH=/vendor/lib64 /data/fuzz/${TARGET_ARCH}/vehicleManager_fuzzer/vendor/vehicleManager_fuzzer /data/local/tmp/CORPUS_DIR
|
||||
```
|
||||
|
||||
## References:
|
||||
* http://llvm.org/docs/LibFuzzer.html
|
||||
* https://github.com/google/oss-fuzz
|
||||
@@ -0,0 +1,433 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
||||
*/
|
||||
|
||||
#include "VehicleManager_fuzzer.h"
|
||||
#include <utils/SystemClock.h>
|
||||
#include <vhal_v2_0/Obd2SensorStore.h>
|
||||
#include <vhal_v2_0/WatchdogClient.h>
|
||||
|
||||
namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
|
||||
|
||||
using ::aidl::android::automotive::watchdog::TimeoutLength;
|
||||
using ::android::elapsedRealtimeNano;
|
||||
using ::android::Looper;
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_handle;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::DiagnosticFloatSensorIndex;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::DiagnosticIntegerSensorIndex;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::kCustomComplexProperty;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::kVehicleProperties;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::MockedVehicleCallback;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::Obd2SensorStore;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehicleAreaConfig;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehicleHal;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehicleHalManager;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyAccess;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyChangeMode;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyType;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::VmsMessageType;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::WatchdogClient;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::createAvailabilityRequest;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::createBaseVmsMessage;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::createPublisherIdRequest;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::createStartSessionMessage;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::createSubscriptionsRequest;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::getAvailableLayers;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForAvailabilityState;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForSubscriptionsState;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::hasServiceNewlyStarted;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::isAvailabilitySequenceNumberNewer;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::isSequenceNumberNewer;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::isValidVmsMessage;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::parseData;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::parseMessageType;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::parsePublisherIdResponse;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::parseStartSessionMessage;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayer;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerAndPublisher;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
|
||||
using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
|
||||
|
||||
constexpr const char kCarMake[] = "Default Car";
|
||||
constexpr VehicleProperty kVehicleProp[] = {VehicleProperty::INVALID,
|
||||
VehicleProperty::HVAC_FAN_SPEED,
|
||||
VehicleProperty::INFO_MAKE,
|
||||
VehicleProperty::DISPLAY_BRIGHTNESS,
|
||||
VehicleProperty::INFO_FUEL_CAPACITY,
|
||||
VehicleProperty::HVAC_SEAT_TEMPERATURE};
|
||||
constexpr DiagnosticIntegerSensorIndex kDiagnosticIntIndex[] = {
|
||||
DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
|
||||
DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON,
|
||||
DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT,
|
||||
DiagnosticIntegerSensorIndex::FUEL_TYPE};
|
||||
constexpr DiagnosticFloatSensorIndex kDiagnosticFloatIndex[] = {
|
||||
DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD,
|
||||
DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1,
|
||||
DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1,
|
||||
DiagnosticFloatSensorIndex::THROTTLE_POSITION};
|
||||
constexpr size_t kVehiclePropArrayLength = std::size(kVehicleProp);
|
||||
constexpr size_t kIntSensorArrayLength = std::size(kDiagnosticIntIndex);
|
||||
constexpr size_t kFloatSensorArrayLength = std::size(kDiagnosticFloatIndex);
|
||||
constexpr VmsMessageType kAvailabilityMessageType[] = {VmsMessageType::AVAILABILITY_CHANGE,
|
||||
VmsMessageType::AVAILABILITY_RESPONSE};
|
||||
constexpr VmsMessageType kSubscriptionMessageType[] = {VmsMessageType::SUBSCRIPTIONS_CHANGE,
|
||||
VmsMessageType::SUBSCRIPTIONS_RESPONSE};
|
||||
|
||||
MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
|
||||
const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
|
||||
VehiclePropValuePtr pValue = nullptr;
|
||||
if (outStatus == nullptr) {
|
||||
return pValue;
|
||||
}
|
||||
auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
|
||||
int32_t areaId = requestedPropValue.areaId;
|
||||
*outStatus = StatusCode::OK;
|
||||
|
||||
switch (property) {
|
||||
case VehicleProperty::INFO_MAKE:
|
||||
pValue = getValuePool()->obtainString(kCarMake);
|
||||
break;
|
||||
case VehicleProperty::INFO_FUEL_CAPACITY:
|
||||
if (mFuelCapacityAttemptsLeft-- > 0) {
|
||||
*outStatus = StatusCode::TRY_AGAIN;
|
||||
} else {
|
||||
pValue = getValuePool()->obtainFloat(42.42);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (requestedPropValue.prop == kCustomComplexProperty) {
|
||||
pValue = getValuePool()->obtainComplex();
|
||||
pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
|
||||
pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
|
||||
pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
|
||||
pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
|
||||
pValue->value.stringValue = kCarMake;
|
||||
break;
|
||||
}
|
||||
auto key = makeKey(toInt(property), areaId);
|
||||
pValue = getValuePool()->obtain(mValues[key]);
|
||||
}
|
||||
|
||||
if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
|
||||
pValue->prop = toInt(property);
|
||||
pValue->areaId = areaId;
|
||||
pValue->timestamp = elapsedRealtimeNano();
|
||||
}
|
||||
|
||||
return pValue;
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
|
||||
mFuzzedDataProvider = new FuzzedDataProvider(data, size);
|
||||
invokeDebug();
|
||||
invokePropConfigs();
|
||||
invokeSubscribe();
|
||||
invokeSetAndGetValues();
|
||||
invokeObd2SensorStore();
|
||||
invokeVmsUtils();
|
||||
invokeVehiclePropStore();
|
||||
invokeWatchDogClient();
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeDebug() {
|
||||
hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
|
||||
{"--help", "--list", "--get", "--set", "", "invalid"});
|
||||
hidl_handle fd = {};
|
||||
fd.setTo(native_handle_create(/*numFds=*/1, /*numInts=*/0), /*shouldOwn=*/true);
|
||||
|
||||
mManager->debug(fd, {});
|
||||
mManager->debug(fd, {debugOption});
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokePropConfigs() {
|
||||
int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
|
||||
hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
|
||||
|
||||
mManager->getPropConfigs(properties,
|
||||
[]([[maybe_unused]] StatusCode status,
|
||||
[[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
|
||||
|
||||
mManager->getPropConfigs({toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength])},
|
||||
[]([[maybe_unused]] StatusCode status,
|
||||
[[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
|
||||
|
||||
mManager->getAllPropConfigs(
|
||||
[]([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeSubscribe() {
|
||||
int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
|
||||
const auto prop1 = toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength]);
|
||||
sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
|
||||
|
||||
hidl_vec<SubscribeOptions> options = {
|
||||
SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
|
||||
|
||||
mManager->subscribe(cb, options);
|
||||
|
||||
auto unsubscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
|
||||
unsubscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
|
||||
|
||||
mHal->sendPropEvent(std::move(unsubscribedValue));
|
||||
cb->getReceivedEvents();
|
||||
cb->waitForExpectedEvents(0);
|
||||
|
||||
auto subscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
|
||||
subscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
|
||||
subscribedValue->value.int32Values[0] = INT32_MAX;
|
||||
|
||||
cb->reset();
|
||||
VehiclePropValue actualValue(*subscribedValue.get());
|
||||
mHal->sendPropEvent(std::move(subscribedValue));
|
||||
cb->waitForExpectedEvents(1);
|
||||
mManager->unsubscribe(cb, prop1);
|
||||
|
||||
sp<MockedVehicleCallback> cb2 = new MockedVehicleCallback();
|
||||
|
||||
hidl_vec<SubscribeOptions> options2 = {
|
||||
SubscribeOptions{
|
||||
.propId = toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
|
||||
.flags = SubscribeFlags::EVENTS_FROM_CAR},
|
||||
};
|
||||
|
||||
mManager->subscribe(cb2, options2);
|
||||
|
||||
mHal->sendHalError(StatusCode::TRY_AGAIN,
|
||||
toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
|
||||
/*areaId=*/0);
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
|
||||
uint32_t vehicleProp1 =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
|
||||
uint32_t vehicleProp2 =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
|
||||
uint32_t vehicleProp3 =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
|
||||
|
||||
invokeGet(kCustomComplexProperty, 0);
|
||||
invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
|
||||
invokeGet(toInt(kVehicleProp[vehicleProp1]), 0);
|
||||
|
||||
auto expectedValue = mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>());
|
||||
mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
|
||||
mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool());
|
||||
expectedValue->prop = toInt(kVehicleProp[vehicleProp2]);
|
||||
expectedValue->areaId = 0;
|
||||
|
||||
mManager->set(*expectedValue.get());
|
||||
invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
|
||||
expectedValue->prop = toInt(kVehicleProp[vehicleProp3]);
|
||||
mManager->set(*expectedValue.get());
|
||||
expectedValue->prop = toInt(VehicleProperty::INVALID);
|
||||
mManager->set(*expectedValue.get());
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
|
||||
uint32_t diagnosticIntIndex =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kIntSensorArrayLength - 1);
|
||||
int32_t diagnosticIntValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
uint32_t diagnosticFloatIndex =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kFloatSensorArrayLength - 1);
|
||||
float diagnosticFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
|
||||
|
||||
std::unique_ptr<Obd2SensorStore> sensorStore(
|
||||
new Obd2SensorStore(kIntSensorArrayLength, kFloatSensorArrayLength));
|
||||
if (sensorStore) {
|
||||
sensorStore->setIntegerSensor(kDiagnosticIntIndex[diagnosticIntIndex], diagnosticIntValue);
|
||||
sensorStore->setFloatSensor(kDiagnosticFloatIndex[diagnosticFloatIndex],
|
||||
diagnosticFloatValue);
|
||||
sensorStore->getIntegerSensors();
|
||||
sensorStore->getFloatSensors();
|
||||
sensorStore->getSensorsBitmask();
|
||||
static std::vector<std::string> sampleDtcs = {"P0070",
|
||||
"P0102"
|
||||
"P0123"};
|
||||
for (auto&& dtc : sampleDtcs) {
|
||||
auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
|
||||
sensorStore->fillPropValue(dtc, freezeFrame.get());
|
||||
freezeFrame->prop = static_cast<int>(VehicleProperty::OBD2_FREEZE_FRAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeVmsUtils() {
|
||||
bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
|
||||
bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
|
||||
int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
|
||||
VmsLayer layer(1, 0, 2);
|
||||
auto message = createSubscribeMessage(layer);
|
||||
isValidVmsMessage(*message);
|
||||
message = createUnsubscribeMessage(layer);
|
||||
|
||||
VmsOffers offers = {intValue, {VmsLayerOffering(VmsLayer(1, 0, 2))}};
|
||||
message = createOfferingMessage(offers);
|
||||
std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2), VmsLayer(3, 0, 3)};
|
||||
std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
|
||||
offers = {intValue, offering};
|
||||
message = createOfferingMessage(offers);
|
||||
|
||||
message = createAvailabilityRequest();
|
||||
message = createSubscriptionsRequest();
|
||||
|
||||
std::string bytes = "placeholder";
|
||||
const VmsLayerAndPublisher layer_and_publisher(VmsLayer(2, 0, 1), intValue);
|
||||
message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
|
||||
parseData(*message);
|
||||
createSubscribeToPublisherMessage(layer_and_publisher);
|
||||
createUnsubscribeToPublisherMessage(layer_and_publisher);
|
||||
|
||||
std::string pub_bytes = "pub_id";
|
||||
message = createPublisherIdRequest(pub_bytes);
|
||||
message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::PUBLISHER_ID_RESPONSE), intValue};
|
||||
parsePublisherIdResponse(*message);
|
||||
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(kSubscriptionMessageType[subscriptionMsgType]), intValue};
|
||||
getSequenceNumberForSubscriptionsState(*message);
|
||||
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(kSubscriptionMessageType[0]), intValue};
|
||||
isSequenceNumberNewer(*message, intValue + 1);
|
||||
invokeGetSubscribedLayers(kSubscriptionMessageType[subscriptionMsgType]);
|
||||
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), 0};
|
||||
hasServiceNewlyStarted(*message);
|
||||
message = createStartSessionMessage(intValue, intValue + 1);
|
||||
parseMessageType(*message);
|
||||
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
|
||||
isAvailabilitySequenceNumberNewer(*message, intValue + 1);
|
||||
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
|
||||
getSequenceNumberForAvailabilityState(*message);
|
||||
message = createBaseVmsMessage(3);
|
||||
int new_service_id;
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
|
||||
parseStartSessionMessage(*message, -1, 0, &new_service_id);
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
|
||||
VehiclePropValue requestedValue{};
|
||||
requestedValue.prop = property;
|
||||
requestedValue.areaId = areaId;
|
||||
mActualValue = VehiclePropValue{}; // reset previous values
|
||||
|
||||
StatusCode refStatus;
|
||||
VehiclePropValue refValue;
|
||||
mManager->get(requestedValue,
|
||||
[&refStatus, &refValue](StatusCode status, const VehiclePropValue& value) {
|
||||
refStatus = status;
|
||||
refValue = value;
|
||||
});
|
||||
|
||||
mActualValue = refValue;
|
||||
mActualStatusCode = refStatus;
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType type) {
|
||||
VmsOffers offers = {123,
|
||||
{VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
|
||||
VmsLayerOffering(VmsLayer(2, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(16);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
2, // number of layers
|
||||
1, // number of associated layers
|
||||
1, // layer 1
|
||||
0, 1,
|
||||
4, // layer 2
|
||||
1, 1,
|
||||
2, // associated layer
|
||||
0, 1,
|
||||
2, // number of publisher IDs
|
||||
111, // publisher IDs
|
||||
123};
|
||||
isValidVmsMessage(*message);
|
||||
getSubscribedLayers(*message, offers);
|
||||
getAvailableLayers(*message);
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
|
||||
bool shouldWriteStatus = mFuzzedDataProvider->ConsumeBool();
|
||||
int32_t vehicleProp = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
auto store = std::make_unique<VehiclePropertyStore>();
|
||||
VehiclePropConfig config{
|
||||
.prop = vehicleProp,
|
||||
.access = VehiclePropertyAccess::READ,
|
||||
.changeMode = VehiclePropertyChangeMode::STATIC,
|
||||
.areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
|
||||
};
|
||||
store->registerProperty(config);
|
||||
VehiclePropValue propValue{};
|
||||
propValue.prop = vehicleProp;
|
||||
propValue.areaId = 0;
|
||||
store->writeValue(propValue, shouldWriteStatus);
|
||||
store->readAllValues();
|
||||
store->getAllConfigs();
|
||||
store->getConfigOrNull(vehicleProp);
|
||||
store->readValuesForProperty(vehicleProp);
|
||||
store->readValueOrNull(propValue);
|
||||
store->readValueOrNull(propValue.prop, propValue.areaId, 0);
|
||||
store->removeValuesForProperty(vehicleProp);
|
||||
store->removeValue(propValue);
|
||||
store->getConfigOrDie(vehicleProp);
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeWatchDogClient() {
|
||||
auto service = new VehicleHalManager(mHal.get());
|
||||
sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
|
||||
if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, service);
|
||||
watchdogClient->initialize()) {
|
||||
watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
|
||||
watchdogClient->prepareProcessTermination();
|
||||
}
|
||||
delete service;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
VehicleHalManagerFuzzer vmFuzzer;
|
||||
vmFuzzer.process(data, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
|
||||
@@ -0,0 +1,124 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
||||
*/
|
||||
|
||||
#ifndef __VEHICLE_MANAGER_FUZZER_H__
|
||||
#define __VEHICLE_MANAGER_FUZZER_H__
|
||||
|
||||
#include <vhal_v2_0/VehicleHalManager.h>
|
||||
#include <vhal_v2_0/VehiclePropertyStore.h>
|
||||
#include <vhal_v2_0/VmsUtils.h>
|
||||
|
||||
#include <VehicleHalTestUtils.h>
|
||||
#include <fuzzer/FuzzedDataProvider.h>
|
||||
|
||||
namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
|
||||
|
||||
constexpr int kRetriableAttempts = 3;
|
||||
|
||||
class MockedVehicleHal : public VehicleHal {
|
||||
public:
|
||||
MockedVehicleHal()
|
||||
: mFuelCapacityAttemptsLeft(kRetriableAttempts),
|
||||
mMirrorFoldAttemptsLeft(kRetriableAttempts) {
|
||||
mConfigs.assign(std::begin(kVehicleProperties), std::end(kVehicleProperties));
|
||||
}
|
||||
|
||||
std::vector<VehiclePropConfig> listProperties() override { return mConfigs; }
|
||||
|
||||
VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
|
||||
StatusCode* outStatus) override;
|
||||
|
||||
StatusCode set(const VehiclePropValue& propValue) override {
|
||||
if (toInt(VehicleProperty::MIRROR_FOLD) == propValue.prop &&
|
||||
mMirrorFoldAttemptsLeft-- > 0) {
|
||||
return StatusCode::TRY_AGAIN;
|
||||
}
|
||||
|
||||
mValues[makeKey(propValue)] = propValue;
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
StatusCode subscribe(int32_t /* property */, float /* sampleRate */) override {
|
||||
return StatusCode::OK;
|
||||
}
|
||||
|
||||
StatusCode unsubscribe(int32_t /* property */) override { return StatusCode::OK; }
|
||||
|
||||
void sendPropEvent(recyclable_ptr<VehiclePropValue> value) { doHalEvent(std::move(value)); }
|
||||
|
||||
void sendHalError(StatusCode error, int32_t property, int32_t areaId) {
|
||||
doHalPropertySetError(error, property, areaId);
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t makeKey(const VehiclePropValue& v) const { return makeKey(v.prop, v.areaId); }
|
||||
|
||||
int64_t makeKey(int32_t prop, int32_t area) const {
|
||||
return (static_cast<int64_t>(prop) << 32) | area;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<VehiclePropConfig> mConfigs;
|
||||
std::unordered_map<int64_t, VehiclePropValue> mValues;
|
||||
int mFuelCapacityAttemptsLeft;
|
||||
int mMirrorFoldAttemptsLeft;
|
||||
};
|
||||
|
||||
class VehicleHalManagerFuzzer {
|
||||
public:
|
||||
VehicleHalManagerFuzzer() {
|
||||
mHal.reset(new MockedVehicleHal);
|
||||
mManager.reset(new VehicleHalManager(mHal.get()));
|
||||
mObjectPool = mHal->getValuePool();
|
||||
}
|
||||
~VehicleHalManagerFuzzer() {
|
||||
mManager.reset(nullptr);
|
||||
mHal.reset(nullptr);
|
||||
mObjectPool = nullptr;
|
||||
if (mFuzzedDataProvider) {
|
||||
delete mFuzzedDataProvider;
|
||||
}
|
||||
}
|
||||
void process(const uint8_t* data, size_t size);
|
||||
|
||||
private:
|
||||
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
|
||||
VehiclePropValue mActualValue = VehiclePropValue{};
|
||||
StatusCode mActualStatusCode = StatusCode::OK;
|
||||
|
||||
VehiclePropValuePool* mObjectPool = nullptr;
|
||||
std::unique_ptr<MockedVehicleHal> mHal;
|
||||
std::unique_ptr<VehicleHalManager> mManager;
|
||||
|
||||
void invokeDebug();
|
||||
void invokePropConfigs();
|
||||
void invokeSubscribe();
|
||||
void invokeSetAndGetValues();
|
||||
void invokeObd2SensorStore();
|
||||
void invokeVmsUtils();
|
||||
void invokeVehiclePropStore();
|
||||
void invokeWatchDogClient();
|
||||
void invokeGetSubscribedLayers(VmsMessageType type);
|
||||
void invokeGet(int32_t property, int32_t areaId);
|
||||
};
|
||||
|
||||
} // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
|
||||
|
||||
#endif // __VEHICLE_MANAGER_FUZZER_H__
|
||||
Reference in New Issue
Block a user