diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c b/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c index dc311d8a635..f8c4397b5ca 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_discovery.c @@ -56,6 +56,17 @@ static UINT8 *add_attr (UINT8 *p, UINT8 *p_end, tSDP_DISCOVERY_DB *p_db, /* Safety check in case we go crazy */ #define MAX_NEST_LEVELS 5 +/* Worst case length of any SDP request built by this module: + * pdu id(1) + transaction id(2) + parameter length(2) + * + UUID sequence: 2 byte header + SDP_MAX_UUID_FILTERS 128-bit UUIDs + * + maximum record/byte count(2) + * + attribute sequence: 3 byte header + SDP_MAX_ATTR_FILTERS entries of 3 bytes + * + continuation state: 1 byte length + SDP_MAX_CONTINUATION_LEN(16) + * A service attribute request carries a 4 byte record handle instead of the UUID + * sequence, so it is covered as well. */ +#define SDP_MAX_REQ_LEN (5 + (2 + SDP_MAX_UUID_FILTERS * (1 + LEN_UUID_128)) + 2 \ + + (3 + SDP_MAX_ATTR_FILTERS * 3) + (1 + SDP_MAX_CONTINUATION_LEN)) + /******************************************************************************* ** @@ -117,7 +128,7 @@ static void sdp_snd_service_search_req(tCONN_CB *p_ccb, UINT8 cont_len, UINT8 *p UINT16 param_len; /* Get a buffer to send the packet to L2CAP */ - if ((p_cmd = (BT_HDR *) osi_malloc(SDP_DATA_BUF_SIZE)) == NULL) { + if ((p_cmd = (BT_HDR *) osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + SDP_MAX_REQ_LEN)) == NULL) { sdp_disconnect (p_ccb, SDP_NO_RESOURCES); return; } @@ -507,7 +518,7 @@ static void process_service_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UINT8 *p_ /* Now, ask for the next handle. Reuse the buffer we just got. */ if (p_ccb->cur_handle < p_ccb->num_handles) { - BT_HDR *p_msg = (BT_HDR *) osi_malloc(SDP_DATA_BUF_SIZE); + BT_HDR *p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + SDP_MAX_REQ_LEN); UINT8 *p; if (!p_msg) { @@ -656,7 +667,7 @@ static void process_service_search_attr_rsp (tCONN_CB *p_ccb, UINT8 *p_reply, UI #endif /* If continuation request (or first time request) */ if ((cont_request_needed) || (!p_reply)) { - BT_HDR *p_msg = (BT_HDR *) osi_malloc(SDP_DATA_BUF_SIZE); + BT_HDR *p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + SDP_MAX_REQ_LEN); UINT8 *p; if (!p_msg) { diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_server.c b/components/bt/host/bluedroid/stack/sdp/sdp_server.c index 3523ccbb93d..aef85fd5468 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_server.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_server.c @@ -256,8 +256,8 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num, is_cont = TRUE; } - /* Get a buffer to use to build the response */ - if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) == NULL) { + /* Get a buffer to use to build the response, the whole PDU has to fit the peer MTU */ + if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + p_ccb->rem_mtu_size)) == NULL) { SDP_TRACE_ERROR ("SDP - no buf for search rsp\n"); return; } @@ -523,8 +523,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) { + /* Get a buffer to use to build the response, the whole PDU has to fit the peer MTU */ + if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + p_ccb->rem_mtu_size)) == NULL) { SDP_TRACE_ERROR ("SDP - no buf for search rsp\n"); osi_free(p_ccb->rsp_list); p_ccb->rsp_list = NULL; @@ -865,8 +865,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) { + /* Get a buffer to use to build the response, the whole PDU has to fit the peer MTU */ + if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + L2CAP_MIN_OFFSET + p_ccb->rem_mtu_size)) == NULL) { SDP_TRACE_ERROR ("SDP - no buf for search rsp\n"); osi_free (p_ccb->rsp_list); p_ccb->rsp_list = NULL; diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_utils.c b/components/bt/host/bluedroid/stack/sdp/sdp_utils.c index 8b91b36cc94..9da2d33cc61 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_utils.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_utils.c @@ -306,14 +306,27 @@ void sdpu_build_n_send_error (tCONN_CB *p_ccb, UINT16 trans_num, UINT16 error_co { UINT8 *p_rsp, *p_rsp_start, *p_rsp_param_len; UINT16 rsp_param_len; + UINT16 buf_size; BT_HDR *p_buf; + UINT16 len; SDP_TRACE_WARNING ("SDP - sdpu_build_n_send_error code: 0x%x CID: 0x%x\n", error_code, p_ccb->connection_id); + /* pdu id(1), trans num(2), param len(2), error code(2) and the optional error text */ + buf_size = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + 7; + if (p_error_text) { + len = (UINT16)strlen(p_error_text); + if (len > SDP_DATA_BUF_SIZE - buf_size) { + buf_size = SDP_DATA_BUF_SIZE; + }else { + buf_size += len; + } + } + /* Get a buffer to use to build and send the packet to L2CAP */ - if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) == NULL) { + if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) { SDP_TRACE_ERROR ("SDP - no buf for err msg\n"); return; }