xref: /aosp_15_r20/hardware/interfaces/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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     for (size_t i = 0; i < mFdCount; ++i) {
92       if (mFdList[i]) {
93         close(mFdList[i]);
94       }
95     }
96   }
97   bool init(const uint8_t* data, size_t size);
98   void process();
99 
100  private:
101   size_t mFdCount = 1;
102   int32_t mFdList[CH_MAX] = {0};
103   sp<BluetoothHci> mBtHci = nullptr;
104   FuzzedDataProvider* mFdp = nullptr;
105 };
106 
init(const uint8_t * data,size_t size)107 bool BluetoothFuzzer::init(const uint8_t* data, size_t size) {
108   mBtHci = sp<BluetoothHci>::make();
109   if (!mBtHci) {
110     return false;
111   }
112   mFdp = new FuzzedDataProvider(data, size);
113   return true;
114 }
115 
process()116 void BluetoothFuzzer::process() {
117   sp<BluetoothHciCallbacks> bluetoothCallback =
118       sp<BluetoothHciCallbacks>::make();
119 
120   uint8_t btAddress[BluetoothAddress::kBytes];
121   mFdp->ConsumeData(btAddress, sizeof(uint8_t) * BluetoothAddress::kBytes);
122 
123   char btAddrString[BluetoothAddress::kStringLength + 1];
124   BluetoothAddress::bytes_to_string(btAddress, btAddrString);
125 
126   /* property_set() is called so that BluetoothAddress::get_local_address()
127    * could return true and the LOG_ALWAYS_FATAL() that aborts the run, if
128    * BluetoothAddress::get_local_address() returns false, could be avoided.
129    *
130    * BluetoothAddress::get_local_address() first searches if
131    * PROPERTY_BT_BDADDR_PATH is set, if it fails to get PROPERTY_BT_BDADDR_PATH,
132    * it searches for FACTORY_BDADDR_PROPERTY. If it fails to get
133    * FACTORY_BDADDR_PROPERTY, it then searches for PERSIST_BDADDR_PROPERTY. If
134    * PERSIST_BDADDR_PROPERTY is also not set, it results in an abort.
135    */
136   property_set(PERSIST_BDADDR_PROPERTY, btAddrString);
137 
138   if (mFdp->ConsumeBool()) {
139     property_set(FACTORY_BDADDR_PROPERTY, btAddrString);
140   }
141 
142   if (mFdp->ConsumeBool()) {
143     char property[PROPERTY_VALUE_MAX] = {0};
144     property_get("ro.vendor.bt.bdaddr_path", property, NULL);
145     // get the value of ro.vendor.bt.bdaddr_path and set it to
146     // PROPERTY_BT_BDADDR_PATH
147     property_set(PROPERTY_BT_BDADDR_PATH, property);
148   }
149 
150   bool shouldSetH4Protocol = mFdp->ConsumeBool();
151   BtVendor* btVendor = BtVendor::getInstance();
152 
153   if (!shouldSetH4Protocol) {
154     mFdCount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
155   }
156 
157   for (size_t i = 0; i < mFdCount; ++i) {
158     mFdList[i] = open("/dev/null", O_RDWR | O_CREAT);
159   }
160 
161   btVendor->populateFdList(mFdList, mFdCount);
162   mBtHci->initialize(bluetoothCallback);
163 
164   if (!bluetoothCallback->isInitialized) {
165     return;
166   }
167 
168   std::vector<uint8_t> hciPacket, aclPacket;
169 
170   size_t hciPacketSize =
171       mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
172   hciPacket = mFdp->ConsumeBytes<uint8_t>(hciPacketSize);
173   mBtHci->sendHciCommand(toHidlVec(hciPacket));
174 
175   size_t aclPacketSize =
176       mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
177   aclPacket = mFdp->ConsumeBytes<uint8_t>(aclPacketSize);
178   mBtHci->sendAclData(toHidlVec(aclPacket));
179 
180   if (shouldSetH4Protocol) {
181     std::vector<uint8_t> scoPacket;
182     size_t scoPacketSize =
183         mFdp->ConsumeIntegralInRange<size_t>(0, kMaxPacketSize);
184     scoPacket = mFdp->ConsumeBytes<uint8_t>(scoPacketSize);
185     mBtHci->sendScoData(toHidlVec(scoPacket));
186   }
187 
188   btVendor->callRemainingCbacks();
189 }
190 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)191 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
192   BluetoothFuzzer bluetoothFuzzer;
193   if (bluetoothFuzzer.init(data, size)) {
194     bluetoothFuzzer.process();
195   }
196   return 0;
197 }
198