-
Notifications
You must be signed in to change notification settings - Fork 7.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
esp_ble_resolve_adv_data Trigger crash (IDFGH-11791) #12886
Comments
I tried to fix it this way,I wonder if this problem can be solved UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
{
UINT8 *p = p_adv;
UINT8 length;
UINT8 adv_type;
BTM_TRACE_API("BTM_CheckAdvData type=0x%02X", type);
STREAM_TO_UINT8(length, p);
while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX)) {
STREAM_TO_UINT8(adv_type, p);
if ( adv_type == type ) {
/* length doesn't include itself */
*p_length = length - 1; /* minus the length of type */
return p;
}
p += length - 1; /* skip the length of data */
//mz_fix_start
//广播里的length字段出现错误,可能是对端发了一个错误的广播或者其它原因导致数据被污染,
//这里判断一下防止内存越界
if(p >= p_adv + BTM_BLE_CACHE_ADV_DATA_MAX){
break;
}
//mz_fix_end
STREAM_TO_UINT8(length, p);
}
*p_length = 0;
return NULL;
} |
When BTM_BLE_CACHE_ADV_DATA_MAX is greater than p_length, two wrong types and lengths will be accessed illegally, 09:42:33.475 E (13208) BT_BTM: 182 adv invalid len.
09:42:33.480 I (00:00:12.463) BT_BTM: addr = 5c:cd:7c:57:c0:61
09:42:33.491 I (00:00:12.463) BT_BTM: 02 01 06 03 03 27 18 15 16 27 18 03 ab 5c cd 7c
09:42:33.497 I (00:00:12.470) BT_BTM: 57 c0 61 09 88 18 00 05 05 12 40 00 00 b6 fb |
Could you please try version 4.4 or later to see if there are any issues? |
Can you provide relevant patches for repair? Because my product has been released based on version 4.3.1, I cannot change the version |
@maenkai |
It's not duplicated in the actual test, it's code //handle
static void handle_scan_result(uint8_t *ble_data, uint16_t length, uint8_t addr[6], uint8_t addr_type, int8_t rssi, bool from_mesh) {
uint16_t company_id = 0;
uint32_t device_type = 0xffffffff;
uint8_t *manuf_data = NULL;
uint8_t manuf_data_len = 0;
manuf_data = esp_ble_resolve_adv_data(ble_data,
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE,
&manuf_data_len);
if (manuf_data == NULL) {
return;
}
//doing..............
}
//from gap evetn
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT:
mz_handle_scan_result(scan_result->scan_rst.ble_adv,
scan_result->scan_rst.adv_data_len,
scan_result->scan_rst.bda,
scan_result->scan_rst.ble_addr_type,
scan_result->scan_rst.rssi,
false);
break;
default:
break;
}
break;
}
//from mesh event
switch (event) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT: {
mz_handle_scan_result(param->scan_ble_adv_pkt.data,
param->scan_ble_adv_pkt.length,
param->scan_ble_adv_pkt.addr,
param->scan_ble_adv_pkt.addr_type,
param->scan_ble_adv_pkt.rssi,
true);
break;
} |
Not 100% in the actual test. //handle
static void handle_scan_result(uint8_t *ble_data, uint16_t length, uint8_t addr[6], uint8_t addr_type, int8_t rssi, bool from_mesh) {
uint16_t company_id = 0;
uint32_t device_type = 0xffffffff;
uint8_t *manuf_data = NULL;
uint8_t manuf_data_len = 0;
manuf_data = esp_ble_resolve_adv_data(ble_data,
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE,
&manuf_data_len);
if (manuf_data == NULL) {
return;
}
//doing..............
}
//from gap evetn
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT:
handle_scan_result(scan_result->scan_rst.ble_adv,
scan_result->scan_rst.adv_data_len,
scan_result->scan_rst.bda,
scan_result->scan_rst.ble_addr_type,
scan_result->scan_rst.rssi,
false);
break;
default:
break;
}
break;
}
//from mesh event
switch (event) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT: {
handle_scan_result(param->scan_ble_adv_pkt.data,
param->scan_ble_adv_pkt.length,
param->scan_ble_adv_pkt.addr,
param->scan_ble_adv_pkt.addr_type,
param->scan_ble_adv_pkt.rssi,
true);
break;
} |
Can you print the adv data before the crash? |
OK,I need time to recreate |
According to your description, there might be a crash issue when encountering specific adv data.
Therefore, if you can provide ADV data that may lead to a crash, it would be very helpful. |
I didn't capture the broadcast that caused the crash in the real world.
|
param[out] length - return the length of ADV data not including type
*/ |
In the mesh scan event callback, how to ensure that the data range is greater than or equal to BTM_BLE_CACHE_ADV_DATA_MAX?
struct {
uint8_t addr[6]; /*!< Device address */
uint8_t addr_type; /*!< Device address type */
uint8_t adv_type; /*!< Advertising data type */
uint8_t *data; /*!< Advertising data */
uint16_t length; /*!< Advertising data length */
int8_t rssi; /*!< RSSI of the advertising packet */
} scan_ble_adv_pkt; /*!< Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT */
} esp_ble_mesh_ble_cb_param_t;
switch (event) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT: {
handle_scan_result(param->scan_ble_adv_pkt.data,
param->scan_ble_adv_pkt.length,
param->scan_ble_adv_pkt.addr,
param->scan_ble_adv_pkt.addr_type,
param->scan_ble_adv_pkt.rssi,
true);
break;
} |
Sorry for writing the wrong demo, after modifying it correctly, you can see that the pointer p still accesses addresses that are out of range, which is a serious problem.
// ESP_BLE_ADV_DATA_LEN_MAX = 31 ESP_BLE_SCAN_RSP_DATA_LEN_MAX = 31
uint8_t test_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX] = {
0x02, 0x01, 0x06,
0x03, 0x03, 0x27, 0x18,
0x15, 0x16, 0x27, 0x18, 0x03, 0xab, 0x5c, 0xcd, 0x7c, 0x57, 0xc0, 0x61, 0x09, 0x88, 0x18, 0x00, 0x05, 0x05, 0x12, 0x40, 0x00, 0x00,
0xff, 0xfb
};
uint8_t manuf_data_len = 29;
esp_ble_resolve_adv_data(test_adv,
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE,
&manuf_data_len);
UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
{
UINT8 *p = p_adv;
UINT8 length;
UINT8 adv_type;
BTM_TRACE_API("BTM_CheckAdvData type=0x%02X", type);
STREAM_TO_UINT8(length, p);
while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX)) {
STREAM_TO_UINT8(adv_type, p);
if ( adv_type == type ) {
/* length doesn't include itself */
*p_length = length - 1; /* minus the length of type */
return p;
}
p += length - 1; /* skip the length of data */
printf("length is %d p = %p end = %p\r\n",length, p , p_adv + BTM_BLE_CACHE_ADV_DATA_MAX);
STREAM_TO_UINT8(length, p);
}
*p_length = 0;
return NULL;
}
17:17:03.788 length is 2 p = 0x3ffbcdf3 end = 0x3ffbce2e
17:17:03.794 length is 3 p = 0x3ffbcdf7 end = 0x3ffbce2e
17:17:03.800 length is 21 p = 0x3ffbce0d end = 0x3ffbce2e
17:17:03.802 length is 255 p = 0x3ffbcf0d end = 0x3ffbce2e |
@maenkai |
I need to test it for a long time and get back to you with the results |
Hi, |
Answers checklist.
IDF version.
v4.3.1
Espressif SoC revision.
ESP32D-WROVE
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32D-WROVE
Power Supply used.
USB
What is the expected behavior?
The scan adv is normal
What is the actual behavior?
Trigger crash
Steps to reproduce.
Run on standby for a period of time
Debug Logs.
More Information.
No response
The text was updated successfully, but these errors were encountered: