android13/hardware/interfaces/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp

199 lines
6.0 KiB
C++

/*
* 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.
*
*/
#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
#include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
#include <bluetooth_address.h>
#include <bluetooth_hci.h>
#include <cutils/properties.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <log/log.h>
#include "bt_vendor.h"
using namespace std;
using ::android::sp;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
using ::android::hardware::bluetooth::V1_0::Status;
using ::android::hardware::bluetooth::V1_0::implementation::BluetoothAddress;
using ::android::hardware::bluetooth::V1_0::implementation::BluetoothHci;
using ::android::hardware::bluetooth::V1_0::implementation::
FACTORY_BDADDR_PROPERTY;
using ::android::hardware::bluetooth::V1_0::implementation::
PERSIST_BDADDR_PROPERTY;
using ::android::hardware::bluetooth::V1_0::implementation::
PROPERTY_BT_BDADDR_PATH;
constexpr size_t kMaxPacketSize = 100;
constexpr size_t kMinFdcount = 2;
template <typename T>
const hidl_vec<T> toHidlVec(const std::vector<T>& vec) {
hidl_vec<T> hVec;
hVec.setToExternal(const_cast<T*>(vec.data()), vec.size());
return hVec;
}
class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
public:
virtual ~BluetoothHciCallbacks() = default;
Return<void> initializationComplete(Status status) override {
if (status == Status::SUCCESS) {
isInitialized = true;
} else {
isInitialized = false;
}
return Return<void>();
};
Return<void> hciEventReceived(
const ::android::hardware::hidl_vec<uint8_t>& /*event*/) override {
return Return<void>();
};
Return<void> aclDataReceived(
const ::android::hardware::hidl_vec<uint8_t>& /*data*/) override {
return Return<void>();
};
Return<void> scoDataReceived(
const ::android::hardware::hidl_vec<uint8_t>& /*data*/) override {
return Return<void>();
};
bool isInitialized;
};
class BluetoothFuzzer {
public:
~BluetoothFuzzer() {
if (mFdp) {
delete mFdp;
}
mBtHci->close();
mBtHci.clear();
}
bool init(const uint8_t* data, size_t size);
void process();
private:
sp<BluetoothHci> mBtHci = nullptr;
FuzzedDataProvider* mFdp = nullptr;
};
bool BluetoothFuzzer::init(const uint8_t* data, size_t size) {
mBtHci = sp<BluetoothHci>::make();
if (!mBtHci) {
return false;
}
mFdp = new FuzzedDataProvider(data, size);
return true;
}
void BluetoothFuzzer::process() {
sp<BluetoothHciCallbacks> bluetoothCallback =
sp<BluetoothHciCallbacks>::make();
uint8_t btAddress[BluetoothAddress::kBytes];
mFdp->ConsumeData(btAddress, sizeof(uint8_t) * BluetoothAddress::kBytes);
char btAddrString[BluetoothAddress::kStringLength + 1];
BluetoothAddress::bytes_to_string(btAddress, btAddrString);
/* property_set() is called so that BluetoothAddress::get_local_address()
* could return true and the LOG_ALWAYS_FATAL() that aborts the run, if
* BluetoothAddress::get_local_address() returns false, could be avoided.
*
* BluetoothAddress::get_local_address() first searches if
* PROPERTY_BT_BDADDR_PATH is set, if it fails to get PROPERTY_BT_BDADDR_PATH,
* it searches for FACTORY_BDADDR_PROPERTY. If it fails to get
* FACTORY_BDADDR_PROPERTY, it then searches for PERSIST_BDADDR_PROPERTY. If
* PERSIST_BDADDR_PROPERTY is also not set, it results in an abort.
*/
property_set(PERSIST_BDADDR_PROPERTY, btAddrString);
if (mFdp->ConsumeBool()) {
property_set(FACTORY_BDADDR_PROPERTY, btAddrString);
}
if (mFdp->ConsumeBool()) {
char property[PROPERTY_VALUE_MAX] = {0};
property_get("ro.vendor.bt.bdaddr_path", property, NULL);
// get the value of ro.vendor.bt.bdaddr_path and set it to
// PROPERTY_BT_BDADDR_PATH
property_set(PROPERTY_BT_BDADDR_PATH, property);
}
bool shouldSetH4Protocol = mFdp->ConsumeBool();
BtVendor* btVendor = BtVendor::getInstance();
size_t fdcount = 1;
int32_t fdList[CH_MAX] = {0};
if (!shouldSetH4Protocol) {
fdcount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
}
for (size_t i = 0; i < fdcount; ++i) {
fdList[i] = open("/dev/null", O_RDWR | O_CREAT);
}
btVendor->populateFdList(fdList, fdcount);
mBtHci->initialize(bluetoothCallback);
if (!bluetoothCallback->isInitialized) {
return;
}
std::vector<uint8_t> hciPacket, aclPacket;
size_t hciPacketSize =
mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
hciPacket = mFdp->ConsumeBytes<uint8_t>(hciPacketSize);
mBtHci->sendHciCommand(toHidlVec(hciPacket));
size_t aclPacketSize =
mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
aclPacket = mFdp->ConsumeBytes<uint8_t>(aclPacketSize);
mBtHci->sendAclData(toHidlVec(aclPacket));
if (shouldSetH4Protocol) {
std::vector<uint8_t> scoPacket;
size_t scoPacketSize =
mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
scoPacket = mFdp->ConsumeBytes<uint8_t>(scoPacketSize);
mBtHci->sendScoData(toHidlVec(scoPacket));
}
btVendor->callRemainingCbacks();
for (size_t i = 0; i < fdcount; ++i) {
if (fdList[i]) {
close(fdList[i]);
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
BluetoothFuzzer bluetoothFuzzer;
if (bluetoothFuzzer.init(data, size)) {
bluetoothFuzzer.process();
}
return 0;
}