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