Bluetooth: LE: BAP: Check buf len before using it
Check whether the length of buf is consistent with the valid data received for op code BT_BAP_BASS_OP_ADD_SRC and BT_BAP_BASS_OP_MOD_SRC. If the length of buf is inconsistent with the valid data received, the response is error code BT_ATT_ERR_WRITE_REQ_REJECTED instead of other errors. Signed-off-by: Lyle Zhu <lyle.zhu@nxp.com>
This commit is contained in:
parent
4921ce2118
commit
132a24d21c
1 changed files with 60 additions and 33 deletions
|
@ -494,6 +494,8 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
|||
uint32_t aggregated_bis_syncs = 0;
|
||||
uint32_t broadcast_id;
|
||||
bool bis_sync_requested;
|
||||
uint16_t total_len;
|
||||
struct bt_bap_bass_cp_add_src *add_src;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) {
|
||||
|
@ -501,6 +503,34 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
|||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
add_src = (void *)(buf->data - 1);
|
||||
total_len = sizeof(struct bt_bap_bass_cp_add_src) - 1;
|
||||
for (int i = 0; i < add_src->num_subgroups; i++) {
|
||||
struct bt_bap_bass_cp_subgroup *subgroup;
|
||||
uint16_t index = total_len;
|
||||
|
||||
total_len += sizeof(struct bt_bap_bass_cp_subgroup);
|
||||
if (total_len > buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
subgroup = (void *)&buf->data[index];
|
||||
total_len += subgroup->metadata_len;
|
||||
if (total_len > buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (total_len != buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
internal_state = get_free_recv_state();
|
||||
if (internal_state == NULL) {
|
||||
LOG_DBG("Could not get free receive state");
|
||||
|
@ -558,11 +588,6 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
|||
struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
|
||||
uint8_t *metadata;
|
||||
|
||||
if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
|
||||
LOG_DBG("Invalid length %u", buf->size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
|
||||
|
||||
if (internal_state->requested_bis_sync[i] &&
|
||||
|
@ -596,13 +621,6 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
|||
|
||||
subgroup->metadata_len = net_buf_simple_pull_u8(buf);
|
||||
|
||||
if (buf->len < subgroup->metadata_len) {
|
||||
LOG_DBG("Invalid length %u", buf->size);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
|
||||
if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
|
||||
LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
|
||||
CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
|
||||
|
@ -615,11 +633,6 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
|||
subgroup->metadata_len);
|
||||
}
|
||||
|
||||
if (buf->len != 0) {
|
||||
LOG_DBG("Invalid length %u", buf->size);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
/* The active flag shall be set before any application callbacks, so that any calls for the
|
||||
* receive state can be processed
|
||||
*/
|
||||
|
@ -676,6 +689,8 @@ static int scan_delegator_mod_src(struct bt_conn *conn,
|
|||
uint8_t pa_sync;
|
||||
uint32_t aggregated_bis_syncs = 0;
|
||||
bool bis_sync_change_requested;
|
||||
uint16_t total_len;
|
||||
struct bt_bap_bass_cp_mod_src *mod_src;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) {
|
||||
|
@ -684,6 +699,34 @@ static int scan_delegator_mod_src(struct bt_conn *conn,
|
|||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
mod_src = (void *)(buf->data - 1);
|
||||
total_len = sizeof(struct bt_bap_bass_cp_mod_src) - 1;
|
||||
for (int i = 0; i < mod_src->num_subgroups; i++) {
|
||||
struct bt_bap_bass_cp_subgroup *subgroup;
|
||||
uint16_t index = total_len;
|
||||
|
||||
total_len += sizeof(struct bt_bap_bass_cp_subgroup);
|
||||
if (total_len > buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
subgroup = (void *)&buf->data[index];
|
||||
total_len += subgroup->metadata_len;
|
||||
if (total_len > buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (total_len != buf->len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
src_id = net_buf_simple_pull_u8(buf);
|
||||
internal_state = bass_lookup_src_id(src_id);
|
||||
|
||||
|
@ -718,11 +761,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn,
|
|||
uint32_t old_bis_sync_req;
|
||||
uint8_t *metadata;
|
||||
|
||||
if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
old_bis_sync_req = internal_state->requested_bis_sync[i];
|
||||
|
||||
internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
|
||||
|
@ -754,11 +792,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn,
|
|||
|
||||
subgroup->metadata_len = net_buf_simple_pull_u8(buf);
|
||||
|
||||
if (buf->len < subgroup->metadata_len) {
|
||||
LOG_DBG("Invalid length %u", buf->len);
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
|
||||
LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
|
||||
CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
|
||||
|
@ -771,12 +804,6 @@ static int scan_delegator_mod_src(struct bt_conn *conn,
|
|||
subgroup->metadata_len);
|
||||
}
|
||||
|
||||
if (buf->len != 0) {
|
||||
LOG_DBG("Invalid length %u", buf->size);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
/* All input has been validated; update receive state and check for changes */
|
||||
state = &internal_state->state;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue