1 /*
2  * Copyright 2022 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 <base/location.h>
18 #include <bluetooth/log.h>
19 #include <fuzzer/FuzzedDataProvider.h>
20 #include <gmock/gmock.h>
21 
22 #include <cstdint>
23 #include <string>
24 #include <vector>
25 
26 #include "btif/include/stack_manager_t.h"
27 #include "common/message_loop_thread.h"
28 #include "hal/snoop_logger.h"
29 #include "hci/controller_interface_mock.h"
30 #include "osi/include/allocator.h"
31 #include "stack/btm/btm_int_types.h"
32 #include "stack/include/bt_psm_types.h"
33 #include "stack/include/l2c_api.h"
34 #include "stack/include/l2cap_acl_interface.h"
35 #include "stack/include/l2cap_controller_interface.h"
36 #include "stack/include/l2cap_hci_link_interface.h"
37 #include "stack/include/l2cdefs.h"
38 #include "test/fake/fake_osi.h"
39 #include "test/mock/mock_main_shim_entry.h"
40 #include "test/mock/mock_stack_acl.h"
41 #include "test/mock/mock_stack_btm_devctl.h"
42 
43 using bluetooth::Uuid;
44 using testing::Return;
45 using namespace bluetooth;
46 
47 // Verify the passed data is readable
ConsumeData(const uint8_t * data,size_t size)48 static void ConsumeData(const uint8_t* data, size_t size) {
49   volatile uint8_t checksum = 0;
50   for (size_t i = 0; i < size; i++) {
51     checksum ^= data[i];
52   }
53 }
54 
55 tBTM_CB btm_cb;
56 
do_in_main_thread(base::Location const &,base::OnceCallback<void ()>)57 bt_status_t do_in_main_thread(base::Location const&,
58                               base::OnceCallback<void()>) {
59   // this is not properly mocked, so we use abort to catch if this is used in
60   // any test cases
61   abort();
62 }
do_in_main_thread_delayed(base::Location const &,base::OnceCallback<void ()>,std::chrono::microseconds)63 bt_status_t do_in_main_thread_delayed(base::Location const&,
64                                       base::OnceCallback<void()>,
65                                       std::chrono::microseconds) {
66   // this is not properly mocked, so we use abort to catch if this is used in
67   // any test cases
68   abort();
69 }
get_main_thread()70 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
71 
72 namespace bluetooth {
73 namespace os {
GetSystemPropertyUint32Base(const std::string & property,uint32_t default_value,int base)74 uint32_t GetSystemPropertyUint32Base(const std::string& property,
75                                      uint32_t default_value, int base) {
76   return default_value;
77 }
78 }  // namespace os
79 
80 namespace hal {
81 class SnoopLogger;
82 
83 const std::string SnoopLogger::kBtSnoopLogModeFiltered = "filtered";
84 
GetBtSnoopMode()85 std::string SnoopLogger::GetBtSnoopMode() { return "filtered"; }
AcceptlistL2capChannel(uint16_t,uint16_t,uint16_t)86 void SnoopLogger::AcceptlistL2capChannel(uint16_t, uint16_t, uint16_t) {}
AddA2dpMediaChannel(uint16_t,uint16_t,uint16_t)87 void SnoopLogger::AddA2dpMediaChannel(uint16_t, uint16_t, uint16_t) {}
AddRfcommL2capChannel(uint16_t,uint16_t,uint16_t)88 void SnoopLogger::AddRfcommL2capChannel(uint16_t, uint16_t, uint16_t) {}
ClearL2capAcceptlist(uint16_t,uint16_t,uint16_t)89 void SnoopLogger::ClearL2capAcceptlist(uint16_t, uint16_t, uint16_t) {}
RemoveA2dpMediaChannel(uint16_t,uint16_t)90 void SnoopLogger::RemoveA2dpMediaChannel(uint16_t, uint16_t) {}
SetL2capChannelClose(uint16_t,uint16_t,uint16_t)91 void SnoopLogger::SetL2capChannelClose(uint16_t, uint16_t, uint16_t) {}
SetL2capChannelOpen(uint16_t,uint16_t,uint16_t,uint16_t,bool)92 void SnoopLogger::SetL2capChannelOpen(uint16_t, uint16_t, uint16_t, uint16_t,
93                                       bool) {}
94 }  // namespace hal
95 }  // namespace bluetooth
96 
97 namespace {
98 
99 class FakeBtStack {
100  public:
FakeBtStack()101   FakeBtStack() {
102     test::mock::stack_btm_devctl::BTM_IsDeviceUp.body = []() { return true; };
103     test::mock::stack_acl::acl_create_le_connection.body =
104         [](const RawAddress& bd_addr) { return true; };
105     test::mock::stack_acl::acl_send_data_packet_br_edr.body =
106         [](const RawAddress& bd_addr, BT_HDR* hdr) {
107           ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len);
108           osi_free(hdr);
109         };
110     test::mock::stack_acl::acl_send_data_packet_ble.body =
111         [](const RawAddress& bd_addr, BT_HDR* hdr) {
112           ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len);
113           osi_free(hdr);
114         };
115 
116     GetInterfaceToProfiles()->profileSpecific_HACK->GetHearingAidDeviceCount =
117         []() { return 1; };
118 
119     ON_CALL(controller_, GetLeSuggestedDefaultDataLength)
120         .WillByDefault(Return(512));
121     bluetooth::hci::LeBufferSize iso_size;
122     iso_size.le_data_packet_length_ = 512;
123     iso_size.total_num_le_packets_ = 6;
124     ON_CALL(controller_, GetControllerIsoBufferSize)
125         .WillByDefault(Return(iso_size));
126     bluetooth::hci::LeBufferSize le_size;
127     le_size.le_data_packet_length_ = 512;
128     le_size.total_num_le_packets_ = 6;
129     ON_CALL(controller_, GetLeBufferSize).WillByDefault(Return(le_size));
130     ON_CALL(controller_, SupportsBle).WillByDefault(Return(true));
131     ON_CALL(controller_, GetAclPacketLength).WillByDefault(Return(512));
132     bluetooth::hci::testing::mock_controller_ = &controller_;
133   }
134 
~FakeBtStack()135   ~FakeBtStack() {
136     test::mock::stack_btm_devctl::BTM_IsDeviceUp = {};
137     test::mock::stack_acl::acl_create_le_connection = {};
138     test::mock::stack_acl::acl_send_data_packet_br_edr = {};
139     test::mock::stack_acl::acl_send_data_packet_ble = {};
140     bluetooth::hci::testing::mock_controller_ = nullptr;
141   }
142   bluetooth::hci::testing::MockControllerInterface controller_;
143 };
144 
145 class Fakes {
146  public:
147   test::fake::FakeOsi fake_osi;
148   FakeBtStack fake_stack;
149 };
150 
151 }  // namespace
152 
153 constexpr uint8_t kAttAddr[] = {0x11, 0x78, 0x78, 0x78, 0x78, 0x78};
154 constexpr uint16_t kAttHndl = 0x0111;
155 
156 constexpr uint8_t kEattAddr[] = {0x22, 0x78, 0x78, 0x78, 0x78, 0x78};
157 
158 constexpr uint8_t kSmpBrAddr[] = {0x33, 0x78, 0x78, 0x78, 0x78, 0x78};
159 constexpr uint16_t kSmpBrHndl = 0x0222;
160 
161 constexpr uint16_t kNumClassicAclBuffer = 100;
162 constexpr uint16_t kNumLeAclBuffer = 100;
163 
164 void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle,
165                             const RawAddress& p_bda);
166 
Fuzz(const uint8_t * data,size_t size)167 static void Fuzz(const uint8_t* data, size_t size) {
168   memset(&btm_cb, 0, sizeof(btm_cb));
169 
170   l2c_init();
171 
172   l2c_link_init(kNumClassicAclBuffer);
173   l2c_link_processs_ble_num_bufs(kNumLeAclBuffer);
174 
175   tL2CAP_FIXED_CHNL_REG reg = {
176       .pL2CA_FixedConn_Cb = [](uint16_t, const RawAddress&, bool, uint16_t,
177                                tBT_TRANSPORT) {},
178       .pL2CA_FixedData_Cb =
179           [](uint16_t, const RawAddress&, BT_HDR* hdr) {
180             ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len);
181           },
182       .pL2CA_FixedCong_Cb = [](const RawAddress&, bool) {},
183       .default_idle_tout = 1000,
184   };
185 
186   tL2CAP_APPL_INFO appl_info = {
187       .pL2CA_ConnectInd_Cb = [](const RawAddress&, uint16_t, uint16_t,
188                                 uint8_t) {},
189       .pL2CA_ConnectCfm_Cb = [](uint16_t, uint16_t) {},
190       .pL2CA_ConfigInd_Cb = [](uint16_t, tL2CAP_CFG_INFO*) {},
191       .pL2CA_ConfigCfm_Cb = [](uint16_t, uint16_t, tL2CAP_CFG_INFO*) {},
192       .pL2CA_DisconnectInd_Cb = [](uint16_t, bool) {},
193       .pL2CA_DisconnectCfm_Cb = [](uint16_t, uint16_t) {},
194       .pL2CA_DataInd_Cb =
195           [](uint16_t, BT_HDR* hdr) {
196             ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len);
197           },
198       .pL2CA_CongestionStatus_Cb = [](uint16_t, bool) {},
199       .pL2CA_TxComplete_Cb = [](uint16_t, uint16_t) {},
200       .pL2CA_Error_Cb = [](uint16_t, uint16_t) {},
201       .pL2CA_CreditBasedConnectInd_Cb = [](const RawAddress&,
202                                            std::vector<uint16_t>&, uint16_t,
203                                            uint16_t, uint8_t) {},
204       .pL2CA_CreditBasedConnectCfm_Cb = [](const RawAddress&, uint16_t,
205                                            uint16_t, uint16_t) {},
206       .pL2CA_CreditBasedReconfigCompleted_Cb = [](const RawAddress&, uint16_t,
207                                                   bool, tL2CAP_LE_CFG_INFO*) {},
208       .pL2CA_CreditBasedCollisionInd_Cb = [](const RawAddress&) {},
209   };
210   log::assert_that(
211       L2CA_RegisterWithSecurity(BT_PSM_ATT, appl_info, false, nullptr,
212                                 L2CAP_MTU_SIZE, 0, BTM_SEC_NONE),
213       "assert failed: L2CA_RegisterWithSecurity(BT_PSM_ATT, appl_info, "
214       "false, nullptr, L2CAP_MTU_SIZE, 0, BTM_SEC_NONE)");
215   log::assert_that(L2CA_RegisterLECoc(BT_PSM_EATT, appl_info, BTM_SEC_NONE, {}),
216                    "assert failed: L2CA_RegisterLECoc(BT_PSM_EATT, appl_info, "
217                    "BTM_SEC_NONE, {{}})");
218 
219   log::assert_that(
220       L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &reg),
221       "assert failed: L2CA_RegisterFixedChannel(L2CAP_ATT_CID, &reg)");
222   log::assert_that(
223       L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr),
224       "assert failed: L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr)");
225   log::assert_that(
226       l2cble_conn_comp(kAttHndl, HCI_ROLE_CENTRAL, kAttAddr, BLE_ADDR_PUBLIC,
227                        100, 100, 100),
228       "assert failed: l2cble_conn_comp(kAttHndl, HCI_ROLE_CENTRAL, kAttAddr, "
229       "BLE_ADDR_PUBLIC, 100, 100, 100)");
230 
231   log::assert_that(
232       L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &reg),
233       "assert failed: L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, &reg)");
234   log::assert_that(
235       L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr),
236       "assert failed: L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr)");
237   l2c_link_hci_conn_comp(HCI_SUCCESS, kSmpBrHndl, kSmpBrAddr);
238 
239   auto att_cid = L2CA_ConnectReq(BT_PSM_ATT, kAttAddr);
240   log::assert_that(att_cid != 0, "assert failed: att_cid != 0");
241 
242   tL2CAP_LE_CFG_INFO cfg;
243   auto eatt_cid = L2CA_ConnectLECocReq(BT_PSM_EATT, kEattAddr, &cfg, 0);
244   log::assert_that(eatt_cid != 0, "assert failed: eatt_cid != 0");
245 
246   FuzzedDataProvider fdp(data, size);
247 
248   // Feeding input packets
249   constexpr uint16_t kMinPacketSize = 4 + L2CAP_PKT_OVERHEAD;
250   constexpr uint16_t kMaxPacketSize = 1024;
251   for (;;) {
252     auto size =
253         fdp.ConsumeIntegralInRange<uint16_t>(kMinPacketSize, kMaxPacketSize);
254     auto bytes = fdp.ConsumeBytes<uint8_t>(size);
255     if (bytes.size() < kMinPacketSize) {
256       break;
257     }
258 
259     BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size());
260     hdr->len = bytes.size();
261     std::copy(bytes.cbegin(), bytes.cend(), hdr->data);
262     l2c_rcv_acl_data(hdr);
263   }
264 
265   (void)L2CA_DisconnectReq(att_cid);
266   (void)L2CA_DisconnectLECocReq(eatt_cid);
267 
268   (void)L2CA_RemoveFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr);
269   l2c_link_hci_disc_comp(kSmpBrHndl, HCI_SUCCESS);
270 
271   (void)L2CA_RemoveFixedChnl(L2CAP_ATT_CID, kAttAddr);
272   l2c_link_hci_disc_comp(kAttHndl, HCI_SUCCESS);
273 
274   l2cu_device_reset();
275   l2c_free();
276 }
277 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)278 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
279   auto fakes = std::make_unique<Fakes>();
280   Fuzz(Data, Size);
281   return 0;
282 }
283