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