mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(ble_iso): Fix null dereference may happened during BIG/CIG creation
This commit is contained in:
@@ -1656,10 +1656,27 @@ static bool is_advanced_cig_param(const struct bt_iso_cig_param *param)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This probe runs before valid_cig_param(); guard structure here so
|
||||||
|
* caller misuse (NULL cis_channels/cis/qos, or an over-reported num_cis)
|
||||||
|
* falls through to that check's -EINVAL instead of a NULL or
|
||||||
|
* out-of-bounds deref in this probe.
|
||||||
|
*/
|
||||||
|
if (param->cis_channels == NULL ||
|
||||||
|
param->num_cis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
||||||
|
param->num_cis > CONFIG_BT_ISO_MAX_CHAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if any of the CIS contain any test-param-only values */
|
/* Check if any of the CIS contain any test-param-only values */
|
||||||
for (uint8_t i = 0U; i < param->num_cis; i++) {
|
for (uint8_t i = 0U; i < param->num_cis; i++) {
|
||||||
const struct bt_iso_chan *cis = param->cis_channels[i];
|
const struct bt_iso_chan *cis = param->cis_channels[i];
|
||||||
const struct bt_iso_chan_qos *qos = cis->qos;
|
const struct bt_iso_chan_qos *qos;
|
||||||
|
|
||||||
|
if (cis == NULL || cis->qos == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
qos = cis->qos;
|
||||||
|
|
||||||
if (qos->num_subevents > 0U) {
|
if (qos->num_subevents > 0U) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1785,6 +1802,14 @@ static bool valid_cig_param(const struct bt_iso_cig_param *param, bool advanced,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Not guaranteed by all callers (bt_iso_cig_reconfigure does not pre-check
|
||||||
|
* it); the per-CIS loop below dereferences cis_channels[i] directly.
|
||||||
|
*/
|
||||||
|
if (param->cis_channels == NULL) {
|
||||||
|
LOG_ERR("CisChansNull");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (param->num_cis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
if (param->num_cis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
||||||
param->num_cis > CONFIG_BT_ISO_MAX_CHAN) {
|
param->num_cis > CONFIG_BT_ISO_MAX_CHAN) {
|
||||||
LOG_ERR("TooLargeNumCis[%u][%u]",
|
LOG_ERR("TooLargeNumCis[%u][%u]",
|
||||||
@@ -2659,17 +2684,32 @@ static bool is_advanced_big_param(const struct bt_iso_big_create_param *param)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This probe runs before valid_big_param(); guard structure here so
|
||||||
|
* caller misuse (NULL bis_channels/bis/qos/qos->tx, or an over-reported
|
||||||
|
* num_bis) falls through to that check's -EINVAL instead of a NULL or
|
||||||
|
* out-of-bounds deref in this probe.
|
||||||
|
*/
|
||||||
|
if (param->bis_channels == NULL ||
|
||||||
|
param->num_bis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
||||||
|
param->num_bis > CONFIG_BT_ISO_MAX_CHAN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if any of the CIS contain any test-param-only values */
|
/* Check if any of the CIS contain any test-param-only values */
|
||||||
for (uint8_t i = 0U; i < param->num_bis; i++) {
|
for (uint8_t i = 0U; i < param->num_bis; i++) {
|
||||||
const struct bt_iso_chan *bis = param->bis_channels[i];
|
const struct bt_iso_chan *bis = param->bis_channels[i];
|
||||||
const struct bt_iso_chan_qos *qos = bis->qos;
|
const struct bt_iso_chan_qos *qos;
|
||||||
|
|
||||||
|
if (bis == NULL || bis->qos == NULL || bis->qos->tx == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
qos = bis->qos;
|
||||||
|
|
||||||
if (qos->num_subevents > 0U) {
|
if (qos->num_subevents > 0U) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(qos->tx != NULL && "BigWithNullTx");
|
|
||||||
|
|
||||||
if (qos->tx->max_pdu > 0U || qos->tx->burst_number > 0U) {
|
if (qos->tx->max_pdu > 0U || qos->tx->burst_number > 0U) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2693,6 +2733,17 @@ static bool valid_big_param(const struct bt_iso_big_create_param *param, bool ad
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bound num_bis before the per-BIS loop so a caller that over-reports it
|
||||||
|
* cannot drive the loop past the bis_channels[] array.
|
||||||
|
*/
|
||||||
|
CHECKIF(param->num_bis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
||||||
|
param->num_bis > CONFIG_BT_ISO_MAX_CHAN) {
|
||||||
|
LOG_ERR("TooLargeNumBis[%u][%u][%u]",
|
||||||
|
param->num_bis, BT_ISO_MAX_GROUP_ISO_COUNT, CONFIG_BT_ISO_MAX_CHAN);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t i = 0; i < param->num_bis; i++) {
|
for (uint8_t i = 0; i < param->num_bis; i++) {
|
||||||
struct bt_iso_chan *bis = param->bis_channels[i];
|
struct bt_iso_chan *bis = param->bis_channels[i];
|
||||||
|
|
||||||
@@ -2736,14 +2787,6 @@ static bool valid_big_param(const struct bt_iso_big_create_param *param, bool ad
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKIF(param->num_bis > BT_ISO_MAX_GROUP_ISO_COUNT ||
|
|
||||||
param->num_bis > CONFIG_BT_ISO_MAX_CHAN) {
|
|
||||||
LOG_ERR("TooLargeNumBis[%u][%u]",
|
|
||||||
param->num_bis, MAX(CONFIG_BT_ISO_MAX_CHAN, BT_ISO_MAX_GROUP_ISO_COUNT));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECKIF(!IN_RANGE(param->interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
|
CHECKIF(!IN_RANGE(param->interval, BT_ISO_SDU_INTERVAL_MIN, BT_ISO_SDU_INTERVAL_MAX)) {
|
||||||
LOG_ERR("InvInterval[%u]", param->interval);
|
LOG_ERR("InvInterval[%u]", param->interval);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user