Merge branch 'bugfix/msbc_oob_read_v6.1' into 'release/v6.1'

fix(bt/bluedroid): fixed OOB read dring mSBC sync word check (v6.1)

See merge request espressif/esp-idf!52766
This commit is contained in:
Jiang Jiang Jian
2026-09-15 17:16:03 +08:00
3 changed files with 33 additions and 7 deletions

View File

@@ -586,6 +586,12 @@ uint32_t bta_ag_sco_co_out_data(UINT8 *p_buf)
*******************************************************************************/
void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
{
if (p_buf->len < HCI_SCO_PREAMBLE_SIZE) {
APPL_TRACE_ERROR("%s SCO packet too short: %u", __func__, p_buf->len);
osi_free(p_buf);
return;
}
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
UINT8 * const data_end = p + p_buf->len;
UINT8 pkt_size = 0;
@@ -638,7 +644,7 @@ void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
}
btc_hf_audio_data_cb_to_app((uint8_t *)p_new_buf, (uint8_t *)p_data, data_len,
bta_ag_co_cb.is_bad_frame);
bta_ag_co_cb.is_bad_frame = FALSE;
bta_ag_co_cb.is_bad_frame = false;
}
}
bta_ag_co_cb.rx_first_pkt = !bta_ag_co_cb.rx_first_pkt;
@@ -648,15 +654,16 @@ void bta_ag_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
pkt_size = BTM_MSBC_FRAME_SIZE;
}
UINT16 data_len = pkt_size;
if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
if (data_len >= 2 && BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
/* H2 header sync word found, skip */
p += 2;
data_len -= 2;
}
else if (!bta_ag_co_cb.is_bad_frame){
} else if (data_len >= 1 && !bta_ag_co_cb.is_bad_frame) {
/* not a bad frame, assume as H1 header */
p += 1;
data_len -= 1;
} else {
bta_ag_co_cb.is_bad_frame = true;
}
btc_hf_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, data_len, bta_ag_co_cb.is_bad_frame);
bta_ag_co_cb.is_bad_frame = false;

View File

@@ -499,12 +499,24 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
return;
}
if (p_buf->len < HCI_SCO_PREAMBLE_SIZE) {
APPL_TRACE_ERROR("%s SCO packet too short: %u", __func__, p_buf->len);
osi_free(p_buf);
return;
}
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
UINT8 * const data_end = p + p_buf->len;
UINT8 pkt_size = 0;
STREAM_SKIP_UINT16(p);
STREAM_TO_UINT8 (pkt_size, p);
UINT16 rem = (data_end > p) ? (UINT16)(data_end - p) : 0;
if (pkt_size > rem) {
pkt_size = (UINT8)rem;
}
#if (BTC_HFP_EXT_CODEC == TRUE)
if (hf_air_mode == BTM_SCO_AIR_MODE_CVSD) {
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, pkt_size, status != BTM_SCO_DATA_CORRECT);
@@ -559,15 +571,16 @@ void bta_hf_client_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status)
pkt_size = BTM_MSBC_FRAME_SIZE;
}
UINT16 data_len = pkt_size;
if (BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
if (data_len >= 2 && BTA_HF_H2_HEADER_SYNC_WORD_CHECK(p)) {
/* H2 header sync word found, skip */
p += 2;
data_len -= 2;
}
else if (!bta_hf_client_co_cb.is_bad_frame){
} else if (data_len >= 1 && !bta_hf_client_co_cb.is_bad_frame) {
/* not a bad frame, assume as H1 header */
p += 1;
data_len -= 1;
} else {
bta_hf_client_co_cb.is_bad_frame = true;
}
btc_hf_client_audio_data_cb_to_app((uint8_t *)p_buf, (uint8_t *)p, data_len, bta_hf_client_co_cb.is_bad_frame);
bta_hf_client_co_cb.is_bad_frame = false;

View File

@@ -479,6 +479,12 @@ void btm_route_sco_data(BT_HDR *p_msg)
UINT8 pkt_size = 0;
UINT8 pkt_status = 0;
if (len < HCI_SCO_PREAMBLE_SIZE) {
BTM_TRACE_WARNING("SCO packet too short: %u", len);
osi_free(p_msg);
return;
}
/* Extract Packet_Status_Flag and handle */
STREAM_TO_UINT16 (handle, p);
pkt_status = HCID_GET_EVENT(handle);