diff --git a/components/bt/host/bluedroid/stack/gap/gap_ble.c b/components/bt/host/bluedroid/stack/gap/gap_ble.c index e32151298e0..bf3d97d666c 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_ble.c +++ b/components/bt/host/bluedroid/stack/gap/gap_ble.c @@ -104,7 +104,7 @@ tGAP_CLCB *gap_ble_find_clcb_by_conn_id(UINT16 conn_id) } } - return p_clcb; + return NULL; } /******************************************************************************* @@ -126,10 +126,10 @@ tGAP_CLCB *gap_clcb_alloc (BD_ADDR bda) memset(p_clcb, 0, sizeof(tGAP_CLCB)); p_clcb->in_use = TRUE; memcpy (p_clcb->bda, bda, BD_ADDR_LEN); - break; + return p_clcb; } } - return p_clcb; + return NULL; } /******************************************************************************* @@ -665,6 +665,12 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS switch (op_type) { case GATT_UUID_GAP_PREF_CONN_PARAM: GAP_TRACE_EVENT ("GATT_UUID_GAP_PREF_CONN_PARAM"); + /* Verify sufficient data length before reading connection parameters */ + if (p_data->att_value.len < 8) { + GAP_TRACE_ERROR ("GATT_UUID_GAP_PREF_CONN_PARAM: insufficient data length %d", p_data->att_value.len); + gap_ble_cl_op_cmpl(p_clcb, FALSE, 0, NULL); + break; + } /* Extract the peripheral preferred connection parameters and save them */ STREAM_TO_UINT16 (min, pp); @@ -679,7 +685,8 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS case GATT_UUID_GAP_DEVICE_NAME: GAP_TRACE_EVENT ("GATT_UUID_GAP_DEVICE_NAME\n"); - len = (UINT16)strlen((char *)pp); + /* Use att_value.len instead of strlen to avoid reading beyond buffer */ + len = p_data->att_value.len; if (len > GAP_CHAR_DEV_NAME_SIZE) { len = GAP_CHAR_DEV_NAME_SIZE; } @@ -687,6 +694,12 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS break; case GATT_UUID_GAP_CENTRAL_ADDR_RESOL: + /* Verify sufficient data length */ + if (p_data->att_value.len < 1) { + GAP_TRACE_ERROR ("GATT_UUID_GAP_CENTRAL_ADDR_RESOL: insufficient data length"); + gap_ble_cl_op_cmpl(p_clcb, FALSE, 0, NULL); + break; + } gap_ble_cl_op_cmpl(p_clcb, TRUE, 1, pp); break; } diff --git a/components/bt/host/bluedroid/stack/gap/gap_conn.c b/components/bt/host/bluedroid/stack/gap/gap_conn.c index db9065de818..cdd6a2d3a9b 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_conn.c +++ b/components/bt/host/bluedroid/stack/gap/gap_conn.c @@ -148,7 +148,7 @@ UINT16 GAP_ConnOpen (const char *p_serv_name, UINT8 service_id, BOOLEAN is_serve memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN); } else if (!is_server) { - /* remore addr is not specified and is not a server -> bad */ + /* remote addr is not specified and is not a server -> bad */ return (GAP_INVALID_HANDLE); } @@ -775,7 +775,9 @@ static void gap_checks_con_flags (tGAP_CCB *p_ccb) if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) { p_ccb->con_state = GAP_CCB_STATE_CONNECTED; - p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED); + if (p_ccb->p_callback) { + p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED); + } } } @@ -933,7 +935,9 @@ static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) gap_checks_con_flags (p_ccb); } else { - p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + if (p_ccb->p_callback) { + p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + } gap_release_ccb (p_ccb); } } @@ -964,7 +968,9 @@ static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed) L2CA_DISCONNECT_RSP (l2cap_cid); } - p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + if (p_ccb->p_callback) { + p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED); + } gap_release_ccb (p_ccb); } @@ -997,7 +1003,9 @@ static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg) p_ccb->rx_queue_size, p_msg->len); */ - p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL); + if (p_ccb->p_callback) { + p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL); + } } else { osi_free (p_msg); } @@ -1030,7 +1038,9 @@ static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested) p_ccb->is_congested = is_congested; event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED; - p_ccb->p_callback (p_ccb->gap_handle, event); + if (p_ccb->p_callback) { + p_ccb->p_callback (p_ccb->gap_handle, event); + } if (!is_congested) { while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {