1 /*
2  * Copyright 2020 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 #ifndef FUZZER_SDP_FUNCTIONS_H_
18 #define FUZZER_SDP_FUNCTIONS_H_
19 
20 #include <base/functional/bind.h>
21 #include <fuzzer/FuzzedDataProvider.h>
22 
23 #include <vector>
24 
25 #include "fuzzers/common/commonFuzzHelpers.h"
26 #include "fuzzers/sdp/sdpFuzzHelpers.h"
27 #include "stack/include/sdp_api.h"
28 #include "types/bluetooth/uuid.h"
29 #include "types/raw_address.h"
30 
31 #define SDP_MAX_DB_LEN 1024 * 1024  // 1 MB
32 #define MAX_NUM_DBS 64
33 
34 /* This is a vector of lambda functions the fuzzer will pull from.
35  *  This is done so new functions can be added to the fuzzer easily
36  *  without requiring modifications to the main fuzzer file. This also
37  *  allows multiple fuzzers to include this file, if functionality is needed.
38  */
39 static const std::vector<std::function<void(FuzzedDataProvider*)>>
40     sdp_operations = {
41         // ::SDP_InitDiscoveryDb
42         [](FuzzedDataProvider* fdp) -> void {
43           if (sdp_db_vect.size() >= MAX_NUM_DBS) {
44             return;
45           }
46 
47           // build out uuid_list
48           std::vector<bluetooth::Uuid> uuid_list;
49           uint8_t num_uuids = fdp->ConsumeIntegral<uint8_t>();
50           for (uint8_t i = 0; i < num_uuids; i++) {
51             uuid_list.push_back(generateArbitraryUuid(fdp));
52           }
53 
54           // build out attr_list
55           std::vector<uint16_t> attr_list = generateArbitraryAttrList(fdp);
56 
57           uint32_t db_size =
58               fdp->ConsumeIntegralInRange<uint32_t>(0, SDP_MAX_DB_LEN);
59           std::shared_ptr<tSDP_DISCOVERY_DB> p_db(
60               reinterpret_cast<tSDP_DISCOVERY_DB*>(malloc(db_size)), free);
61           if (p_db) {
62             bool success =
63                 get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
64                     p_db.get(), db_size, uuid_list.size(), uuid_list.data(),
65                     attr_list.size(),
66                     reinterpret_cast<uint16_t*>(attr_list.data()));
67             if (success) {
68               sdp_db_vect.push_back(p_db);
69             }
70           }
71         },
72 
73         // ::SDP_CancelServiceSearch
74         [](FuzzedDataProvider* fdp) -> void {
75           [[maybe_unused]] bool rc =
76               get_legacy_stack_sdp_api()->service.SDP_CancelServiceSearch(
77                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
78         },
79 
80         // ::SDP_ServiceSearchRequest
81         [](FuzzedDataProvider* fdp) -> void {
82           const RawAddress bd_addr = generateRawAddress(fdp);
83           tSDP_DISCOVERY_DB* db =
84               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
85           if (db) {
86             [[maybe_unused]] bool rc =
87                 get_legacy_stack_sdp_api()->service.SDP_ServiceSearchRequest(
88                     bd_addr, db, &sdp_disc_cmpl_cb);
89           }
90         },
91 
92         // ::SDP_ServiceSearchAttributeRequest
93         [](FuzzedDataProvider* fdp) -> void {
94           const RawAddress bd_addr = generateRawAddress(fdp);
95           tSDP_DISCOVERY_DB* db =
96               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
97           if (db) {
98             [[maybe_unused]] bool rc =
99                 get_legacy_stack_sdp_api()
100                     ->service.SDP_ServiceSearchAttributeRequest(
101                         bd_addr, db, &sdp_disc_cmpl_cb);
102           }
103         },
104 
105         // ::SDP_ServiceSearchAttributeRequest2
106         [](FuzzedDataProvider* fdp) -> void {
107           const RawAddress bd_addr = generateRawAddress(fdp);
108           std::vector<uint8_t> user_data = fdp->ConsumeBytes<uint8_t>(
109               fdp->ConsumeIntegralInRange<size_t>(0, 1024));
110           tSDP_DISCOVERY_DB* db =
111               getArbitraryVectorElement(fdp, sdp_db_vect, false).get();
112 
113           if (db) {
114             [[maybe_unused]] bool rc =
115                 get_legacy_stack_sdp_api()
116                     ->service.SDP_ServiceSearchAttributeRequest2(
117                         bd_addr, db,
118                         base::BindRepeating(&sdp_disc_cmpl_cb2, user_data));
119           }
120         },
121 
122         // ::SDP_FindAttributeInRec
123         [](FuzzedDataProvider* fdp) -> void {
124           tSDP_DISC_REC* p_rec =
125               generateArbitrarySdpDiscRecord(fdp, false).get();
126           [[maybe_unused]] bool rc =
127               get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
128                   p_rec, fdp->ConsumeIntegral<uint16_t>());
129         },
130 
131         // ::SDP_FindServiceInDb
132         [](FuzzedDataProvider* fdp) -> void {
133           [[maybe_unused]] bool rc =
134               get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(
135                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get(),
136                   fdp->ConsumeIntegral<uint16_t>(),
137                   generateArbitrarySdpDiscRecord(fdp, true).get());
138         },
139 
140         // ::SDP_FindServiceUUIDInDb
141         [](FuzzedDataProvider* fdp) -> void {
142           const bluetooth::Uuid uuid = generateArbitraryUuid(fdp);
143           [[maybe_unused]] bool rc =
144               get_legacy_stack_sdp_api()->db.SDP_FindServiceUUIDInDb(
145                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get(), uuid,
146                   generateArbitrarySdpDiscRecord(fdp, true).get());
147         },
148 
149         // ::SDP_FindServiceUUIDInRec_128bit
150         [](FuzzedDataProvider* fdp) -> void {
151           bluetooth::Uuid uuid = generateArbitraryUuid(fdp);
152           tSDP_DISC_REC* p_rec =
153               generateArbitrarySdpDiscRecord(fdp, false).get();
154           [[maybe_unused]] bool rc =
155               get_legacy_stack_sdp_api()
156                   ->record.SDP_FindServiceUUIDInRec_128bit(p_rec, &uuid);
157         },
158 
159         // ::SDP_FindServiceInDb_128bit
160         [](FuzzedDataProvider* fdp) -> void {
161           [[maybe_unused]] bool rc =
162               get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb_128bit(
163                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get(),
164                   generateArbitrarySdpDiscRecord(fdp, true).get());
165         },
166 
167         // ::SDP_FindProtocolListElemInRec
168         [](FuzzedDataProvider* fdp) -> void {
169           tSDP_PROTOCOL_ELEM elem = generateArbitrarySdpProtocolElements(fdp);
170           tSDP_DISC_REC* p_rec =
171               generateArbitrarySdpDiscRecord(fdp, false).get();
172           [[maybe_unused]] bool rc =
173               get_legacy_stack_sdp_api()->record.SDP_FindProtocolListElemInRec(
174                   p_rec, fdp->ConsumeIntegral<uint16_t>(), &elem);
175         },
176 
177         // ::SDP_FindProfileVersionInRec
178         [](FuzzedDataProvider* fdp) -> void {
179           uint16_t p_version;
180           tSDP_DISC_REC* p_rec =
181               generateArbitrarySdpDiscRecord(fdp, false).get();
182 
183           [[maybe_unused]] bool rc =
184               get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
185                   p_rec, fdp->ConsumeIntegral<uint16_t>(), &p_version);
186         },
187 
188         // ::SDP_CreateRecord
189         [](FuzzedDataProvider* fdp) -> void {
190           uint32_t handle =
191               get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
192           if (handle) {
193             sdp_record_handles.push_back(handle);
194           }
195         },
196 
197         // ::SDP_DeleteRecord
198         [](FuzzedDataProvider* fdp) -> void {
199           [[maybe_unused]] bool rc =
200               get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(
201                   getArbitraryVectorElement(fdp, sdp_record_handles, true));
202         },
203 
204         // ::SDP_AddAttribute
205         [](FuzzedDataProvider* fdp) -> void {
206           std::vector<uint8_t> val = fdp->ConsumeBytes<uint8_t>(
207               fdp->ConsumeIntegralInRange<size_t>(1, 1024));
208           if (val.size() > 0) {
209             [[maybe_unused]] bool rc =
210                 get_legacy_stack_sdp_api()->handle.SDP_AddAttribute(
211                     getArbitraryVectorElement(fdp, sdp_record_handles, true),
212                     fdp->ConsumeIntegral<uint16_t>(),
213                     fdp->ConsumeIntegral<uint8_t>(), val.size(), val.data());
214           }
215         },
216 
217         // ::SDP_AddSequence
218         [](FuzzedDataProvider* fdp) -> void {
219           SDP_Sequence_Helper seq = generateArbitrarySdpElemSequence(fdp);
220 
221           [[maybe_unused]] bool rc =
222               get_legacy_stack_sdp_api()->handle.SDP_AddSequence(
223                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
224                   fdp->ConsumeIntegral<uint16_t>(), seq.num_elem,
225                   seq.type.get(), seq.len.get(), seq.p_val.get());
226         },
227 
228         // ::SDP_AddUuidSequence
229         [](FuzzedDataProvider* fdp) -> void {
230           uint16_t num_uuids = fdp->ConsumeIntegralInRange<uint16_t>(1, 64);
231           uint16_t* uuids = new uint16_t[num_uuids];
232           for (uint16_t i = 0; i < num_uuids; i++) {
233             uuids[i] = fdp->ConsumeIntegral<uint16_t>();
234           }
235 
236           [[maybe_unused]] bool rc =
237               get_legacy_stack_sdp_api()->handle.SDP_AddUuidSequence(
238                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
239                   fdp->ConsumeIntegral<uint16_t>(), num_uuids, uuids);
240           delete[] uuids;
241         },
242 
243         // ::SDP_AddProtocolList
244         [](FuzzedDataProvider* fdp) -> void {
245           std::shared_ptr<tSDP_PROTO_LIST_ELEM> p_proto_list =
246               generateArbitrarySdpProtocolElementList(fdp);
247           if (p_proto_list) {
248             [[maybe_unused]] bool rc =
249                 get_legacy_stack_sdp_api()->handle.SDP_AddProtocolList(
250                     getArbitraryVectorElement(fdp, sdp_record_handles, true),
251                     p_proto_list.get()->num_elems,
252                     p_proto_list.get()->list_elem);
253           }
254         },
255 
256         // ::SDP_AddAdditionProtoLists
257         [](FuzzedDataProvider* fdp) -> void {
258           uint16_t arr_size;
259           tSDP_PROTO_LIST_ELEM** p_proto_list =
260               generateArbitrarySdpProtocolElementListArray(fdp, &arr_size);
261           if (p_proto_list) {
262             if (p_proto_list[0]) {
263               [[maybe_unused]] bool rc =
264                   get_legacy_stack_sdp_api()->handle.SDP_AddAdditionProtoLists(
265                       getArbitraryVectorElement(fdp, sdp_record_handles, true),
266                       arr_size, p_proto_list[0]);
267               for (uint16_t i = 0; i < arr_size; i++) {
268                 delete p_proto_list[i];
269               }
270             }
271             free(p_proto_list);
272           }
273         },
274 
275         // ::SDP_AddProfileDescriptorList
276         [](FuzzedDataProvider* fdp) -> void {
277           [[maybe_unused]] bool rc =
278               get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
279                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
280                   fdp->ConsumeIntegral<uint16_t>(),
281                   fdp->ConsumeIntegral<uint16_t>());
282         },
283 
284         // ::SDP_AddLanguageBaseAttrIDList
285         [](FuzzedDataProvider* fdp) -> void {
286           [[maybe_unused]] bool rc =
287               get_legacy_stack_sdp_api()->handle.SDP_AddLanguageBaseAttrIDList(
288                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
289                   fdp->ConsumeIntegral<uint16_t>(),
290                   fdp->ConsumeIntegral<uint16_t>(),
291                   fdp->ConsumeIntegral<uint16_t>());
292         },
293 
294         // ::SDP_AddServiceClassIdList
295         [](FuzzedDataProvider* fdp) -> void {
296           uint16_t num_services = fdp->ConsumeIntegralInRange<uint16_t>(0, 64);
297           uint16_t* service_uuids = new uint16_t[num_services];
298           for (uint16_t i = 0; i < num_services; i++) {
299             service_uuids[i] = fdp->ConsumeIntegral<uint16_t>();
300           }
301 
302           [[maybe_unused]] bool rc =
303               get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
304                   getArbitraryVectorElement(fdp, sdp_record_handles, true),
305                   num_services, service_uuids);
306 
307           delete[] service_uuids;
308         },
309 
310         // ::SDP_SetLocalDiRecord
311         [](FuzzedDataProvider* fdp) -> void {
312           uint32_t handle;  // Output var
313           tSDP_DI_RECORD device_info = generateArbitrarySdpDiRecord(fdp);
314           [[maybe_unused]] bool rc =
315               get_legacy_stack_sdp_api()->device_id.SDP_SetLocalDiRecord(
316                   &device_info, &handle);
317         },
318 
319         // ::SDP_DiDiscover
320         [](FuzzedDataProvider* fdp) -> void {
321           const RawAddress remote_device = generateRawAddress(fdp);
322 
323           // Create a new buffer for the discoveryDB init call
324           uint32_t db_size =
325               fdp->ConsumeIntegralInRange<uint32_t>(0, SDP_MAX_DB_LEN);
326           std::shared_ptr<tSDP_DISCOVERY_DB> p_db(
327               reinterpret_cast<tSDP_DISCOVERY_DB*>(malloc(db_size)), free);
328           if (p_db) {
329             [[maybe_unused]] bool rc =
330                 get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
331                     remote_device, p_db.get(), db_size, &sdp_disc_cmpl_cb);
332           }
333         },
334 
335         // ::SDP_GetNumDiRecords
336         [](FuzzedDataProvider* fdp) -> void {
337           [[maybe_unused]] bool rc =
338               get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(
339                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
340         },
341 
342         // ::SDP_GetDiRecord
343         [](FuzzedDataProvider* fdp) -> void {
344           tSDP_DI_GET_RECORD device_info;  // Output var
345           [[maybe_unused]] bool rc =
346               get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
347                   fdp->ConsumeIntegral<uint8_t>(), &device_info,
348                   getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
349         },
350 
351         // ::SDP_FindServiceUUIDInRec
352         [](FuzzedDataProvider* fdp) -> void {
353           tSDP_DISC_REC* p_rec =
354               generateArbitrarySdpDiscRecord(fdp, false).get();
355           bluetooth::Uuid uuid;  // Output var
356           [[maybe_unused]] bool rc =
357               get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(
358                   p_rec, &uuid);
359         }};
360 
361 #endif  // FUZZER_SDP_FUNCTIONS_H_
362