Merge "Added automotiveCanV1.0_fuzzer" am: 20b69d76d0

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1991533

Change-Id: Iccc4e6a9349cc2fc865dfdbd608462673318e964
This commit is contained in:
Cory Barker 2022-03-02 18:46:12 +00:00 committed by Automerger Merge Worker
commit 96c8da665f
4 changed files with 396 additions and 7 deletions

View file

@ -46,13 +46,7 @@ cc_binary {
vendor: true,
relative_install_path: "hw",
srcs: [
"CanBus.cpp",
"CanBusNative.cpp",
"CanBusVirtual.cpp",
"CanBusSlcan.cpp",
"CanController.cpp",
"CanSocket.cpp",
"CloseHandle.cpp",
":automotiveCanV1.0_sources",
"service.cpp",
],
shared_libs: [
@ -66,3 +60,22 @@ cc_binary {
],
vintf_fragments: ["manifest_android.hardware.automotive.can@1.0.xml"],
}
filegroup {
name: "automotiveCanV1.0_sources",
srcs: [
"CanBus.cpp",
"CanBusNative.cpp",
"CanBusVirtual.cpp",
"CanBusSlcan.cpp",
"CanController.cpp",
"CanSocket.cpp",
"CloseHandle.cpp",
],
}
cc_library_headers {
name: "automotiveCanV1.0_headers",
vendor: true,
export_include_dirs: ["."],
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2022 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.
*
*/
cc_fuzz {
name: "automotiveCanV1.0_fuzzer",
vendor: true,
defaults: ["android.hardware.automotive.can@defaults"],
srcs: [
"AutomotiveCanV1_0Fuzzer.cpp",
":automotiveCanV1.0_sources",
],
header_libs: [
"automotiveCanV1.0_headers",
"android.hardware.automotive.can@hidl-utils-lib",
],
shared_libs: [
"android.hardware.automotive.can@1.0",
"libhidlbase",
],
static_libs: [
"android.hardware.automotive.can@libnetdevice",
"android.hardware.automotive@libc++fs",
"libnl++",
],
fuzz_config: {
cc: [
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
},
}

View file

@ -0,0 +1,202 @@
/*
* Copyright (C) 2022 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.
*
*/
#include "AutomotiveCanV1_0Fuzzer.h"
namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
constexpr CanController::InterfaceType kInterfaceType[] = {CanController::InterfaceType::VIRTUAL,
CanController::InterfaceType::SOCKETCAN,
CanController::InterfaceType::SLCAN};
constexpr FilterFlag kFilterFlag[] = {FilterFlag::DONT_CARE, FilterFlag::SET, FilterFlag::NOT_SET};
constexpr size_t kInterfaceTypeLength = std::size(kInterfaceType);
constexpr size_t kFilterFlagLength = std::size(kFilterFlag);
constexpr size_t kMaxCharacters = 30;
constexpr size_t kMaxPayloadBytes = 64;
constexpr size_t kMaxFilters = 20;
constexpr size_t kMaxSerialNumber = 1000;
constexpr size_t kMaxBuses = 10;
constexpr size_t kMaxRepeat = 5;
Bus CanFuzzer::makeBus() {
ICanController::BusConfig config = {};
if (mBusNames.size() > 0 && mLastInterface < mBusNames.size()) {
config.name = mBusNames[mLastInterface++];
} else {
config.name = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
}
config.interfaceId.virtualif({mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters)});
return Bus(mCanController, config);
}
void CanFuzzer::getSupportedInterfaceTypes() {
hidl_vec<CanController::InterfaceType> iftypesResult;
mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&iftypesResult));
}
hidl_vec<hidl_string> CanFuzzer::getBusNames() {
hidl_vec<hidl_string> services = {};
if (auto manager = hidl::manager::V1_2::IServiceManager::getService(); manager) {
manager->listManifestByInterface(ICanBus::descriptor, hidl_utils::fill(&services));
}
return services;
}
void CanFuzzer::invokeUpInterface() {
const CanController::InterfaceType iftype =
kInterfaceType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kInterfaceTypeLength - 1)];
std::string configName;
if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
(shouldInvokeValidBus) && (mBusNames.size() > 0)) {
const size_t busNameIndex =
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
configName = mBusNames[busNameIndex];
} else {
configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
}
const std::string ifname = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
ICanController::BusConfig config = {.name = configName};
if (iftype == CanController::InterfaceType::SOCKETCAN) {
CanController::BusConfig::InterfaceId::Socketcan socketcan = {};
if (const bool shouldPassSerialSocket = mFuzzedDataProvider->ConsumeBool();
shouldPassSerialSocket) {
socketcan.serialno(
{mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
} else {
socketcan.ifname(ifname);
}
config.interfaceId.socketcan(socketcan);
} else if (iftype == CanController::InterfaceType::SLCAN) {
CanController::BusConfig::InterfaceId::Slcan slcan = {};
if (const bool shouldPassSerialSlcan = mFuzzedDataProvider->ConsumeBool();
shouldPassSerialSlcan) {
slcan.serialno(
{mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
} else {
slcan.ttyname(ifname);
}
config.interfaceId.slcan(slcan);
} else if (iftype == CanController::InterfaceType::VIRTUAL) {
config.interfaceId.virtualif({ifname});
}
const size_t numInvocations =
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
for (size_t i = 0; i < numInvocations; ++i) {
mCanController->upInterface(config);
}
}
void CanFuzzer::invokeDownInterface() {
hidl_string configName;
if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
(shouldInvokeValidBus) && (mBusNames.size() > 0)) {
const size_t busNameIndex =
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
configName = mBusNames[busNameIndex];
} else {
configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
}
const size_t numInvocations =
mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
for (size_t i = 0; i < numInvocations; ++i) {
mCanController->downInterface(configName);
}
}
void CanFuzzer::invokeController() {
getSupportedInterfaceTypes();
invokeUpInterface();
invokeDownInterface();
}
void CanFuzzer::invokeBus() {
const size_t numBuses = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxBuses);
for (size_t i = 0; i < numBuses; ++i) {
if (const bool shouldSendMessage = mFuzzedDataProvider->ConsumeBool(); shouldSendMessage) {
auto sendingBus = makeBus();
CanMessage msg = {.id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>()};
uint32_t numPayloadBytes =
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxPayloadBytes);
hidl_vec<uint8_t> payload(numPayloadBytes);
for (uint32_t j = 0; j < numPayloadBytes; ++j) {
payload[j] = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
}
msg.payload = payload;
msg.remoteTransmissionRequest = mFuzzedDataProvider->ConsumeBool();
msg.isExtendedId = mFuzzedDataProvider->ConsumeBool();
sendingBus.send(msg);
} else {
auto listeningBus = makeBus();
uint32_t numFilters =
mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxFilters);
hidl_vec<CanMessageFilter> filterVector(numFilters);
for (uint32_t k = 0; k < numFilters; ++k) {
filterVector[k].id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
filterVector[k].mask = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
filterVector[k].rtr =
kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kFilterFlagLength - 1)];
filterVector[k].extendedFormat =
kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
0, kFilterFlagLength - 1)];
filterVector[k].exclude = mFuzzedDataProvider->ConsumeBool();
}
auto listener = listeningBus.listen(filterVector);
}
}
}
void CanFuzzer::deInit() {
mCanController.clear();
if (mFuzzedDataProvider) {
delete mFuzzedDataProvider;
}
mBusNames = {};
}
void CanFuzzer::process(const uint8_t* data, size_t size) {
mFuzzedDataProvider = new FuzzedDataProvider(data, size);
invokeController();
invokeBus();
}
bool CanFuzzer::init() {
mCanController = sp<CanController>::make();
if (!mCanController) {
return false;
}
mBusNames = getBusNames();
return true;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) {
return 0;
}
CanFuzzer canFuzzer;
if (canFuzzer.init()) {
canFuzzer.process(data, size);
}
return 0;
}
} // namespace android::hardware::automotive::can::V1_0::implementation::fuzzer

