diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 59fe63d0a5..858d2fb45d 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -45,7 +45,8 @@ #define BTA_DM_MSG_LEN 50 -#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id)) +/* Use 1ULL to avoid UB: 1 << 32 is undefined when int is 32-bit (C11 ยง6.5.7) */ +#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) ((UINT32)(1ULL << (id))) /* DM events */ enum { diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c index 09e1aea2fa..bbf2b346bf 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c @@ -108,7 +108,6 @@ const tBTA_GATTC_ACTION bta_gattc_action[] = { #define BTA_GATTC_ACTIONS 1 /* number of actions */ #define BTA_GATTC_NEXT_STATE 1 /* position of next state */ #define BTA_GATTC_NUM_COLS 2 /* number of columns in state tables */ - /* state table for idle state */ static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = { /* Event Action 1 Next state */ @@ -298,6 +297,11 @@ BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_D event &= 0x00FF; + if (event >= sizeof(bta_gattc_st_idle) / sizeof(bta_gattc_st_idle[0])) { + APPL_TRACE_ERROR("bta_gattc_sm_execute: invalid event index %d", event); + return TRUE; + } + /* set next state */ p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE]; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index bc329b775b..1786835e33 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -125,8 +125,13 @@ tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0]; UINT8 i; + if (remote_bda == NULL) { + return NULL; + } + for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) { if (p_clcb->in_use && + p_clcb->p_rcb != NULL && p_clcb->p_rcb->client_if == client_if && p_clcb->transport == transport && bdcmp(p_clcb->bda, remote_bda) == 0) { @@ -244,16 +249,16 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb) if (p_clcb) { p_srcb = p_clcb->p_srcb; - if (p_srcb->num_clcb) { + if (p_srcb != NULL && p_srcb->num_clcb) { p_srcb->num_clcb --; } - if (p_clcb->p_rcb->num_clcb) { + if (p_clcb->p_rcb != NULL && p_clcb->p_rcb->num_clcb) { p_clcb->p_rcb->num_clcb --; } /* if the srcb is no longer needed, reset the state */ - if ( p_srcb->num_clcb == 0) { + if (p_srcb != NULL && p_srcb->num_clcb == 0) { p_srcb->connected = FALSE; p_srcb->state = BTA_GATTC_SERV_IDLE; p_srcb->mtu = 0; @@ -268,13 +273,13 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb) #endif } - if ( p_clcb->p_q_cmd != NULL && !list_contains(p_clcb->p_cmd_list, p_clcb->p_q_cmd)){ + if (p_clcb->p_q_cmd != NULL && + (p_clcb->p_cmd_list == NULL || !list_contains(p_clcb->p_cmd_list, p_clcb->p_q_cmd))) { osi_free(p_clcb->p_q_cmd); p_clcb->p_q_cmd = NULL; } // don't forget to clear the command queue before dealloc the clcb. - list_clear(p_clcb->p_cmd_list); - osi_free((void *)p_clcb->p_cmd_list); + list_free(p_clcb->p_cmd_list); p_clcb->p_cmd_list = NULL; //osi_free_and_reset((void **)&p_clcb->p_q_cmd); memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB)); @@ -970,6 +975,10 @@ tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg) { tBTA_GATTC_CLCB *p_clcb = NULL; + if (p_msg == NULL) { + return NULL; + } + if (p_msg->int_conn.role == HCI_ROLE_SLAVE) { bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda); } @@ -1005,6 +1014,10 @@ tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg) { tBTA_GATTC_CLCB *p_clcb = NULL; + if (p_msg == NULL) { + return NULL; + } + bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda); if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL) { /* connection attempt failed, send connection callback event */ @@ -1033,6 +1046,8 @@ void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src) switch (p_src->len) { case 0: + /* Invalid/empty UUID: zero p_dest so callers don't use garbage */ + memset(p_dest->uu, 0, sizeof(p_dest->uu)); break; case LEN_UUID_16: @@ -1041,8 +1056,8 @@ void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src) break; case LEN_UUID_32: - p_dest->uu[12] = p_src->uu.uuid16 & 0xff; - p_dest->uu[13] = (p_src->uu.uuid16 >> 8) & 0xff; + p_dest->uu[12] = p_src->uu.uuid32 & 0xff; + p_dest->uu[13] = (p_src->uu.uuid32 >> 8) & 0xff; p_dest->uu[14] = (p_src->uu.uuid32 >> 16) & 0xff; p_dest->uu[15] = (p_src->uu.uuid32 >> 24) & 0xff; break; @@ -1054,6 +1069,7 @@ void bta_to_btif_uuid(bt_uuid_t *p_dest, tBT_UUID *p_src) default: APPL_TRACE_ERROR("%s: Unknown UUID length %d!", __FUNCTION__, p_src->len); + memset(p_dest->uu, 0, sizeof(p_dest->uu)); break; } } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index 04bcb697f8..9688b5d2bc 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -872,7 +872,7 @@ void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg) tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_send_service_change.server_if); tBTA_GATTS_SERVICE_CHANGE service_change; tBTA_GATT_STATUS status = BTA_GATT_OK; - UINT16 addr[BD_ADDR_LEN] = {0}; + UINT8 addr[BD_ADDR_LEN] = {0}; if(memcmp(p_msg->api_send_service_change.remote_bda, addr, BD_ADDR_LEN) != 0) { BD_ADDR bd_addr; memcpy(bd_addr, p_msg->api_send_service_change.remote_bda, BD_ADDR_LEN); diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c index 06667a415b..f1d7d62e99 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c @@ -223,6 +223,7 @@ void BTA_GATTS_AddCharacteristic (UINT16 service_id, const tBT_UUID * p_char_u UINT16 len = 0; if(attr_val != NULL){ len = attr_val->attr_len; + APPL_TRACE_DEBUG("attr_val->attr_len = %x, attr_max_len = %x\n",attr_val->attr_len, attr_val->attr_max_len); } if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) osi_malloc(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) { memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR)); @@ -234,15 +235,22 @@ void BTA_GATTS_AddCharacteristic (UINT16 service_id, const tBT_UUID * p_char_u if(control !=NULL){ p_buf->control.auto_rsp = control->auto_rsp; } - if(attr_val != NULL){ - APPL_TRACE_DEBUG("!!!!!!attr_val->attr_len = %x\n",attr_val->attr_len); - APPL_TRACE_DEBUG("!!!!!!!attr_val->attr_max_len = %x\n",attr_val->attr_max_len); + + if(attr_val != NULL && len){ p_buf->attr_val.attr_len = attr_val->attr_len; p_buf->attr_val.attr_max_len = attr_val->attr_max_len; p_buf->attr_val.attr_val = (uint8_t *)osi_malloc(len); if(p_buf->attr_val.attr_val != NULL){ memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, len); + } else { + p_buf->attr_val.attr_len = 0; + p_buf->attr_val.attr_max_len = 0; + APPL_TRACE_ERROR("Allocate fail for %s\n", __func__); } + } else { + p_buf->attr_val.attr_len = 0; + p_buf->attr_val.attr_max_len = 0; + p_buf->attr_val.attr_val = NULL; } if (p_char_uuid) { @@ -499,6 +507,9 @@ void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value) if(value != NULL){ if((p_buf->value = (UINT8 *)osi_malloc(length)) != NULL){ memcpy(p_buf->value, value, length); + } else { + p_buf->length = 0; + APPL_TRACE_ERROR("Allocate fail for %s\n", __func__); } } diff --git a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c index ea1bc5a854..3bf41d9dab 100644 --- a/components/bt/host/bluedroid/bta/sys/bta_sys_main.c +++ b/components/bt/host/bluedroid/bta/sys/bta_sys_main.c @@ -103,6 +103,7 @@ enum { #define BTA_SYS_ACTIONS 2 /* number of actions */ #define BTA_SYS_NEXT_STATE 2 /* position of next state */ #define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */ +#define BTA_SYS_NUM_STATES 4 /* OFF, STARTING, ON, STOPPING */ /* state table for OFF state */ @@ -213,22 +214,39 @@ BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg) BOOLEAN freebuf = TRUE; tBTA_SYS_ST_TBL state_table; UINT8 action; + UINT8 evt_idx; int i; + if (p_msg == NULL) { + return freebuf; + } + + evt_idx = p_msg->event & 0x00ff; + if (evt_idx >= BTA_SYS_NUM_ACTIONS) { + APPL_TRACE_ERROR("bta_sys_sm_execute: event 0x%x out of range (evt_idx=%u)", p_msg->event, evt_idx); + return freebuf; + } + if (bta_sys_cb.state >= BTA_SYS_NUM_STATES) { + APPL_TRACE_ERROR("bta_sys_sm_execute: invalid state %u", bta_sys_cb.state); + return freebuf; + } + APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x\n", bta_sys_cb.state, p_msg->event); /* look up the state table for the current state */ state_table = bta_sys_st_tbl[bta_sys_cb.state]; /* update state */ - bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE]; + bta_sys_cb.state = state_table[evt_idx][BTA_SYS_NEXT_STATE]; /* execute action functions */ for (i = 0; i < BTA_SYS_ACTIONS; i++) { - if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE) { - (*bta_sys_action[action])( (tBTA_SYS_HW_MSG *) p_msg); - } else { + action = state_table[evt_idx][i]; + if (action == BTA_SYS_IGNORE) { break; } + if (action < BTA_SYS_NUM_ACTIONS) { + (*bta_sys_action[action])( (tBTA_SYS_HW_MSG *) p_msg); + } } return freebuf; @@ -598,16 +616,29 @@ void bta_alarm_cb(void *data) void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) { + osi_alarm_t *alarm = NULL; + assert(p_tle != NULL); // Get the alarm for this p_tle. osi_mutex_lock(&bta_alarm_lock, OSI_MUTEX_MAX_TIMEOUT); if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) { - hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0)); + alarm = osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0); + if (alarm == NULL) { + APPL_TRACE_ERROR("%s unable to create new alarm.", __func__); + osi_mutex_unlock(&bta_alarm_lock); + return; + } + if (!hash_map_set(bta_alarm_hash_map, p_tle, alarm)) { + APPL_TRACE_ERROR("%s unable to set alarm in map.", __func__); + osi_alarm_free(alarm); + osi_mutex_unlock(&bta_alarm_lock); + return; + } } osi_mutex_unlock(&bta_alarm_lock); - osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle); + alarm = hash_map_get(bta_alarm_hash_map, p_tle); if (alarm == NULL) { APPL_TRACE_ERROR("%s unable to create alarm.", __func__); return;