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:
Treehugger Robot 2023-11-17 09:45:01 +00:00 committed by Automerger Merge Worker
commit 1daa555faf
2 changed files with 355 additions and 226 deletions

View file

@ -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) {

View file

@ -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();