fix(bt/bluedroid): fixed the vulerabilities from AI code review in SPP

This commit is contained in:
Jin Cheng
2026-03-30 17:38:46 +08:00
parent 2839dacbc2
commit ed270d71c8
17 changed files with 133 additions and 75 deletions
@@ -84,7 +84,7 @@ UINT16 GOEPC_Open(tOBEX_SVR_INFO *svr, tGOEPC_EVT_CBACK callback, UINT16 *out_ha
p_ccb = goepc_allocate_ccb();
if (p_ccb == NULL) {
ret = GOEP_NO_RESOURCES;
ret = GOEP_NO_RESOURCES;
break;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -183,7 +183,7 @@ void goepc_obex_callback(UINT16 handle, UINT8 event, tOBEX_MSG *msg)
case OBEX_DISCONNECT_EVT:
/* when we received this event, obex connection already disconnect */
p_ccb->obex_handle = 0;
goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT;;
goepc_sm_event = GOEPC_SM_EVENT_DISCONNECT;
exec_sm = TRUE;
break;
case OBEX_CONGEST_EVT:
@@ -316,11 +316,16 @@ static void goepc_sm_state_opening(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *
GOEPC_TRACE_ERROR("goepc_sm_state_opening received unexpected response from peer\n");
if (p_data->pkt != NULL) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
goepc_sm_act_disconnect(p_ccb);
break;
default:
GOEPC_TRACE_ERROR("goepc_sm_state_opening unexpected event: 0x%x\n", event);
if (p_data->pkt != NULL) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
break;
}
}
@@ -349,6 +354,10 @@ static void goepc_sm_state_opened_idle(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DA
break;
default:
GOEPC_TRACE_ERROR("goepc_sm_state_opened_idle unexpected event: 0x%x\n", event);
if (p_data->pkt != NULL) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
break;
}
}
@@ -374,6 +383,10 @@ static void goepc_sm_state_opened_req(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DAT
break;
default:
GOEPC_TRACE_ERROR("goepc_sm_state_opened_req unexpected event: 0x%x\n", event);
if (p_data->pkt != NULL) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
break;
}
}
@@ -396,6 +409,10 @@ static void goepc_sm_state_opened_rsp(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DAT
break;
default:
GOEPC_TRACE_ERROR("goepc_sm_state_opened_rsp unexpected event: 0x%x\n", event);
if (p_data->pkt != NULL) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
break;
}
}
@@ -431,10 +448,14 @@ BOOLEAN goepc_check_obex_req_allow(UINT8 state, BOOLEAN final)
void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
{
bool free_pkt = false;
bool has_pkt = false;
switch (p_ccb->state)
{
case GOEPC_STATE_INIT:
/* do nothing */
free_pkt = true;
break;
case GOEPC_STATE_OPENING:
goepc_sm_state_opening(p_ccb, event, p_data);
@@ -449,9 +470,34 @@ void goepc_sm_execute(tGOEPC_CCB *p_ccb, UINT8 event, tGOEPC_DATA *p_data)
goepc_sm_state_opened_rsp(p_ccb, event, p_data);
break;
default:
free_pkt = true;
GOEPC_TRACE_ERROR("goepc_sm_execute unexpected state: 0x%x\n", p_ccb->state);
break;
}
switch (event)
{
case GOEPC_SM_EVENT_REQ:
/* falls through */
case GOEPC_SM_EVENT_REQ_FB:
/* falls through */
case GOEPC_SM_EVENT_RSP:
/* falls through */
case GOEPC_SM_EVENT_RSP_FB:
/* falls through */
has_pkt = true;
break;
default:
has_pkt = false;
break;
}
if (has_pkt && free_pkt) {
if (p_data->pkt) {
osi_free(p_data->pkt);
p_data->pkt = NULL;
}
}
}
static void goepc_srm_sm_act_req(tGOEPC_CCB *p_ccb, BOOLEAN srm_en, BOOLEAN srm_wait)
@@ -38,7 +38,7 @@ static inline void obex_server_to_tl_server(tOBEX_SVR_INFO *server, tOBEX_TL_SVR
}
}
static inline void obex_updata_packet_length(BT_HDR *p_buf, UINT16 len)
static inline void obex_update_packet_length(BT_HDR *p_buf, UINT16 len)
{
UINT8 *p_pkt_len = (UINT8 *)(p_buf + 1) + p_buf->offset + 1;
UINT16_TO_BE_FIELD(p_pkt_len, len);
@@ -66,12 +66,12 @@ UINT16 OBEX_Init(void)
#endif /* #if (OBEX_DYNAMIC_MEMORY) */
memset(&obex_cb, 0, sizeof(tOBEX_CB));
obex_cb.tl_ops[OBEX_OVER_L2CAP] = obex_tl_l2cap_ops_get();
if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->init != NULL) {
if (obex_cb.tl_ops[OBEX_OVER_L2CAP] && obex_cb.tl_ops[OBEX_OVER_L2CAP]->init) {
obex_cb.tl_ops[OBEX_OVER_L2CAP]->init(obex_tl_l2cap_callback);
}
#if (RFCOMM_INCLUDED == TRUE)
obex_cb.tl_ops[OBEX_OVER_RFCOMM] = obex_tl_rfcomm_ops_get();
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init != NULL) {
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM] && obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init) {
obex_cb.tl_ops[OBEX_OVER_RFCOMM]->init(obex_tl_rfcomm_callback);
}
#endif
@@ -89,11 +89,11 @@ UINT16 OBEX_Init(void)
*******************************************************************************/
void OBEX_Deinit(void)
{
if (obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit != NULL) {
if (obex_cb.tl_ops[OBEX_OVER_L2CAP] && obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit) {
obex_cb.tl_ops[OBEX_OVER_L2CAP]->deinit();
}
#if (RFCOMM_INCLUDED == TRUE)
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit != NULL) {
if (obex_cb.tl_ops[OBEX_OVER_RFCOMM] && obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit) {
obex_cb.tl_ops[OBEX_OVER_RFCOMM]->deinit();
}
#endif
@@ -327,7 +327,7 @@ UINT16 OBEX_BuildRequest(tOBEX_PARSE_INFO *info, UINT16 buff_size, BT_HDR **out_
}
buff_size += sizeof(BT_HDR) + OBEX_BT_HDR_MIN_OFFSET + OBEX_BT_HDR_RESERVE_LEN;
BT_HDR *p_buf= (BT_HDR *)osi_malloc(buff_size);
BT_HDR *p_buf = (BT_HDR *)osi_malloc(buff_size);
if (p_buf == NULL) {
return OBEX_NO_RESOURCES;
}
@@ -780,10 +780,10 @@ UINT8 *OBEX_GetNextHeader(BT_HDR *pkt, tOBEX_PARSE_INFO *info)
if (pkt == NULL || info == NULL) {
return NULL;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
if (info->next_header_pos == 0 || info->next_header_pos >= pkt->len) {
return NULL;
}
UINT8 *p_data = (UINT8 *)(pkt + 1) + pkt->offset;
UINT8 *header = p_data + info->next_header_pos;
UINT16 header_len = OBEX_GetHeaderLength(header);
info->next_header_pos += header_len;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -554,7 +554,7 @@ void obex_tl_l2cap_congestion_status_ind(UINT16 lcid, BOOLEAN is_congested)
** other APIs
**
*******************************************************************************/
void obex_tl_l2cap_init(tOBEX_TL_CBACK callback)
void obex_tl_l2cap_init(tOBEX_TL_CBACK *callback)
{
assert(callback != NULL);
#if (OBEX_DYNAMIC_MEMORY)
@@ -587,7 +587,7 @@ void obex_tl_l2cap_init(tOBEX_TL_CBACK callback)
/*******************************************************************************
**
** Function obex_tl_l2cap_init
** Function obex_tl_l2cap_deinit
**
** Description Deinitialize OBEX over L2CAP transport layer
**
@@ -674,7 +674,7 @@ void obex_tl_l2cap_disconnect(UINT16 hdl)
**
** Function obex_tl_l2cap_send_data
**
** Description Start the process of establishing a L2CAP connection
** Description Send data on an established L2CAP connection
**
** Returns OBEX_TL_SUCCESS, if data accepted
** OBEX_TL_CONGESTED, if data accepted and the channel is congested
@@ -357,6 +357,8 @@ UINT16 obex_tl_rfcomm_send(UINT16 handle, BT_HDR *p_buf)
if (PORT_Write(p_ccb->rfc_handle, p_buf) == PORT_SUCCESS) {
ret = OBEX_TL_SUCCESS;
} else {
osi_free(p_buf);
}
} while (0);
return ret;
@@ -114,7 +114,9 @@ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
RFCOMM_TRACE_API ("RFCOMM_CreateConnection() BDA: %02x-%02x-%02x-%02x-%02x-%02x",
bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
*p_handle = 0;
if (p_handle) {
*p_handle = 0;
}
if (( scn == 0 ) || (scn >= PORT_MAX_RFC_PORTS )) {
/* Server Channel Number(SCN) should be in range 1...30 */
@@ -170,7 +172,9 @@ int RFCOMM_CreateConnection (UINT16 uuid, UINT8 scn, BOOLEAN is_server,
RFCOMM_TRACE_EVENT ("RFCOMM_CreateConnection dlci:%d signal state:0x%x", dlci, p_port->default_signal_state);
*p_handle = p_port->inx;
if (p_handle) {
*p_handle = p_port->inx;
}
p_port->state = PORT_STATE_OPENING;
p_port->uuid = uuid;
@@ -421,7 +421,7 @@ tRFC_MCB *rfc_find_lcid_mcb (UINT16 lcid)
**
** Function rfc_save_lcid_mcb
**
** Description This function returns MCB block supporting local cid
** Description This function saves MCB block supporting local cid
**
*******************************************************************************/
void rfc_save_lcid_mcb (tRFC_MCB *p_mcb, UINT16 lcid)
@@ -119,6 +119,9 @@ void rfc_mx_sm_execute (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
rfc_mx_sm_state_disc_wait_ua (p_mcb, event, p_data);
break;
default:
RFCOMM_TRACE_DEBUG("invalid state:%d\n", p_mcb->state);
break;
}
}
@@ -215,7 +218,7 @@ void rfc_mx_sm_state_wait_conn_cnf (tRFC_MCB *p_mcb, UINT16 event, void *p_data)
return;
/* There is some new timing so that Config Ind comes before security is completed
so we are still waiting fo the confirmation. */
so we are still waiting for the confirmation. */
case RFC_MX_EVENT_CONF_IND:
rfc_mx_conf_ind (p_mcb, (tL2CAP_CFG_INFO *)p_data);
return;
@@ -597,8 +597,7 @@ void rfc_process_rpn (tRFC_MCB *p_mcb, BOOLEAN is_command,
}
/* If we are not awaiting response just ignore it */
p_port = port_find_mcb_dlci_port (p_mcb, p_frame->dlci);
if ((p_port == NULL) || !(p_port->rfc.expected_rsp & (RFC_RSP_RPN | RFC_RSP_RPN_REPLY))) {
if (!(p_port->rfc.expected_rsp & (RFC_RSP_RPN | RFC_RSP_RPN_REPLY))) {
return;
}
@@ -359,7 +359,7 @@ void RFCOMM_LineStatusReq (tRFC_MCB *p_mcb, UINT8 dlci, UINT8 status)
*******************************************************************************/
void RFCOMM_DlcReleaseReq (tRFC_MCB *p_mcb, UINT8 dlci)
{
rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, 0);
rfc_port_sm_execute(port_find_mcb_dlci_port (p_mcb, dlci), RFC_EVENT_CLOSE, NULL);
}
@@ -527,16 +527,12 @@ void rfc_bqb_send_msc_cmd(BD_ADDR cert_pts_addr)
UINT8 dlci;
BOOLEAN get_dlci = FALSE;
tPORT *p_port;
tPORT_CTRL *p_pars;
tPORT_CTRL pars;
tRFC_MCB *p_mcb;
if ((p_pars = (tPORT_CTRL *)osi_malloc(sizeof(tPORT_CTRL))) == NULL) {
return;
}
p_pars->modem_signal = 0;
p_pars->break_signal = 0;
p_pars->fc = TRUE;
pars.modem_signal = 0;
pars.break_signal = 0;
pars.fc = TRUE;
p_mcb = port_find_mcb (cert_pts_addr);
@@ -549,12 +545,11 @@ void rfc_bqb_send_msc_cmd(BD_ADDR cert_pts_addr)
}
}
if (get_dlci) {
rfc_send_msc(p_mcb, dlci, TRUE, p_pars);
if (get_dlci && p_mcb) {
rfc_send_msc(p_mcb, dlci, TRUE, &pars);
} else {
RFCOMM_TRACE_ERROR ("Get dlci fail");
}
osi_free(p_pars);
}
#endif /* BT_RFCOMM_BQB_INCLUDED */
@@ -794,7 +789,7 @@ void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
RFCOMM_TRACE_ERROR("Illegal MX Frame len:%d < 2", length);
osi_free(p_buf);
return;
}
}
p_rx_frame->ea = *p_data & RFCOMM_EA;
p_rx_frame->cr = (*p_data & RFCOMM_CR_MASK) >> RFCOMM_SHIFT_CR;
@@ -991,7 +986,7 @@ void rfc_process_mx_message (tRFC_MCB *p_mcb, BT_HDR *p_buf)
if (!ea || !cr || !p_rx_frame->dlci
|| !RFCOMM_VALID_DLCI (p_rx_frame->dlci)) {
RFCOMM_TRACE_ERROR ("Bad RPN frame");
RFCOMM_TRACE_ERROR ("Bad RLS frame");
break;
}
@@ -121,6 +121,10 @@ BOOLEAN rfc_check_fcs (UINT16 len, UINT8 *p, UINT8 received_fcs)
return (fcs == 0xCF);
}
void osi_free_fun(void *p)
{
osi_free(p);
}
/*******************************************************************************
**
@@ -168,7 +172,7 @@ tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
p_mcb = &rfc_cb.port.rfc_mcb[j];
if (rfc_cb.port.rfc_mcb[j].state == RFC_MX_STATE_IDLE) {
/* New multiplexer control block */
fixed_queue_free(p_mcb->cmd_q, NULL);
fixed_queue_free(p_mcb->cmd_q, osi_free_fun);
rfc_timer_free(p_mcb);
memset (p_mcb, 0, sizeof (tRFC_MCB));
memcpy (p_mcb->bd_addr, bd_addr, BD_ADDR_LEN);
@@ -188,15 +192,11 @@ tRFC_MCB *rfc_alloc_multiplexer_channel (BD_ADDR bd_addr, BOOLEAN is_initiator)
return (NULL);
}
void osi_free_fun(void *p)
{
osi_free(p);
}
/*******************************************************************************
**
** Function rfc_release_multiplexer_channel
**
** Description This function returns existing or new control block for
** Description This function releases existing control block for
** the BD_ADDR.
**
*******************************************************************************/
@@ -299,7 +299,7 @@ void rfc_port_timer_stop (tPORT *p_port)
*******************************************************************************/
void rfc_port_timer_free (tPORT *p_port)
{
RFCOMM_TRACE_EVENT ("rfc_port_timer_stop");
RFCOMM_TRACE_EVENT ("rfc_port_timer_free");
btu_free_timer (&p_port->rfc.tle);
memset(&p_port->rfc.tle, 0, sizeof(TIMER_LIST_ENT));