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