1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 #include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
18 #include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
19 #include <bluetooth_address.h>
20 #include <bluetooth_hci.h>
21 #include <cutils/properties.h>
22 #include <fuzzer/FuzzedDataProvider.h>
23 #include <log/log.h>
24
25 #include "bt_vendor.h"
26
27 using namespace std;
28 using ::android::sp;
29 using ::android::hardware::hidl_vec;
30 using ::android::hardware::Return;
31 using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
32 using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
33 using ::android::hardware::bluetooth::V1_0::Status;
34 using ::android::hardware::bluetooth::V1_0::implementation::BluetoothAddress;
35 using ::android::hardware::bluetooth::V1_0::implementation::BluetoothHci;
36 using ::android::hardware::bluetooth::V1_0::implementation::
37 FACTORY_BDADDR_PROPERTY;
38 using ::android::hardware::bluetooth::V1_0::implementation::
39 PERSIST_BDADDR_PROPERTY;
40 using ::android::hardware::bluetooth::V1_0::implementation::
41 PROPERTY_BT_BDADDR_PATH;
42
43 constexpr size_t kMaxPacketSize = 100;
44 constexpr size_t kMinFdcount = 2;
45
46 template <typename T>
toHidlVec(const std::vector<T> & vec)47 const hidl_vec<T> toHidlVec(const std::vector<T>& vec) {
48 hidl_vec<T> hVec;
49 hVec.setToExternal(const_cast<T*>(vec.data()), vec.size());
50 return hVec;
51 }
52
53 class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
54 public:
55 virtual ~BluetoothHciCallbacks() = default;
56
initializationComplete(Status status)57 Return<void> initializationComplete(Status status) override {
58 if (status == Status::SUCCESS) {
59 isInitialized = true;
60 } else {
61 isInitialized = false;
62 }
63 return Return<void>();
64 };
65
hciEventReceived(const::android::hardware::hidl_vec<uint8_t> &)66 Return<void> hciEventReceived(
67 const ::android::hardware::hidl_vec<uint8_t>& /*event*/) override {
68 return Return<void>();
69 };
70
aclDataReceived(const::android::hardware::hidl_vec<uint8_t> &)71 Return<void> aclDataReceived(
72 const ::android::hardware::hidl_vec<uint8_t>& /*data*/) override {
73 return Return<void>();
74 };
75
scoDataReceived(const::android::hardware::hidl_vec<uint8_t> &)76 Return<void> scoDataReceived(
77 const ::android::hardware::hidl_vec<uint8_t>& /*data*/) override {
78 return Return<void>();
79 };
80 bool isInitialized;
81 };
82
83 class BluetoothFuzzer {
84 public:
~BluetoothFuzzer()85 ~BluetoothFuzzer() {
86 if (mFdp) {
87 delete mFdp;
88 }
89 mBtHci->close();
90 mBtHci.clear();
91 }
92 bool init(const uint8_t* data, size_t size);
93 void process();
94
95 private:
96 sp<BluetoothHci> mBtHci = nullptr;
97 FuzzedDataProvider* mFdp = nullptr;
98 };
99
init(const uint8_t * data,size_t size)100 bool BluetoothFuzzer::init(const uint8_t* data, size_t size) {
101 mBtHci = sp<BluetoothHci>::make();
102 if (!mBtHci) {
103 return false;
104 }
105 mFdp = new FuzzedDataProvider(data, size);
106 return true;
107 }
108
process()109 void BluetoothFuzzer::process() {
110 sp<BluetoothHciCallbacks> bluetoothCallback =
111 sp<BluetoothHciCallbacks>::make();
112
113 uint8_t btAddress[BluetoothAddress::kBytes];
114 mFdp->ConsumeData(btAddress, sizeof(uint8_t) * BluetoothAddress::kBytes);
115
116 char btAddrString[BluetoothAddress::kStringLength + 1];
117 BluetoothAddress::bytes_to_string(btAddress, btAddrString);
118
119 /* property_set() is called so that BluetoothAddress::get_local_address()
120 * could return true and the LOG_ALWAYS_FATAL() that aborts the run, if
121 * BluetoothAddress::get_local_address() returns false, could be avoided.
122 *
123 * BluetoothAddress::get_local_address() first searches if
124 * PROPERTY_BT_BDADDR_PATH is set, if it fails to get PROPERTY_BT_BDADDR_PATH,
125 * it searches for FACTORY_BDADDR_PROPERTY. If it fails to get
126 * FACTORY_BDADDR_PROPERTY, it then searches for PERSIST_BDADDR_PROPERTY. If
127 * PERSIST_BDADDR_PROPERTY is also not set, it results in an abort.
128 */
129 property_set(PERSIST_BDADDR_PROPERTY, btAddrString);
130
131 if (mFdp->ConsumeBool()) {
132 property_set(FACTORY_BDADDR_PROPERTY, btAddrString);
133 }
134
135 if (mFdp->ConsumeBool()) {
136 char property[PROPERTY_VALUE_MAX] = {0};
137 property_get("ro.vendor.bt.bdaddr_path", property, NULL);
138 // get the value of ro.vendor.bt.bdaddr_path and set it to
139 // PROPERTY_BT_BDADDR_PATH
140 property_set(PROPERTY_BT_BDADDR_PATH, property);
141 }
142
143 bool shouldSetH4Protocol = mFdp->ConsumeBool();
144 BtVendor* btVendor = BtVendor::getInstance();
145
146 size_t fdcount = 1;
147 int32_t fdList[CH_MAX] = {0};
148 if (!shouldSetH4Protocol) {
149 fdcount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
150 }
151
152 for (size_t i = 0; i < fdcount; ++i) {
153 fdList[i] = open("/dev/null", O_RDWR | O_CREAT);
154 }
155
156 btVendor->populateFdList(fdList, fdcount);
157 mBtHci->initialize(bluetoothCallback);
158
159 if (!bluetoothCallback->isInitialized) {
160 return;
161 }
162
163 std::vector<uint8_t> hciPacket, aclPacket;
164
165 size_t hciPacketSize =
166 mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
167 hciPacket = mFdp->ConsumeBytes<uint8_t>(hciPacketSize);
168 mBtHci->sendHciCommand(toHidlVec(hciPacket));
169
170 size_t aclPacketSize =
171 mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
172 aclPacket = mFdp->ConsumeBytes<uint8_t>(aclPacketSize);
173 mBtHci->sendAclData(toHidlVec(aclPacket));
174
175 if (shouldSetH4Protocol) {
176 std::vector<uint8_t> scoPacket;
177 size_t scoPacketSize =
178 mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
179 scoPacket = mFdp->ConsumeBytes<uint8_t>(scoPacketSize);
180 mBtHci->sendScoData(toHidlVec(scoPacket));
181 }
182
183 btVendor->callRemainingCbacks();
184
185 for (size_t i = 0; i < fdcount; ++i) {
186 if (fdList[i]) {
187 close(fdList[i]);
188 }
189 }
190 }
191
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)192 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
193 BluetoothFuzzer bluetoothFuzzer;
194 if (bluetoothFuzzer.init(data, size)) {
195 bluetoothFuzzer.process();
196 }
197 return 0;
198 }
199