Skip to content

Commit abe2e0d

Browse files
Thalleykartben
authored andcommitted
Bluetooth: BAP: BA: Add validation of add/mod src
The functions did not verify the provided parameters before sending it as a control point operation. This also fixes a bug where BT_BAP_BIS_SYNC_NO_PREF was not allowed when pa_sync=0. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 38a32b7 commit abe2e0d

File tree

1 file changed

+161
-21
lines changed

1 file changed

+161
-21
lines changed

subsys/bluetooth/audio/bap_broadcast_assistant.c

Lines changed: 161 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,112 @@ int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn)
12381238
return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
12391239
}
12401240

1241+
static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs, uint32_t aggregated_bis_syncs)
1242+
{
1243+
if (requested_bis_syncs == 0U || aggregated_bis_syncs == 0U) {
1244+
return true;
1245+
}
1246+
1247+
if (requested_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF &&
1248+
aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
1249+
return true;
1250+
}
1251+
1252+
return (requested_bis_syncs & aggregated_bis_syncs) != 0U;
1253+
}
1254+
1255+
static bool valid_subgroup_params(uint8_t pa_sync, const struct bt_bap_bass_subgroup subgroups[],
1256+
uint8_t num_subgroups)
1257+
{
1258+
uint32_t aggregated_bis_syncs = 0U;
1259+
1260+
for (uint8_t i = 0U; i < num_subgroups; i++) {
1261+
/* BIS sync values of 0 and BT_BAP_BIS_SYNC_NO_PREF are allowed at any time, but any
1262+
* other values are only allowed if PA sync state is also set
1263+
*/
1264+
CHECKIF(pa_sync == 0 && (subgroups[i].bis_sync != 0U &&
1265+
subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF)) {
1266+
LOG_DBG("[%u]: Only syncing to BIS is not allowed", i);
1267+
1268+
return false;
1269+
}
1270+
1271+
/* Verify that the request BIS sync indexes are unique or no preference */
1272+
if (!bis_syncs_unique_or_no_pref(subgroups[i].bis_sync, aggregated_bis_syncs)) {
1273+
LOG_DBG("[%u]: Duplicate BIS index 0x%08x (aggregated 0x%08x)", i,
1274+
subgroups[i].bis_sync, aggregated_bis_syncs);
1275+
1276+
return false;
1277+
}
1278+
1279+
/* Keep track of BIS sync values to ensure that we do not have duplicates */
1280+
if (subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF) {
1281+
aggregated_bis_syncs |= subgroups[i].bis_sync;
1282+
}
1283+
1284+
#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
1285+
if (subgroups[i].metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1286+
LOG_DBG("[%u]: Invalid metadata_len: %u", i, subgroups[i].metadata_len);
1287+
1288+
return false;
1289+
}
1290+
}
1291+
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
1292+
1293+
return true;
1294+
}
1295+
1296+
static bool valid_add_src_param(const struct bt_bap_broadcast_assistant_add_src_param *param)
1297+
{
1298+
CHECKIF(param == NULL) {
1299+
LOG_DBG("param is NULL");
1300+
return false;
1301+
}
1302+
1303+
CHECKIF(param->addr.type > BT_ADDR_LE_RANDOM) {
1304+
LOG_DBG("Invalid address type %u", param->addr.type);
1305+
return false;
1306+
}
1307+
1308+
CHECKIF(param->adv_sid > BT_GAP_SID_MAX) {
1309+
LOG_DBG("Invalid adv_sid %u", param->adv_sid);
1310+
return false;
1311+
}
1312+
1313+
CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) &&
1314+
!IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL,
1315+
BT_GAP_PER_ADV_MAX_INTERVAL)) {
1316+
LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval);
1317+
return false;
1318+
}
1319+
1320+
CHECKIF(param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1321+
LOG_DBG("Invalid broadcast_id 0x%08X", param->broadcast_id);
1322+
return false;
1323+
}
1324+
1325+
CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) {
1326+
LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups);
1327+
return false;
1328+
}
1329+
1330+
CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1331+
LOG_DBG("Too many subgroups %u/%u", param->num_subgroups,
1332+
CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1333+
1334+
return false;
1335+
}
1336+
1337+
CHECKIF(param->subgroups != NULL) {
1338+
if (!valid_subgroup_params(param->pa_sync, param->subgroups,
1339+
param->num_subgroups)) {
1340+
return false;
1341+
}
1342+
}
1343+
1344+
return true;
1345+
}
1346+
12411347
int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
12421348
const struct bt_bap_broadcast_assistant_add_src_param *param)
12431349
{
@@ -1264,6 +1370,10 @@ int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
12641370
return -EINVAL;
12651371
}
12661372

