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/functional/bind.h>
18 #include <bluetooth/log.h>
19 #include <fuzzer/FuzzedDataProvider.h>
20
21 #include <cstdint>
22 #include <functional>
23 #include <vector>
24
25 #include "osi/include/allocator.h"
26 #include "stack/include/avct_api.h"
27 #include "stack/include/avrc_api.h"
28 #include "stack/include/bt_psm_types.h"
29 #include "test/fake/fake_osi.h"
30 #include "test/mock/mock_btif_config.h"
31 #include "test/mock/mock_stack_acl.h"
32 #include "test/mock/mock_stack_btm_dev.h"
33 #include "test/mock/mock_stack_l2cap_api.h"
34 #include "types/bluetooth/uuid.h"
35
36 using bluetooth::Uuid;
37 using namespace bluetooth;
38
39 // Verify the passed data is readable
ConsumeData(const uint8_t * data,size_t size)40 static void ConsumeData(const uint8_t* data, size_t size) {
41 volatile uint8_t checksum = 0;
42 for (size_t i = 0; i < size; i++) {
43 checksum ^= data[i];
44 }
45 }
46
47 namespace {
48
49 constexpr uint16_t kDummyCid = 0x1234;
50 constexpr uint8_t kDummyId = 0x77;
51 constexpr uint8_t kDummyRemoteAddr[] = {0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC};
52
53 // Set up default callback structure
54 static tL2CAP_APPL_INFO avct_appl, avct_br_appl;
55
56 class FakeBtStack {
57 public:
FakeBtStack()58 FakeBtStack() {
59 test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t cid, BT_HDR* hdr) {
60 log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid");
61 ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len);
62 osi_free(hdr);
63 return tL2CAP_DW_RESULT::SUCCESS;
64 };
65 test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) {
66 log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid");
67 return true;
68 };
69 test::mock::stack_l2cap_api::L2CA_ConnectReqWithSecurity.body =
70 [](uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) {
71 log::assert_that(p_bd_addr == kDummyRemoteAddr,
72 "assert failed: p_bd_addr == kDummyRemoteAddr");
73 return kDummyCid;
74 };
75 test::mock::stack_l2cap_api::L2CA_RegisterWithSecurity.body =
76 [](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop,
77 tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, uint16_t required_remote_mtu,
78 uint16_t sec_level) {
79 log::assert_that(psm == BT_PSM_AVCTP || psm == BT_PSM_AVCTP_BROWSE,
80 "assert failed: psm == BT_PSM_AVCTP || psm == BT_PSM_AVCTP_BROWSE");
81 if (psm == BT_PSM_AVDTP) {
82 avct_appl = p_cb_info;
83 } else if (psm == BT_PSM_AVCTP_BROWSE) {
84 avct_br_appl = p_cb_info;
85 }
86 return psm;
87 };
88 test::mock::stack_l2cap_api::L2CA_Deregister.body = [](uint16_t psm) {};
89 }
90
~FakeBtStack()91 ~FakeBtStack() {
92 test::mock::stack_l2cap_api::L2CA_DataWrite = {};
93 test::mock::stack_l2cap_api::L2CA_ConnectReqWithSecurity = {};
94 test::mock::stack_l2cap_api::L2CA_DisconnectReq = {};
95 test::mock::stack_l2cap_api::L2CA_RegisterWithSecurity = {};
96 test::mock::stack_l2cap_api::L2CA_Deregister = {};
97 }
98 };
99
100 class Fakes {
101 public:
102 test::fake::FakeOsi fake_osi;
103 FakeBtStack fake_stack;
104 };
105
106 } // namespace
107
108 #ifdef __ANDROID__
109 namespace android {
110 namespace sysprop {
111 namespace bluetooth {
112 namespace Avrcp {
absolute_volume()113 std::optional<bool> absolute_volume() { return true; }
114 } // namespace Avrcp
115
116 namespace Bta {
disable_delay()117 std::optional<std::int32_t> disable_delay() { return 200; }
118 } // namespace Bta
119
120 namespace Pan {
nap()121 std::optional<bool> nap() { return false; }
122 } // namespace Pan
123 } // namespace bluetooth
124 } // namespace sysprop
125 } // namespace android
126 #endif
127
ctrl_cb(uint8_t handle,uint8_t event,uint16_t result,const RawAddress * peer_addr)128 static void ctrl_cb(uint8_t handle, uint8_t event, uint16_t result, const RawAddress* peer_addr) {}
129
msg_cb(uint8_t handle,uint8_t label,uint8_t opcode,tAVRC_MSG * p_msg)130 static void msg_cb(uint8_t handle, uint8_t label, uint8_t opcode, tAVRC_MSG* p_msg) {
131 uint8_t scratch_buf[512];
132 tAVRC_STS status;
133
134 if (p_msg->hdr.ctype == AVCT_CMD) {
135 tAVRC_COMMAND cmd = {0};
136 memset(scratch_buf, 0, sizeof(scratch_buf));
137 status = AVRC_ParsCommand(p_msg, &cmd, scratch_buf, sizeof(scratch_buf));
138 if (status == AVRC_STS_NO_ERROR) {
139 BT_HDR* p_pkt = (BT_HDR*)nullptr;
140 status = AVRC_BldCommand(&cmd, &p_pkt);
141 if (status == AVRC_STS_NO_ERROR && p_pkt) {
142 osi_free(p_pkt);
143 }
144 }
145 } else if (p_msg->hdr.ctype == AVCT_RSP) {
146 tAVRC_RESPONSE rsp = {0};
147 memset(scratch_buf, 0, sizeof(scratch_buf));
148 status = AVRC_ParsResponse(p_msg, &rsp, scratch_buf, sizeof(scratch_buf));
149 if (status == AVRC_STS_NO_ERROR) {
150 BT_HDR* p_pkt = (BT_HDR*)nullptr;
151 status = AVRC_BldResponse(handle, &rsp, &p_pkt);
152 if (status == AVRC_STS_NO_ERROR && p_pkt) {
153 osi_free(p_pkt);
154 }
155 }
156
157 uint16_t buf_len = sizeof(scratch_buf);
158 memset(scratch_buf, 0, sizeof(scratch_buf));
159 status = AVRC_Ctrl_ParsResponse(p_msg, &rsp, scratch_buf, &buf_len);
160 if (status == AVRC_STS_NO_ERROR) {
161 BT_HDR* p_pkt = (BT_HDR*)nullptr;
162 status = AVRC_BldResponse(handle, &rsp, &p_pkt);
163 if (status == AVRC_STS_NO_ERROR && p_pkt) {
164 osi_free(p_pkt);
165 }
166 }
167 }
168 }
169
Fuzz(const uint8_t * data,size_t size)170 static void Fuzz(const uint8_t* data, size_t size) {
171 FuzzedDataProvider fdp(data, size);
172 bool is_initiator = fdp.ConsumeBool();
173 bool is_controller = fdp.ConsumeBool();
174 bool is_br = fdp.ConsumeBool();
175
176 AVCT_Register();
177 AVRC_Init();
178
179 tL2CAP_APPL_INFO* appl_info = is_br ? &avct_br_appl : &avct_appl;
180
181 tAVRC_CONN_CB ccb = {
182 .ctrl_cback = base::Bind(ctrl_cb),
183 .msg_cback = base::Bind(msg_cb),
184 .conn = (is_initiator ? AVCT_ROLE_INITIATOR : AVCT_ROLE_ACCEPTOR),
185 .control = (uint8_t)(is_controller ? AVCT_CONTROL : AVCT_TARGET),
186 };
187
188 appl_info->pL2CA_ConnectInd_Cb(kDummyRemoteAddr, kDummyCid, 0, kDummyId);
189
190 uint8_t handle;
191 if (AVCT_SUCCESS != AVRC_Open(&handle, &ccb, kDummyRemoteAddr)) {
192 return;
193 }
194
195 tL2CAP_CFG_INFO cfg;
196 appl_info->pL2CA_ConfigCfm_Cb(kDummyCid, is_initiator, &cfg);
197
198 // Feeding input packets
199 constexpr uint16_t kMaxPacketSize = 1024;
200 while (fdp.remaining_bytes() > 0) {
201 auto size = fdp.ConsumeIntegralInRange<uint16_t>(0, kMaxPacketSize);
202 auto bytes = fdp.ConsumeBytes<uint8_t>(size);
203 BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size());
204 hdr->len = bytes.size();
205 std::copy(bytes.cbegin(), bytes.cend(), hdr->data);
206 appl_info->pL2CA_DataInd_Cb(kDummyCid, hdr);
207 }
208
209 AVRC_Close(handle);
210
211 // Simulating disconnecting event
212 appl_info->pL2CA_DisconnectInd_Cb(kDummyCid, false);
213
214 AVCT_Deregister();
215 }
216
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)217 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
218 auto fakes = std::make_unique<Fakes>();
219 Fuzz(Data, Size);
220 return 0;
221 }
222