mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
fix(bt/bluedroid): fixed the vulerabilities from AI code review in Bluedroid
This commit is contained in:
@@ -72,8 +72,8 @@ BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len, UINT16 num_uui
|
||||
/* verify the parameters */
|
||||
if (p_db == NULL || (sizeof (tSDP_DISCOVERY_DB) > len) ||
|
||||
num_attr > SDP_MAX_ATTR_FILTERS || num_uuid > SDP_MAX_UUID_FILTERS) {
|
||||
SDP_TRACE_ERROR("SDP_InitDiscoveryDb Illegal param: p_db 0x%x, len %d, num_uuid %d, num_attr %d",
|
||||
(UINT32)p_db, len, num_uuid, num_attr);
|
||||
SDP_TRACE_ERROR("SDP_InitDiscoveryDb Illegal param: p_db %p, len %d, num_uuid %d, num_attr %d",
|
||||
p_db, len, num_uuid, num_attr);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
@@ -99,8 +99,9 @@ BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len, UINT16 num_uui
|
||||
sdpu_sort_attr_list( num_attr, p_db );
|
||||
|
||||
p_db->num_attr_filters = num_attr;
|
||||
#endif
|
||||
return (TRUE);
|
||||
#endif
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,8 +125,9 @@ BOOLEAN SDP_CancelServiceSearch (tSDP_DISCOVERY_DB *p_db)
|
||||
|
||||
sdp_disconnect (p_ccb, SDP_CANCEL);
|
||||
p_ccb->disc_state = SDP_DISC_WAIT_CANCEL;
|
||||
#endif
|
||||
return (TRUE);
|
||||
#endif
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
@@ -429,7 +431,7 @@ BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid)
|
||||
for (p_sattr = p_attr->attr_value.v.p_sub_attr; p_sattr; p_sattr = p_sattr->p_next_attr) {
|
||||
if (SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UUID_DESC_TYPE) {
|
||||
/* only support 128 bits UUID for now */
|
||||
if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 16) {
|
||||
if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == LEN_UUID_128) {
|
||||
p_uuid->len = LEN_UUID_128;
|
||||
for (uint8_t i = 0; i != LEN_UUID_128; ++i) {
|
||||
p_uuid->uu.uuid128[i] = p_sattr->attr_value.v.array[LEN_UUID_128 - i - 1];
|
||||
|
||||
@@ -68,15 +68,15 @@ tSDP_RECORD *sdp_db_service_search (tSDP_RECORD *p_rec, tSDP_UUID_SEQ *p_seq)
|
||||
|
||||
/* If NULL, start at the beginning, else start at the first specified record */
|
||||
if (!p_rec) {
|
||||
p_node = list_begin(sdp_cb.server_db.p_record_list);
|
||||
p_node = list_begin(sdp_cb.server_db.p_record_list);
|
||||
} else {
|
||||
/* get node in the record list with given p_rec */
|
||||
/* get node in the record list with given p_rec */
|
||||
p_node = list_get_node(sdp_cb.server_db.p_record_list, p_rec);
|
||||
if (p_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* get next node */
|
||||
p_node = list_next(p_node);
|
||||
if (p_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* get next node */
|
||||
p_node = list_next(p_node);
|
||||
}
|
||||
|
||||
/* Look through the records. The spec says that a match occurs if */
|
||||
@@ -178,8 +178,8 @@ tSDP_RECORD *sdp_db_find_record (UINT32 handle)
|
||||
|
||||
/* Look through the records for the caller's handle */
|
||||
for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
|
||||
p_rec = list_node(p_node);
|
||||
if (p_rec->record_handle == handle) {
|
||||
p_rec = list_node(p_node);
|
||||
if (p_rec->record_handle == handle) {
|
||||
return (p_rec);
|
||||
}
|
||||
}
|
||||
@@ -446,7 +446,7 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type,
|
||||
|
||||
/* Find the record in the database */
|
||||
for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
|
||||
p_rec= list_node(p_node);
|
||||
p_rec= list_node(p_node);
|
||||
if (p_rec->record_handle == handle) {
|
||||
tSDP_ATTRIBUTE *p_attr = &p_rec->attribute[0];
|
||||
|
||||
@@ -498,13 +498,12 @@ BOOLEAN SDP_AddAttribute (UINT32 handle, UINT16 attr_id, UINT8 attr_type,
|
||||
}
|
||||
}
|
||||
|
||||
if ((attr_len > 0) && (p_val != 0)) {
|
||||
if (attr_len > 0) {
|
||||
p_attr->len = attr_len;
|
||||
memcpy (&p_rec->attr_pad[p_rec->free_pad_ptr], p_val, (size_t)attr_len);
|
||||
p_attr->value_ptr = &p_rec->attr_pad[p_rec->free_pad_ptr];
|
||||
p_rec->free_pad_ptr += attr_len;
|
||||
} else if ((attr_len == 0 && p_attr->len != 0) || /* if truncate to 0 length, simply don't add */
|
||||
p_val == 0) {
|
||||
} else if (attr_len == 0 && p_attr->len != 0) { /* if truncate to 0 length, simply don't add */
|
||||
SDP_TRACE_ERROR("SDP_AddAttribute fail, length exceed maximum: ID %d: attr_len:%d \n",
|
||||
attr_id, attr_len );
|
||||
p_attr->id = p_attr->type = p_attr->len = 0;
|
||||
@@ -889,7 +888,7 @@ BOOLEAN SDP_DeleteAttribute (UINT32 handle, UINT16 attr_id)
|
||||
|
||||
/* Find the record in the database */
|
||||
for(p_node = list_begin(sdp_cb.server_db.p_record_list); p_node; p_node = list_next(p_node)) {
|
||||
p_rec= list_node(p_node);
|
||||
p_rec= list_node(p_node);
|
||||
if (p_rec->record_handle == handle) {
|
||||
tSDP_ATTRIBUTE *p_attr = &p_rec->attribute[0];
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ static UINT8 *sdpu_build_uuid_seq (UINT8 *p_out, UINT16 num_uuids, tSDP_UUID *p_
|
||||
UINT32_TO_BE_STREAM (p_out, p_uuid_list->uu.uuid32);
|
||||
} else {
|
||||
UINT8_TO_BE_STREAM (p_out, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
|
||||
ARRAY_TO_BE_STREAM (p_out, p_uuid_list->uu.uuid128, p_uuid_list->len);
|
||||
ARRAY_TO_BE_STREAM (p_out, p_uuid_list->uu.uuid128, LEN_UUID_128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,6 +374,10 @@ static void sdp_copy_raw_data (tCONN_CB *p_ccb, BOOLEAN offset)
|
||||
p = &p_ccb->rsp_list[0];
|
||||
p_end = &p_ccb->rsp_list[0] + list_len;
|
||||
|
||||
if (cpy_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset) {
|
||||
type = *p++;
|
||||
cpy_len--;
|
||||
@@ -835,7 +839,7 @@ static UINT8 *save_attr_seq (tCONN_CB *p_ccb, UINT8 *p, UINT8 *p_msg_end)
|
||||
** Returns pointer to next byte in data stream
|
||||
**
|
||||
*******************************************************************************/
|
||||
tSDP_DISC_REC *add_record (tSDP_DISCOVERY_DB *p_db, BD_ADDR p_bda)
|
||||
static tSDP_DISC_REC *add_record (tSDP_DISCOVERY_DB *p_db, BD_ADDR p_bda)
|
||||
{
|
||||
tSDP_DISC_REC *p_rec;
|
||||
|
||||
@@ -950,7 +954,7 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, tSDP_DI
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Case falls through */
|
||||
/* falls through */
|
||||
|
||||
case TWO_COMP_INT_DESC_TYPE:
|
||||
switch (attr_len) {
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "stack/l2cdefs.h"
|
||||
#include "stack/hcidefs.h"
|
||||
#include "stack/hcimsgs.h"
|
||||
|
||||
@@ -138,6 +137,10 @@ void sdp_init (void)
|
||||
{
|
||||
#if SDP_DYNAMIC_MEMORY
|
||||
sdp_cb_ptr = (tSDP_CB *)osi_malloc(sizeof(tSDP_CB));
|
||||
if (!sdp_cb_ptr) {
|
||||
ESP_LOGE("BT_SDP", "SDP control block malloc failed\n");
|
||||
return;
|
||||
}
|
||||
#endif /* #if SDP_DYNAMIC_MEMORY */
|
||||
/* Clears all structures and local SDP database (if Server is enabled) */
|
||||
memset (&sdp_cb, 0, sizeof (tSDP_CB));
|
||||
@@ -208,8 +211,10 @@ void sdp_deinit (void)
|
||||
{
|
||||
list_free(sdp_cb.server_db.p_record_list);
|
||||
#if SDP_DYNAMIC_MEMORY
|
||||
osi_free(sdp_cb_ptr);
|
||||
sdp_cb_ptr = NULL;
|
||||
if (sdp_cb_ptr) {
|
||||
osi_free(sdp_cb_ptr);
|
||||
sdp_cb_ptr = NULL;
|
||||
}
|
||||
#endif /* #if SDP_DYNAMIC_MEMORY */
|
||||
}
|
||||
|
||||
@@ -403,7 +408,7 @@ static void sdp_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
p_cfg->mtu_present = FALSE;
|
||||
p_cfg->result = L2CAP_CFG_OK;
|
||||
|
||||
/* Check peer config request against our rfcomm configuration */
|
||||
/* Check peer config request against our sdp configuration */
|
||||
if (p_cfg->fcr_present) {
|
||||
/* Reject the window size if it is bigger than we want it to be */
|
||||
if (p_cfg->fcr.mode != L2CAP_FCR_BASIC_MODE) {
|
||||
|
||||
@@ -344,13 +344,18 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
max_list_len = p_ccb->rem_mtu_size - SDP_MAX_ATTR_RSPHDR_LEN;
|
||||
}
|
||||
|
||||
p_req = sdpu_extract_attr_seq (p_req, param_len, &attr_seq);
|
||||
p_req = sdpu_extract_attr_seq (p_req, (UINT16)(p_req_end - p_req), &attr_seq);
|
||||
|
||||
if ((!p_req) || (!attr_seq.num_attr) || (p_req > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_ATTR_LIST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (max_list_len < 4) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_ILLEGAL_PARAMETER, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&attr_seq_sav, &attr_seq, sizeof(tSDP_ATTR_SEQ)) ;
|
||||
|
||||
/* Find a record with the record handle */
|
||||
@@ -375,31 +380,32 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
p_ccb->rsp_list = (UINT8 *)osi_malloc(max_list_len);
|
||||
if (p_ccb->rsp_list == NULL) {
|
||||
SDP_TRACE_ERROR("%s No scratch buf for attr rsp\n", __func__);
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*p_req++ != SDP_CONTINUATION_LEN) || (p_req + 2 > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (cont_offset, p_req);
|
||||
|
||||
if (cont_offset != p_ccb->cont_offset) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_INX);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!p_ccb->rsp_list) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
return;
|
||||
}
|
||||
is_cont = TRUE;
|
||||
|
||||
/* Initialise for continuation response */
|
||||
p_rsp = &p_ccb->rsp_list[0];
|
||||
attr_seq.attr_entry[p_ccb->cont_info.next_attr_index].start = p_ccb->cont_info.next_attr_start_id;
|
||||
} else {
|
||||
if (p_ccb->rsp_list) {
|
||||
if (p_ccb->rsp_list) {
|
||||
osi_free (p_ccb->rsp_list);
|
||||
}
|
||||
|
||||
@@ -438,6 +444,12 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
if (p_ccb->cont_info.attr_offset) {
|
||||
p_rsp = sdpu_build_partial_attrib_entry (p_rsp, p_attr, rem_len,
|
||||
&p_ccb->cont_info.attr_offset);
|
||||
if (p_rsp == NULL) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the partial attrib could not been fully added yet */
|
||||
if (p_ccb->cont_info.attr_offset != attr_len) {
|
||||
@@ -449,12 +461,20 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
if (attr_len >= SDP_MAX_ATTR_LEN) {
|
||||
SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d\n", max_list_len, attr_len);
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* add the partial attribute if possible */
|
||||
p_rsp = sdpu_build_partial_attrib_entry (p_rsp, p_attr, (UINT16)rem_len,
|
||||
&p_ccb->cont_info.attr_offset);
|
||||
if (p_rsp == NULL) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
p_ccb->cont_info.next_attr_index = xx;
|
||||
p_ccb->cont_info.next_attr_start_id = p_attr->id;
|
||||
@@ -502,6 +522,8 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
/* Get a buffer to use to build the response */
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) == NULL) {
|
||||
SDP_TRACE_ERROR ("SDP - no buf for search rsp\n");
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
@@ -574,7 +596,6 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
BOOLEAN maxxed_out = FALSE, is_cont = FALSE;
|
||||
UINT8 *p_seq_start;
|
||||
UINT16 seq_len, attr_len;
|
||||
UNUSED(p_req_end);
|
||||
|
||||
/* Extract the UUID sequence to search for */
|
||||
p_req = sdpu_extract_uid_seq (p_req, param_len, &uid_seq);
|
||||
@@ -591,9 +612,9 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
max_list_len = p_ccb->rem_mtu_size - SDP_MAX_SERVATTR_RSPHDR_LEN;
|
||||
}
|
||||
|
||||
p_req = sdpu_extract_attr_seq (p_req, param_len, &attr_seq);
|
||||
p_req = sdpu_extract_attr_seq (p_req, (UINT16)(p_req_end - p_req), &attr_seq);
|
||||
|
||||
if ((!p_req) || (!attr_seq.num_attr)) {
|
||||
if ((!p_req) || (!attr_seq.num_attr) || (p_req > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_ATTR_LIST);
|
||||
return;
|
||||
}
|
||||
@@ -625,17 +646,23 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
|
||||
if ((*p_req++ != SDP_CONTINUATION_LEN) || (p_req + 2 > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
|
||||
osi_free (p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (cont_offset, p_req);
|
||||
|
||||
if (cont_offset != p_ccb->cont_offset) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_INX);
|
||||
osi_free (p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!p_ccb->rsp_list) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free (p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
is_cont = TRUE;
|
||||
@@ -704,6 +731,12 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
if (p_ccb->cont_info.attr_offset) {
|
||||
p_rsp = sdpu_build_partial_attrib_entry (p_rsp, p_attr, rem_len,
|
||||
&p_ccb->cont_info.attr_offset);
|
||||
if (p_rsp == NULL) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the partial attrib could not been fully added yet */
|
||||
if (p_ccb->cont_info.attr_offset != attr_len) {
|
||||
@@ -716,12 +749,20 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
if (attr_len >= SDP_MAX_ATTR_LEN) {
|
||||
SDP_TRACE_ERROR("SDP attr too big: max_list_len=%d,attr_len=%d\n", max_list_len, attr_len);
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* add the partial attribute if possible */
|
||||
p_rsp = sdpu_build_partial_attrib_entry (p_rsp, p_attr, (UINT16)rem_len,
|
||||
&p_ccb->cont_info.attr_offset);
|
||||
if (p_rsp == NULL) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_NO_RESOURCES, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
p_ccb->cont_info.next_attr_index = xx;
|
||||
p_ccb->cont_info.next_attr_start_id = p_attr->id;
|
||||
@@ -791,6 +832,8 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
// TODO(sharvil): rewrite SDP server.
|
||||
if (is_cont && len_to_send == 0) {
|
||||
sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_CONT_STATE, NULL);
|
||||
osi_free(p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -817,6 +860,8 @@ static void process_service_search_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
/* Get a buffer to use to build the response */
|
||||
if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) == NULL) {
|
||||
SDP_TRACE_ERROR ("SDP - no buf for search rsp\n");
|
||||
osi_free (p_ccb->rsp_list);
|
||||
p_ccb->rsp_list = NULL;
|
||||
return;
|
||||
}
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
|
||||
@@ -361,6 +361,8 @@ void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UINT16 error_co
|
||||
UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq)
|
||||
{
|
||||
UINT8 *p_seq_end;
|
||||
UINT8 *p_param_start;
|
||||
UINT8 *p_param_end;
|
||||
UINT8 descr, type, size;
|
||||
UINT32 seq_len, uuid_len;
|
||||
|
||||
@@ -368,7 +370,12 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq)
|
||||
p_seq->num_uids = 0;
|
||||
|
||||
/* A UID sequence is composed of a bunch of UIDs. */
|
||||
p_param_start = p;
|
||||
p_param_end = p_param_start + param_len;
|
||||
|
||||
if (p + 1 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (descr, p);
|
||||
type = descr >> 3;
|
||||
size = descr & 7;
|
||||
@@ -388,26 +395,38 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq)
|
||||
seq_len = 16;
|
||||
break;
|
||||
case SIZE_IN_NEXT_BYTE:
|
||||
if (p + 1 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (seq_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_WORD:
|
||||
if (p + 2 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (seq_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_LONG:
|
||||
if (p + 4 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT32 (seq_len, p);
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (seq_len >= param_len) {
|
||||
p_seq_end = p + seq_len;
|
||||
if (p_seq_end < p || p_seq_end > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
p_seq_end = p + seq_len;
|
||||
|
||||
/* Loop through, extracting the UIDs */
|
||||
for ( ; p < p_seq_end ; ) {
|
||||
if (p_seq->num_uids >= MAX_UUIDS_PER_SEQ) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BE_STREAM_TO_UINT8 (descr, p);
|
||||
type = descr >> 3;
|
||||
size = descr & 7;
|
||||
@@ -427,31 +446,37 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq)
|
||||
uuid_len = 16;
|
||||
break;
|
||||
case SIZE_IN_NEXT_BYTE:
|
||||
if (p + 1 > p_seq_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (uuid_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_WORD:
|
||||
if (p + 2 > p_seq_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (uuid_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_LONG:
|
||||
if (p + 4 > p_seq_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT32 (uuid_len, p);
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* If UUID length is valid, copy it across */
|
||||
if ((uuid_len == 2) || (uuid_len == 4) || (uuid_len == 16)) {
|
||||
p_seq->uuid_entry[p_seq->num_uids].len = (UINT16) uuid_len;
|
||||
BE_STREAM_TO_ARRAY (p, p_seq->uuid_entry[p_seq->num_uids].value, (int)uuid_len);
|
||||
p_seq->num_uids++;
|
||||
} else {
|
||||
if ((uuid_len != 2) && (uuid_len != 4) && (uuid_len != 16)) {
|
||||
return (NULL);
|
||||
}
|
||||
if (p + uuid_len > p_seq_end) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* We can only do so many */
|
||||
if (p_seq->num_uids >= MAX_UUIDS_PER_SEQ) {
|
||||
return (NULL);
|
||||
}
|
||||
p_seq->uuid_entry[p_seq->num_uids].len = (UINT16) uuid_len;
|
||||
BE_STREAM_TO_ARRAY (p, p_seq->uuid_entry[p_seq->num_uids].value, (int)uuid_len);
|
||||
p_seq->num_uids++;
|
||||
}
|
||||
|
||||
if (p != p_seq_end) {
|
||||
@@ -476,13 +501,22 @@ UINT8 *sdpu_extract_uid_seq (UINT8 *p, UINT16 param_len, tSDP_UUID_SEQ *p_seq)
|
||||
UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
|
||||
{
|
||||
UINT8 *p_end_list;
|
||||
UINT8 *p_param_start;
|
||||
UINT8 *p_param_end;
|
||||
UINT8 descr, type, size;
|
||||
UINT32 list_len, attr_len;
|
||||
|
||||
/* Assume none found */
|
||||
p_seq->num_attr = 0;
|
||||
|
||||
/* param_len is bytes available from p through end of SDP parameter block */
|
||||
p_param_start = p;
|
||||
p_param_end = p_param_start + param_len;
|
||||
|
||||
/* Get attribute sequence info */
|
||||
if (p + 1 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (descr, p);
|
||||
type = descr >> 3;
|
||||
size = descr & 7;
|
||||
@@ -493,14 +527,23 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
|
||||
|
||||
switch (size) {
|
||||
case SIZE_IN_NEXT_BYTE:
|
||||
if (p + 1 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (list_len, p);
|
||||
break;
|
||||
|
||||
case SIZE_IN_NEXT_WORD:
|
||||
if (p + 2 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (list_len, p);
|
||||
break;
|
||||
|
||||
case SIZE_IN_NEXT_LONG:
|
||||
if (p + 4 > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT32 (list_len, p);
|
||||
break;
|
||||
|
||||
@@ -508,14 +551,17 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
|
||||
return (p);
|
||||
}
|
||||
|
||||
if (list_len > param_len) {
|
||||
return (p);
|
||||
}
|
||||
|
||||
p_end_list = p + list_len;
|
||||
if (p_end_list < p || p_end_list > p_param_end) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Loop through, extracting the attribute IDs */
|
||||
for ( ; p < p_end_list ; ) {
|
||||
if (p_seq->num_attr >= MAX_ATTR_PER_SEQ) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BE_STREAM_TO_UINT8 (descr, p);
|
||||
type = descr >> 3;
|
||||
size = descr & 7;
|
||||
@@ -532,34 +578,45 @@ UINT8 *sdpu_extract_attr_seq (UINT8 *p, UINT16 param_len, tSDP_ATTR_SEQ *p_seq)
|
||||
attr_len = 4;
|
||||
break;
|
||||
case SIZE_IN_NEXT_BYTE:
|
||||
if (p + 1 > p_end_list) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT8 (attr_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_WORD:
|
||||
if (p + 2 > p_end_list) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (attr_len, p);
|
||||
break;
|
||||
case SIZE_IN_NEXT_LONG:
|
||||
if (p + 4 > p_end_list) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT32 (attr_len, p);
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Attribute length must be 2-bytes or 4-bytes for a paired entry. */
|
||||
if (attr_len == 2) {
|
||||
if (p + 2 > p_end_list) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].start, p);
|
||||
p_seq->attr_entry[p_seq->num_attr].end = p_seq->attr_entry[p_seq->num_attr].start;
|
||||
} else if (attr_len == 4) {
|
||||
if (p + 4 > p_end_list) {
|
||||
return (NULL);
|
||||
}
|
||||
BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].start, p);
|
||||
BE_STREAM_TO_UINT16 (p_seq->attr_entry[p_seq->num_attr].end, p);
|
||||
} else {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* We can only do so many */
|
||||
if (++p_seq->num_attr >= MAX_ATTR_PER_SEQ) {
|
||||
return (NULL);
|
||||
}
|
||||
p_seq->num_attr++;
|
||||
}
|
||||
|
||||
return (p);
|
||||
@@ -995,6 +1052,25 @@ UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UI
|
||||
UINT8 *p_tmp_attr;
|
||||
size_t len_to_copy;
|
||||
UINT16 attr_len;
|
||||
UINT16 rem_in_attr;
|
||||
|
||||
attr_len = sdpu_get_attrib_entry_len(p_attr);
|
||||
if (attr_len > SDP_MAX_ATTR_LEN) {
|
||||
SDP_TRACE_ERROR("sdpu_build_partial_attrib_entry: attr_len %u exceeds SDP_MAX_ATTR_LEN %u\n",
|
||||
attr_len, (UINT16)SDP_MAX_ATTR_LEN);
|
||||
return NULL;
|
||||
}
|
||||
if (*offset > attr_len) {
|
||||
SDP_TRACE_ERROR("sdpu_build_partial_attrib_entry: offset %u past attr_len %u\n", *offset, attr_len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rem_in_attr = (UINT16)(attr_len - *offset);
|
||||
len_to_copy = (size_t)((rem_in_attr < len) ? rem_in_attr : len);
|
||||
/* rem_in_attr is 0 when *offset == attr_len; avoid memcpy(0) issues and useless work */
|
||||
if (len_to_copy == 0) {
|
||||
return p_out;
|
||||
}
|
||||
|
||||
if ((p_attr_buff = (UINT8 *) osi_malloc(sizeof(UINT8) * SDP_MAX_ATTR_LEN )) == NULL) {
|
||||
SDP_TRACE_ERROR("sdpu_build_partial_attrib_entry cannot get a buffer!\n");
|
||||
@@ -1003,14 +1079,11 @@ UINT8 *sdpu_build_partial_attrib_entry (UINT8 *p_out, tSDP_ATTRIBUTE *p_attr, UI
|
||||
p_tmp_attr = p_attr_buff;
|
||||
|
||||
sdpu_build_attrib_entry(p_tmp_attr, p_attr);
|
||||
attr_len = sdpu_get_attrib_entry_len(p_attr);
|
||||
|
||||
len_to_copy = ((attr_len - *offset) < len) ? (attr_len - *offset) : len;
|
||||
|
||||
memcpy(p_out, &p_attr_buff[*offset], len_to_copy);
|
||||
|
||||
p_out = &p_out[len_to_copy];
|
||||
*offset += len_to_copy;
|
||||
*offset += (UINT16)len_to_copy;
|
||||
|
||||
osi_free(p_attr_buff);
|
||||
return p_out;
|
||||
|
||||
Reference in New Issue
Block a user