Merge "Refactored vehicleManager_fuzzer" into main am: 3db45f8509
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2769161 Change-Id: If5cc1fe6e378291a37a63131597c3353b857be04 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
1daa555faf
2 changed files with 355 additions and 226 deletions
|
@ -76,30 +76,20 @@ 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};
|
||||
std::string kCarMake;
|
||||
constexpr int32_t kMaxCaseMessage = 8;
|
||||
constexpr int32_t kMaxRuns = 20;
|
||||
constexpr int32_t kMaxSize = 1000;
|
||||
constexpr int32_t kMinSize = 0;
|
||||
constexpr int32_t kMaxFileSize = 100;
|
||||
float kFloatValue;
|
||||
std::vector<int32_t> kVec32;
|
||||
std::vector<int64_t> kVec64;
|
||||
std::vector<uint8_t> kVec8;
|
||||
std::vector<float> kVecFloat;
|
||||
static const std::vector<std::string> kSampleDtcs = {"P0070",
|
||||
"P0102"
|
||||
"P0123"};
|
||||
|
||||
MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
|
||||
const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
|
||||
|
@ -113,23 +103,23 @@ MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
|
|||
|
||||
switch (property) {
|
||||
case VehicleProperty::INFO_MAKE:
|
||||
pValue = getValuePool()->obtainString(kCarMake);
|
||||
pValue = getValuePool()->obtainString(kCarMake.c_str());
|
||||
break;
|
||||
case VehicleProperty::INFO_FUEL_CAPACITY:
|
||||
if (mFuelCapacityAttemptsLeft-- > 0) {
|
||||
*outStatus = StatusCode::TRY_AGAIN;
|
||||
} else {
|
||||
pValue = getValuePool()->obtainFloat(42.42);
|
||||
pValue = getValuePool()->obtainFloat(kFloatValue);
|
||||
}
|
||||
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;
|
||||
pValue->value.int32Values = hidl_vec<int32_t>{kVec32};
|
||||
pValue->value.int64Values = hidl_vec<int64_t>{kVec64};
|
||||
pValue->value.floatValues = hidl_vec<float_t>{kVecFloat};
|
||||
pValue->value.bytes = hidl_vec<uint8_t>{kVec8};
|
||||
pValue->value.stringValue = kCarMake.c_str();
|
||||
break;
|
||||
}
|
||||
auto key = makeKey(toInt(property), areaId);
|
||||
|
@ -145,28 +135,72 @@ MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
|
|||
return pValue;
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::initValue() {
|
||||
kCarMake = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
|
||||
kFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
|
||||
fillParameter<int32_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
|
||||
kVec32);
|
||||
fillParameter<int64_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
|
||||
kVec64);
|
||||
fillParameter<uint8_t>(mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize),
|
||||
kVec8);
|
||||
size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
kVecFloat.push_back(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
|
||||
mFuzzedDataProvider = new FuzzedDataProvider(data, size);
|
||||
invokeDebug();
|
||||
invokePropConfigs();
|
||||
invokeSubscribe();
|
||||
invokeSetAndGetValues();
|
||||
invokeObd2SensorStore();
|
||||
invokeVmsUtils();
|
||||
invokeVehiclePropStore();
|
||||
invokeWatchDogClient();
|
||||
initValue();
|
||||
/* Limited while loop runs to prevent timeouts caused
|
||||
* by repeated calls to high-execution-time APIs.
|
||||
*/
|
||||
size_t maxRuns = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxRuns);
|
||||
size_t itr = 0;
|
||||
while (mFuzzedDataProvider->remaining_bytes() && ++itr <= maxRuns) {
|
||||
auto invokeVehicleHalManagerFuzzer =
|
||||
mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() { invokeDebug(); },
|
||||
[&]() { invokePropConfigs(); },
|
||||
[&]() { invokeSubscribe(); },
|
||||
[&]() { invokeSetAndGetValues(); },
|
||||
[&]() { invokeObd2SensorStore(); },
|
||||
[&]() { invokeVmsUtils(); },
|
||||
[&]() { invokeVehiclePropStore(); },
|
||||
[&]() { invokeWatchDogClient(); },
|
||||
});
|
||||
invokeVehicleHalManagerFuzzer();
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeDebug() {
|
||||
hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
|
||||
{"--help", "--list", "--get", "--set", "", "invalid"});
|
||||
hidl_handle fd = {};
|
||||
|
||||
native_handle_t* rawHandle = native_handle_create(/*numFds=*/1, /*numInts=*/0);
|
||||
fd.setTo(native_handle_clone(rawHandle), /*shouldOwn=*/true);
|
||||
int32_t size = mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxFileSize);
|
||||
hidl_vec<hidl_string> options(size);
|
||||
|
||||
mManager->debug(fd, {});
|
||||
mManager->debug(fd, {debugOption});
|
||||
for (int32_t idx = 0; idx < size; ++idx) {
|
||||
if (idx == 0 && mFuzzedDataProvider->ConsumeBool()) {
|
||||
options[idx] = mFuzzedDataProvider->PickValueInArray(
|
||||
{"--help", "--list", "--get", "--set", "", "invalid"});
|
||||
} else if (idx == 2 && mFuzzedDataProvider->ConsumeBool()) {
|
||||
options[idx] =
|
||||
mFuzzedDataProvider->PickValueInArray({"-i", "-i64", "-f", "-s", "-b", "-a"});
|
||||
} else if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
options[idx] = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxSize);
|
||||
} else {
|
||||
options[idx] = std::to_string(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
}
|
||||
}
|
||||
|
||||
if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
mManager->debug(fd, {});
|
||||
} else {
|
||||
mManager->debug(fd, options);
|
||||
}
|
||||
native_handle_delete(rawHandle);
|
||||
}
|
||||
|
||||
|
@ -175,178 +209,245 @@ void VehicleHalManagerFuzzer::invokePropConfigs() {
|
|||
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
|
||||
hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
|
||||
auto invokePropConfigsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
mManager->getPropConfigs(
|
||||
properties, []([[maybe_unused]] StatusCode status,
|
||||
[[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
|
||||
},
|
||||
[&]() {
|
||||
mManager->getPropConfigs(
|
||||
{mFuzzedDataProvider->ConsumeIntegral<int32_t>()},
|
||||
[]([[maybe_unused]] StatusCode status,
|
||||
[[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
|
||||
},
|
||||
[&]() {
|
||||
mManager->getAllPropConfigs(
|
||||
[]([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
|
||||
},
|
||||
|
||||
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) {});
|
||||
});
|
||||
invokePropConfigsAPI();
|
||||
}
|
||||
|
||||
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();
|
||||
VehiclePropertyType type =
|
||||
static_cast<VehiclePropertyType>(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
|
||||
hidl_vec<SubscribeOptions> options = {
|
||||
SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
|
||||
auto invokeSubscribeAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
size_t size =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
|
||||
hidl_vec<SubscribeOptions> options(size);
|
||||
for (size_t idx = 0; idx < size; ++idx) {
|
||||
options[idx] = {SubscribeOptions{
|
||||
.propId = mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
.flags = static_cast<SubscribeFlags>(
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>())}};
|
||||
}
|
||||
mManager->subscribe(cb, options);
|
||||
},
|
||||
[&]() {
|
||||
auto unsubscribedValue = mObjectPool->obtain(type);
|
||||
if (!unsubscribedValue) {
|
||||
return;
|
||||
}
|
||||
unsubscribedValue->prop = vehicleProp2;
|
||||
unsubscribedValue->value.int32Values[0] = INT32_MAX;
|
||||
mHal->sendPropEvent(std::move(unsubscribedValue));
|
||||
cb->waitForExpectedEvents(mFuzzedDataProvider->ConsumeIntegral<size_t>());
|
||||
},
|
||||
[&]() {
|
||||
const auto prop1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
mManager->unsubscribe(cb, prop1);
|
||||
},
|
||||
[&]() {
|
||||
mHal->sendHalError(StatusCode::TRY_AGAIN, vehicleProp3,
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>() /*areaId=*/);
|
||||
},
|
||||
|
||||
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);
|
||||
});
|
||||
invokeSubscribeAPI();
|
||||
}
|
||||
|
||||
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());
|
||||
auto invokeSetAndGetAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
invokeGet(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
},
|
||||
[&]() { mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>()); },
|
||||
[&]() { mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>()); },
|
||||
[&]() { mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool()); },
|
||||
[&]() {
|
||||
int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
auto expectedValue =
|
||||
mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
expectedValue->prop = vehicleProp2;
|
||||
expectedValue->areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
mManager->set(*expectedValue.get());
|
||||
},
|
||||
});
|
||||
invokeSetAndGetAPI();
|
||||
}
|
||||
|
||||
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>();
|
||||
size_t diagnosticInt = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
|
||||
size_t diagnosticFloat =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
|
||||
|
||||
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);
|
||||
}
|
||||
new Obd2SensorStore(diagnosticInt, diagnosticFloat));
|
||||
|
||||
if (!sensorStore.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto invokeObd2SensorStoreAPI =
|
||||
mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() {
|
||||
int32_t diagnosticIntValue =
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
int32_t diagnosticIntIndex =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
|
||||
kMinSize,
|
||||
toInt(DiagnosticIntegerSensorIndex::LAST_SYSTEM_INDEX) +
|
||||
diagnosticInt);
|
||||
sensorStore->setIntegerSensor(
|
||||
static_cast<DiagnosticIntegerSensorIndex>(diagnosticIntIndex),
|
||||
diagnosticIntValue);
|
||||
},
|
||||
[&]() {
|
||||
float diagnosticFloatValue =
|
||||
mFuzzedDataProvider->ConsumeFloatingPoint<float>();
|
||||
int32_t diagnosticFloatIndex =
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
|
||||
kMinSize,
|
||||
toInt(DiagnosticFloatSensorIndex::LAST_SYSTEM_INDEX) +
|
||||
diagnosticFloat);
|
||||
sensorStore->setFloatSensor(
|
||||
static_cast<DiagnosticFloatSensorIndex>(diagnosticFloatIndex),
|
||||
diagnosticFloatValue);
|
||||
},
|
||||
[&]() { sensorStore->getIntegerSensors(); },
|
||||
[&]() { sensorStore->getFloatSensors(); },
|
||||
[&]() { sensorStore->getSensorsBitmask(); },
|
||||
[&]() {
|
||||
for (auto&& dtc : kSampleDtcs) {
|
||||
VehiclePropertyType type = static_cast<VehiclePropertyType>(
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
auto freezeFrame = createVehiclePropValue(
|
||||
type, mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(
|
||||
kMinSize, kMaxSize));
|
||||
if (!freezeFrame.get()) {
|
||||
return;
|
||||
}
|
||||
freezeFrame->prop = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
sensorStore->fillPropValue(dtc, freezeFrame.get());
|
||||
}
|
||||
},
|
||||
});
|
||||
invokeObd2SensorStoreAPI();
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeVmsUtils() {
|
||||
bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
|
||||
bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
|
||||
std::unique_ptr<VehiclePropValue> message;
|
||||
int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
VmsLayer layer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
VmsOffers offers = {
|
||||
intValue,
|
||||
{VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
|
||||
const VmsLayerAndPublisher layer_and_publisher(
|
||||
VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>()),
|
||||
intValue);
|
||||
|
||||
switch (mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxCaseMessage)) {
|
||||
case 0: {
|
||||
message = createSubscribeMessage(layer);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
message = createUnsubscribeMessage(layer);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
message = createSubscriptionsRequest();
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
message = createOfferingMessage(offers);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
message = createAvailabilityRequest();
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
std::string pub_bytes;
|
||||
if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
pub_bytes = "pub_id";
|
||||
} else {
|
||||
pub_bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
|
||||
}
|
||||
message = createPublisherIdRequest(pub_bytes);
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
std::string bytes = "placeholder";
|
||||
if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
bytes = "placeholder";
|
||||
} else {
|
||||
bytes = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxFileSize);
|
||||
}
|
||||
message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
message = createBaseVmsMessage(
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize));
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
message = createStartSessionMessage(intValue, intValue + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
hidl_vec<int32_t>{mFuzzedDataProvider->ConsumeIntegral<int32_t>(), intValue};
|
||||
|
||||
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);
|
||||
auto invokeVmsUtilsAPI = mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() { parseData(*message); },
|
||||
[&]() { createSubscribeToPublisherMessage(layer_and_publisher); },
|
||||
[&]() { createUnsubscribeToPublisherMessage(layer_and_publisher); },
|
||||
[&]() { parsePublisherIdResponse(*message); },
|
||||
[&]() { getSequenceNumberForSubscriptionsState(*message); },
|
||||
[&]() { isSequenceNumberNewer(*message, intValue + 1); },
|
||||
[&]() {
|
||||
invokeGetSubscribedLayers(
|
||||
(VmsMessageType)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
},
|
||||
[&]() { hasServiceNewlyStarted(*message); },
|
||||
[&]() { parseMessageType(*message); },
|
||||
[&]() { isAvailabilitySequenceNumberNewer(*message, intValue + 1); },
|
||||
[&]() { getSequenceNumberForAvailabilityState(*message); },
|
||||
[&]() {
|
||||
int32_t new_service_id;
|
||||
parseStartSessionMessage(*message, -1, 0, &new_service_id);
|
||||
},
|
||||
});
|
||||
invokeVmsUtilsAPI();
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
|
||||
|
@ -367,27 +468,31 @@ void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
|
|||
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::invokeGetSubscribedLayers(VmsMessageType /*type*/) {
|
||||
int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
VmsOffers offers = {
|
||||
intValue,
|
||||
{VmsLayerOffering(VmsLayer(mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>()))}};
|
||||
auto message = createBaseVmsMessage(
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxFileSize));
|
||||
std::vector<int32_t> v;
|
||||
size_t size = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(kMinSize, kMaxSize);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
v.push_back(mFuzzedDataProvider->ConsumeIntegralInRange<int32_t>(kMinSize, kMaxSize));
|
||||
}
|
||||
|
||||
message->value.int32Values = hidl_vec<int32_t>(v);
|
||||
if (!isValidVmsMessage(*message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
getSubscribedLayers(*message, offers);
|
||||
} else {
|
||||
getAvailableLayers(*message);
|
||||
}
|
||||
}
|
||||
|
||||
void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
|
||||
|
@ -398,33 +503,49 @@ void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
|
|||
.prop = vehicleProp,
|
||||
.access = VehiclePropertyAccess::READ,
|
||||
.changeMode = VehiclePropertyChangeMode::STATIC,
|
||||
.areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
|
||||
.areaConfigs = {VehicleAreaConfig{
|
||||
.areaId = (mFuzzedDataProvider->ConsumeIntegral<int32_t>())}},
|
||||
};
|
||||
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);
|
||||
propValue.areaId = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
|
||||
|
||||
auto invokeVehiclePropStoreAPI =
|
||||
mFuzzedDataProvider->PickValueInArray<const std::function<void()>>({
|
||||
[&]() { store->registerProperty(config); },
|
||||
[&]() { store->writeValue(propValue, shouldWriteStatus); },
|
||||
[&]() { store->readAllValues(); },
|
||||
[&]() { store->getAllConfigs(); },
|
||||
[&]() { store->getConfigOrNull(vehicleProp); },
|
||||
[&]() { store->readValuesForProperty(vehicleProp); },
|
||||
[&]() { store->readValueOrNull(propValue); },
|
||||
[&]() {
|
||||
store->readValueOrNull(propValue.prop, propValue.areaId,
|
||||
mFuzzedDataProvider->ConsumeIntegralInRange<int64_t>(
|
||||
kMinSize, kMaxFileSize));
|
||||
},
|
||||
[&]() { store->removeValuesForProperty(vehicleProp); },
|
||||
[&]() { store->removeValue(propValue); },
|
||||
[&]() {
|
||||
if (store->getConfigOrNull(vehicleProp)) {
|
||||
store->getConfigOrDie(vehicleProp);
|
||||
}
|
||||
},
|
||||
});
|
||||
invokeVehiclePropStoreAPI();
|
||||
}
|
||||
|
||||
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);
|
||||
if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, mManager.get());
|
||||
watchdogClient->initialize()) {
|
||||
watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
|
||||
if (mFuzzedDataProvider->ConsumeBool()) {
|
||||
watchdogClient->checkIfAlive(
|
||||
mFuzzedDataProvider->ConsumeIntegral<int32_t>(),
|
||||
(TimeoutLength)mFuzzedDataProvider->ConsumeIntegral<int32_t>());
|
||||
}
|
||||
watchdogClient->prepareProcessTermination();
|
||||
}
|
||||
delete service;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
|
|
|
@ -98,6 +98,13 @@ class VehicleHalManagerFuzzer {
|
|||
}
|
||||
void process(const uint8_t* data, size_t size);
|
||||
|
||||
template <typename T>
|
||||
void fillParameter(size_t size, std::vector<T>& data) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
data.push_back(mFuzzedDataProvider->ConsumeIntegral<T>());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
|
||||
VehiclePropValue mActualValue = VehiclePropValue{};
|
||||
|
@ -108,6 +115,7 @@ class VehicleHalManagerFuzzer {
|
|||
std::unique_ptr<VehicleHalManager> mManager;
|
||||
|
||||
void invokeDebug();
|
||||
void initValue();
|
||||
void invokePropConfigs();
|
||||
void invokeSubscribe();
|
||||
void invokeSetAndGetValues();
|
||||
|
|
Loading…
Reference in a new issue