/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FUZZER_SDP_FUNCTIONS_H_ #define FUZZER_SDP_FUNCTIONS_H_ #include #include #include "fuzzers/common/commonFuzzHelpers.h" #include "fuzzers/sdp/sdpFuzzHelpers.h" #include "sdp_api.h" #define SDP_MAX_DB_LEN 1024 * 1024 // 1 MB #define MAX_NUM_DBS 64 /* This is a vector of lambda functions the fuzzer will pull from. * This is done so new functions can be added to the fuzzer easily * without requiring modifications to the main fuzzer file. This also * allows multiple fuzzers to include this file, if functionality is needed. */ static const std::vector> sdp_operations = { // SDP_InitDiscoveryDb [](FuzzedDataProvider* fdp) -> void { if (sdp_db_vect.size() >= MAX_NUM_DBS) { return; } // build out uuid_list std::vector uuid_list; uint8_t num_uuids = fdp->ConsumeIntegral(); for (uint8_t i = 0; i < num_uuids; i++) { uuid_list.push_back(generateArbitraryUuid(fdp)); } // build out attr_list std::vector attr_list = generateArbitraryAttrList(fdp); uint32_t db_size = fdp->ConsumeIntegralInRange(0, SDP_MAX_DB_LEN); std::shared_ptr p_db( reinterpret_cast(malloc(db_size)), free); if (p_db) { bool success = SDP_InitDiscoveryDb( p_db.get(), db_size, uuid_list.size(), uuid_list.data(), attr_list.size(), reinterpret_cast(attr_list.data())); if (success) { sdp_db_vect.push_back(p_db); } } }, // SDP_CancelServiceSearch [](FuzzedDataProvider* fdp) -> void { SDP_CancelServiceSearch( getArbitraryVectorElement(fdp, sdp_db_vect, true).get()); }, // SDP_ServiceSearchRequest [](FuzzedDataProvider* fdp) -> void { const RawAddress bd_addr = generateRawAddress(fdp); tSDP_DISCOVERY_DB* db = getArbitraryVectorElement(fdp, sdp_db_vect, false).get(); if (db) { SDP_ServiceSearchRequest(bd_addr, db, &sdp_disc_cmpl_cb); } }, // SDP_ServiceSearchAttributeRequest [](FuzzedDataProvider* fdp) -> void { const RawAddress bd_addr = generateRawAddress(fdp); tSDP_DISCOVERY_DB* db = getArbitraryVectorElement(fdp, sdp_db_vect, false).get(); if (db) { SDP_ServiceSearchAttributeRequest(bd_addr, db, &sdp_disc_cmpl_cb); } }, // SDP_ServiceSearchAttributeRequest2 [](FuzzedDataProvider* fdp) -> void { const RawAddress bd_addr = generateRawAddress(fdp); std::vector user_data = fdp->ConsumeBytes( fdp->ConsumeIntegralInRange(0, 1024)); tSDP_DISCOVERY_DB* db = getArbitraryVectorElement(fdp, sdp_db_vect, false).get(); if (db) { SDP_ServiceSearchAttributeRequest2(bd_addr, db, &sdp_disc_cmpl_cb2, user_data.data()); } }, // SDP_FindAttributeInRec [](FuzzedDataProvider* fdp) -> void { tSDP_DISC_REC* p_rec = generateArbitrarySdpDiscRecord(fdp, false).get(); SDP_FindAttributeInRec(p_rec, fdp->ConsumeIntegral()); }, // SDP_FindServiceInDb [](FuzzedDataProvider* fdp) -> void { SDP_FindServiceInDb( getArbitraryVectorElement(fdp, sdp_db_vect, true).get(), fdp->ConsumeIntegral(), generateArbitrarySdpDiscRecord(fdp, true).get()); }, // SDP_FindServiceUUIDInDb [](FuzzedDataProvider* fdp) -> void { const bluetooth::Uuid uuid = generateArbitraryUuid(fdp); SDP_FindServiceUUIDInDb( getArbitraryVectorElement(fdp, sdp_db_vect, true).get(), uuid, generateArbitrarySdpDiscRecord(fdp, true).get()); }, // SDP_FindServiceUUIDInRec_128bit [](FuzzedDataProvider* fdp) -> void { bluetooth::Uuid uuid = generateArbitraryUuid(fdp); tSDP_DISC_REC* p_rec = generateArbitrarySdpDiscRecord(fdp, false).get(); SDP_FindServiceUUIDInRec_128bit(p_rec, &uuid); }, // SDP_FindServiceInDb_128bit [](FuzzedDataProvider* fdp) -> void { SDP_FindServiceInDb_128bit( getArbitraryVectorElement(fdp, sdp_db_vect, true).get(), generateArbitrarySdpDiscRecord(fdp, true).get()); }, // SDP_FindProtocolListElemInRec [](FuzzedDataProvider* fdp) -> void { tSDP_PROTOCOL_ELEM elem = generateArbitrarySdpProtocolElements(fdp); tSDP_DISC_REC* p_rec = generateArbitrarySdpDiscRecord(fdp, false).get(); SDP_FindProtocolListElemInRec(p_rec, fdp->ConsumeIntegral(), &elem); }, // SDP_FindProfileVersionInRec [](FuzzedDataProvider* fdp) -> void { uint16_t p_version; tSDP_DISC_REC* p_rec = generateArbitrarySdpDiscRecord(fdp, false).get(); SDP_FindProfileVersionInRec(p_rec, fdp->ConsumeIntegral(), &p_version); }, // SDP_CreateRecord [](FuzzedDataProvider* fdp) -> void { uint32_t handle = SDP_CreateRecord(); if (handle) { sdp_record_handles.push_back(handle); } }, // SDP_DeleteRecord [](FuzzedDataProvider* fdp) -> void { SDP_DeleteRecord( getArbitraryVectorElement(fdp, sdp_record_handles, true)); }, // SDP_AddAttribute [](FuzzedDataProvider* fdp) -> void { std::vector val = fdp->ConsumeBytes( fdp->ConsumeIntegralInRange(1, 1024)); if (val.size() > 0) { SDP_AddAttribute( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral(), fdp->ConsumeIntegral(), val.size(), val.data()); } }, // SDP_AddSequence [](FuzzedDataProvider* fdp) -> void { SDP_Sequence_Helper seq = generateArbitrarySdpElemSequence(fdp); SDP_AddSequence( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral(), seq.num_elem, seq.type.get(), seq.len.get(), seq.p_val.get()); }, // SDP_AddUuidSequence [](FuzzedDataProvider* fdp) -> void { uint16_t num_uuids = fdp->ConsumeIntegralInRange(1, 64); uint16_t* uuids = new uint16_t[num_uuids]; for (uint16_t i = 0; i < num_uuids; i++) { uuids[i] = fdp->ConsumeIntegral(); } SDP_AddUuidSequence( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral(), num_uuids, uuids); delete[] uuids; }, // SDP_AddProtocolList [](FuzzedDataProvider* fdp) -> void { std::shared_ptr p_proto_list = generateArbitrarySdpProtocolElementList(fdp); if (p_proto_list) { SDP_AddProtocolList( getArbitraryVectorElement(fdp, sdp_record_handles, true), p_proto_list.get()->num_elems, p_proto_list.get()->list_elem); } }, // SDP_AddAdditionProtoLists [](FuzzedDataProvider* fdp) -> void { uint16_t arr_size; tSDP_PROTO_LIST_ELEM** p_proto_list = generateArbitrarySdpProtocolElementListArray(fdp, &arr_size); if (p_proto_list) { if (p_proto_list[0]) { SDP_AddAdditionProtoLists( getArbitraryVectorElement(fdp, sdp_record_handles, true), arr_size, p_proto_list[0]); for (uint16_t i = 0; i < arr_size; i++) { delete p_proto_list[i]; } } free(p_proto_list); } }, // SDP_AddProfileDescriptorList [](FuzzedDataProvider* fdp) -> void { SDP_AddProfileDescriptorList( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral(), fdp->ConsumeIntegral()); }, // SDP_AddLanguageBaseAttrIDList [](FuzzedDataProvider* fdp) -> void { SDP_AddLanguageBaseAttrIDList( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral(), fdp->ConsumeIntegral(), fdp->ConsumeIntegral()); }, // SDP_AddServiceClassIdList [](FuzzedDataProvider* fdp) -> void { uint16_t num_services = fdp->ConsumeIntegralInRange(0, 64); uint16_t* service_uuids = new uint16_t[num_services]; for (uint16_t i = 0; i < num_services; i++) { service_uuids[i] = fdp->ConsumeIntegral(); } SDP_AddServiceClassIdList( getArbitraryVectorElement(fdp, sdp_record_handles, true), num_services, service_uuids); delete[] service_uuids; }, // SDP_DeleteAttribute [](FuzzedDataProvider* fdp) -> void { SDP_DeleteAttribute( getArbitraryVectorElement(fdp, sdp_record_handles, true), fdp->ConsumeIntegral()); }, // SDP_SetLocalDiRecord [](FuzzedDataProvider* fdp) -> void { uint32_t handle; // Output var tSDP_DI_RECORD device_info = generateArbitrarySdpDiRecord(fdp); SDP_SetLocalDiRecord(&device_info, &handle); }, // SDP_DiDiscover [](FuzzedDataProvider* fdp) -> void { const RawAddress remote_device = generateRawAddress(fdp); // Create a new buffer for the discoveryDB init call uint32_t db_size = fdp->ConsumeIntegralInRange(0, SDP_MAX_DB_LEN); std::shared_ptr p_db( reinterpret_cast(malloc(db_size)), free); if (p_db) { SDP_DiDiscover(remote_device, p_db.get(), db_size, &sdp_disc_cmpl_cb); } }, // SDP_GetNumDiRecords [](FuzzedDataProvider* fdp) -> void { SDP_GetNumDiRecords( getArbitraryVectorElement(fdp, sdp_db_vect, true).get()); }, // SDP_GetDiRecord [](FuzzedDataProvider* fdp) -> void { tSDP_DI_GET_RECORD device_info; // Output var SDP_GetDiRecord( fdp->ConsumeIntegral(), &device_info, getArbitraryVectorElement(fdp, sdp_db_vect, true).get()); }, // SDP_SetTraceLevel [](FuzzedDataProvider* fdp) -> void { SDP_SetTraceLevel(fdp->ConsumeIntegral()); }, // SDP_FindServiceUUIDInRec [](FuzzedDataProvider* fdp) -> void { tSDP_DISC_REC* p_rec = generateArbitrarySdpDiscRecord(fdp, false).get(); bluetooth::Uuid uuid; // Output var SDP_FindServiceUUIDInRec(p_rec, &uuid); }}; #endif // FUZZER_SDP_FUNCTIONS_H_