1373+
if (!valid_add_src_param(param)) {
1374+
return -EINVAL;
1375+
}
1376+
12671377
if (inst->cp_handle == 0) {
12681378
LOG_DBG("handle not set");
12691379

@@ -1315,28 +1425,58 @@ int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
13151425

13161426
subgroup->bis_sync = param->subgroups[i].bis_sync;
13171427

1318-
CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) {
1319-
LOG_DBG("Only syncing to BIS is not allowed");
1320-
1321-
atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1322-
1323-
return -EINVAL;
1324-
}
1325-
1428+
#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
13261429
if (param->subgroups[i].metadata_len != 0) {
1327-
(void)memcpy(subgroup->metadata,
1328-
param->subgroups[i].metadata,
1430+
(void)memcpy(subgroup->metadata, param->subgroups[i].metadata,
13291431
param->subgroups[i].metadata_len);
13301432
subgroup->metadata_len = param->subgroups[i].metadata_len;
13311433
} else {
1332-
subgroup->metadata_len = 0;
1434+
subgroup->metadata_len = 0U;
13331435
}
1334-
1436+
#else
1437+
subgroup->metadata_len = 0U;
1438+
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
13351439
}
13361440

13371441
return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
13381442
}
13391443

1444+
static bool valid_add_mod_param(const struct bt_bap_broadcast_assistant_mod_src_param *param)
1445+
{
1446+
CHECKIF(param == NULL) {
1447+
LOG_DBG("param is NULL");
1448+
return false;
1449+
}
1450+
1451+
CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) &&
1452+
!IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL,
1453+
BT_GAP_PER_ADV_MAX_INTERVAL)) {
1454+
LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval);
1455+
return false;
1456+
}
1457+
1458+
CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) {
1459+
LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups);
1460+
return false;
1461+
}
1462+
1463+
CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1464+
LOG_DBG("Too many subgroups %u/%u", param->num_subgroups,
1465+
CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1466+
1467+
return false;
1468+
}
1469+
1470+
CHECKIF(param->subgroups != NULL) {
1471+
if (!valid_subgroup_params(param->pa_sync, param->subgroups,
1472+
param->num_subgroups)) {
1473+
return false;
1474+
}
1475+
}
1476+
1477+
return true;
1478+
}
1479+
13401480
int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
13411481
const struct bt_bap_broadcast_assistant_mod_src_param *param)
13421482
{
@@ -1351,6 +1491,10 @@ int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
13511491
return -EINVAL;
13521492
}
13531493

1494+
if (!valid_add_mod_param(param)) {
1495+
return -EINVAL;
1496+
}
1497+
13541498
inst = inst_by_conn(conn);
13551499
if (inst == NULL) {
13561500
return -EINVAL;
@@ -1423,22 +1567,18 @@ int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
14231567

14241568
subgroup->bis_sync = param->subgroups[i].bis_sync;
14251569

1426-
CHECKIF(param->pa_sync == 0 && subgroup->bis_sync != 0) {
1427-
LOG_DBG("Only syncing to BIS is not allowed");
1428-
1429-
atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1430-
1431-
return -EINVAL;
1432-
}
1433-
1570+
#if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
14341571
if (param->subgroups[i].metadata_len != 0) {
14351572
(void)memcpy(subgroup->metadata,
14361573
param->subgroups[i].metadata,
14371574
param->subgroups[i].metadata_len);
14381575
subgroup->metadata_len = param->subgroups[i].metadata_len;
14391576
} else {
1440-
subgroup->metadata_len = 0;
1577+
subgroup->metadata_len = 0U;
14411578
}
1579+
#else
1580+
subgroup->metadata_len = 0U;
1581+
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
14421582
}
14431583

14441584
return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);

0 commit comments

Comments
 (0)