fix(bt/bluedroid): Prevent out-of-bounds access and add type check when resolving EIR data

This commit is contained in:
yangfeng
2025-08-11 17:54:32 +08:00
parent f5c986b213
commit 47c41de0b2
3 changed files with 54 additions and 7 deletions

View File

@@ -138,7 +138,27 @@ uint8_t *esp_bt_gap_resolve_eir_data(uint8_t *eir, esp_bt_eir_type_t type, uint8
return NULL;
}
return BTM_CheckEirData(eir, type, length);
switch (type) {
case ESP_BT_EIR_TYPE_FLAGS:
case ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID:
case ESP_BT_EIR_TYPE_CMPL_16BITS_UUID:
case ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID:
case ESP_BT_EIR_TYPE_CMPL_32BITS_UUID:
case ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID:
case ESP_BT_EIR_TYPE_CMPL_128BITS_UUID:
case ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME:
case ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME:
case ESP_BT_EIR_TYPE_TX_POWER_LEVEL:
case ESP_BT_EIR_TYPE_URL:
case ESP_BT_EIR_TYPE_MANU_SPECIFIC: {
return BTM_CheckEirData(eir, type, length);
}
default:
/*Error type*/
break;
}
return NULL;
}
esp_err_t esp_bt_gap_config_eir_data(esp_bt_eir_data_t *eir_data)

View File

@@ -88,7 +88,7 @@ typedef struct {
#define ESP_BT_EIR_TYPE_TX_POWER_LEVEL 0x0a /*!< Tx power level, value is 1 octet ranging from -127 to 127, unit is dBm*/
#define ESP_BT_EIR_TYPE_URL 0x24 /*!< Uniform resource identifier */
#define ESP_BT_EIR_TYPE_MANU_SPECIFIC 0xff /*!< Manufacturer specific data */
#define ESP_BT_EIR_TYPE_MAX_NUM 12 /*!< MAX number of EIR type */
#define ESP_BT_EIR_TYPE_MAX_NUM 12 /*!< MAX number of EIR type */
typedef uint8_t esp_bt_eir_type_t;

View File

@@ -2420,24 +2420,51 @@ tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
{
UINT8 *p = p_eir;
UINT8 *p_data_length = p_length;
UINT8 length;
UINT8 eir_type;
BTM_TRACE_API("BTM_CheckEirData type=0x%02X\n", type);
if (!p_length) {
if ((p_data_length = (UINT8 *)osi_malloc(sizeof(UINT8))) == NULL) {
BTM_TRACE_ERROR("%s: Memory allocation failed.", __func__);
return NULL;
}
}
STREAM_TO_UINT8(length, p);
while ( length && (p - p_eir <= HCI_EXT_INQ_RESPONSE_LEN)) {
while ( length ) {
STREAM_TO_UINT8(eir_type, p);
if ( eir_type == type ) {
if ((p + length - 1) > (p_eir + HCI_EXT_INQ_RESPONSE_LEN)) {
/*avoid memory overflow*/
*p_data_length = 0;
p = NULL;
goto exit;
}
/* length doesn't include itself */
*p_length = length - 1; /* minus the length of type */
return p;
*p_data_length = length - 1; /* minus the length of type */
goto exit;
}
p += length - 1; /* skip the length of data */
/* Break loop if eir data is in an incorrect format,
as it may lead to memory overflow */
if ( p >= p_eir + HCI_EXT_INQ_RESPONSE_LEN ) {
break;
}
STREAM_TO_UINT8(length, p);
}
*p_length = 0;
return NULL;
*p_data_length = 0;
p = NULL;
exit:
if (!p_length) {
osi_free(p_data_length);
}
return p;
}
/*******************************************************************************