View file

@ -0,0 +1,129 @@
/*
* Copyright (C) 2022 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.
*
*/
#ifndef __AUTOMOTIVE_CAN_V1_0_FUZZER_H__
#define __AUTOMOTIVE_CAN_V1_0_FUZZER_H__
#include <CanController.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <hidl-utils/hidl-utils.h>
namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
using ::android::sp;
struct CanMessageListener : public can::V1_0::ICanMessageListener {
DISALLOW_COPY_AND_ASSIGN(CanMessageListener);
CanMessageListener() {}
virtual Return<void> onReceive(const can::V1_0::CanMessage& msg) override {
std::unique_lock<std::mutex> lock(mMessagesGuard);
mMessages.push_back(msg);
mMessagesUpdated.notify_one();
return {};
}
virtual ~CanMessageListener() {
if (mCloseHandle) {
mCloseHandle->close();
}
}
void assignCloseHandle(sp<ICloseHandle> closeHandle) { mCloseHandle = closeHandle; }
private:
sp<ICloseHandle> mCloseHandle;
std::mutex mMessagesGuard;
std::condition_variable mMessagesUpdated GUARDED_BY(mMessagesGuard);
std::vector<can::V1_0::CanMessage> mMessages GUARDED_BY(mMessagesGuard);
};
struct Bus {
DISALLOW_COPY_AND_ASSIGN(Bus);
Bus(sp<ICanController> controller, const ICanController::BusConfig& config)
: mIfname(config.name), mController(controller) {
const auto result = controller->upInterface(config);
const auto manager = hidl::manager::V1_2::IServiceManager::getService();
const auto service = manager->get(ICanBus::descriptor, config.name);
mBus = ICanBus::castFrom(service);
}
virtual ~Bus() { reset(); }
void reset() {
mBus.clear();
if (mController) {
mController->downInterface(mIfname);
mController.clear();
}
}
ICanBus* operator->() const { return mBus.get(); }
sp<ICanBus> get() { return mBus; }
sp<CanMessageListener> listen(const hidl_vec<CanMessageFilter>& filter) {
sp<CanMessageListener> listener = sp<CanMessageListener>::make();
if (!mBus) {
return listener;
}
Result result;
sp<ICloseHandle> closeHandle;
mBus->listen(filter, listener, hidl_utils::fill(&result, &closeHandle)).assertOk();
listener->assignCloseHandle(closeHandle);
return listener;
}
void send(const CanMessage& msg) {
if (!mBus) {
return;
}
mBus->send(msg);
}
private:
const std::string mIfname;
sp<ICanController> mController;
sp<ICanBus> mBus;
};
class CanFuzzer {
public:
~CanFuzzer() { deInit(); }
bool init();
void process(const uint8_t* data, size_t size);
void deInit();
private:
Bus makeBus();
hidl_vec<hidl_string> getBusNames();
void getSupportedInterfaceTypes();
void invokeBus();
void invokeController();
void invokeUpInterface();
void invokeDownInterface();
FuzzedDataProvider* mFuzzedDataProvider = nullptr;
sp<CanController> mCanController = nullptr;
hidl_vec<hidl_string> mBusNames = {};
unsigned mLastInterface = 0;
};
} // namespace android::hardware::automotive::can::V1_0::implementation::fuzzer
#endif // __AUTOMOTIVE_CAN_V1_0_FUZZER_H__