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