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