mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 18:10:57 +02:00
fix(bt/bluedroid): Prevent out-of-bounds access and add type check when resolving EIR data
This commit is contained in:
@@ -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)
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
Reference in New Issue
Block a user