/*
* 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
#include "fuzzers/common/commonFuzzHelpers.h"
#include "fuzzers/sdp/sdpFuzzHelpers.h"
#include "stack/include/sdp_api.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.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 =
get_legacy_stack_sdp_api()->service.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 {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->service.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->service.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()
->service.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()
->service.SDP_ServiceSearchAttributeRequest2(
bd_addr, db,
base::BindRepeating(&sdp_disc_cmpl_cb2, user_data));
}
},
// ::SDP_FindAttributeInRec
[](FuzzedDataProvider* fdp) -> void {
tSDP_DISC_REC* p_rec =
generateArbitrarySdpDiscRecord(fdp, false).get();
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(
p_rec, fdp->ConsumeIntegral());
},
// ::SDP_FindServiceInDb
[](FuzzedDataProvider* fdp) -> void {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->db.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);
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->db.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();
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()
->record.SDP_FindServiceUUIDInRec_128bit(p_rec, &uuid);
},
// ::SDP_FindServiceInDb_128bit
[](FuzzedDataProvider* fdp) -> void {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->db.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();
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->record.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();
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(
p_rec, fdp->ConsumeIntegral(), &p_version);
},
// ::SDP_CreateRecord
[](FuzzedDataProvider* fdp) -> void {
uint32_t handle =
get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
if (handle) {
sdp_record_handles.push_back(handle);
}
},
// ::SDP_DeleteRecord
[](FuzzedDataProvider* fdp) -> void {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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);
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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();
}
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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]) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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 {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.SDP_AddProfileDescriptorList(
getArbitraryVectorElement(fdp, sdp_record_handles, true),
fdp->ConsumeIntegral(),
fdp->ConsumeIntegral());
},
// ::SDP_AddLanguageBaseAttrIDList
[](FuzzedDataProvider* fdp) -> void {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.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();
}
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->handle.SDP_AddServiceClassIdList(
getArbitraryVectorElement(fdp, sdp_record_handles, true),
num_services, service_uuids);
delete[] service_uuids;
},
// ::SDP_SetLocalDiRecord
[](FuzzedDataProvider* fdp) -> void {
uint32_t handle; // Output var
tSDP_DI_RECORD device_info = generateArbitrarySdpDiRecord(fdp);
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->device_id.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) {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->device_id.SDP_DiDiscover(
remote_device, p_db.get(), db_size, &sdp_disc_cmpl_cb);
}
},
// ::SDP_GetNumDiRecords
[](FuzzedDataProvider* fdp) -> void {
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->device_id.SDP_GetNumDiRecords(
getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
},
// ::SDP_GetDiRecord
[](FuzzedDataProvider* fdp) -> void {
tSDP_DI_GET_RECORD device_info; // Output var
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->device_id.SDP_GetDiRecord(
fdp->ConsumeIntegral(), &device_info,
getArbitraryVectorElement(fdp, sdp_db_vect, true).get());
},
// ::SDP_FindServiceUUIDInRec
[](FuzzedDataProvider* fdp) -> void {
tSDP_DISC_REC* p_rec =
generateArbitrarySdpDiscRecord(fdp, false).get();
bluetooth::Uuid uuid; // Output var
[[maybe_unused]] bool rc =
get_legacy_stack_sdp_api()->record.SDP_FindServiceUUIDInRec(
p_rec, &uuid);
}};
#endif // FUZZER_SDP_FUNCTIONS_H_