Skip to content

Commit 68652a6

Browse files
Thalleykartben
authored andcommitted
Bluetooth: CAP: Broadcast: Add check for memory allocation for create
When creating a broadcast source with bt_cap_initiator_broadcast_audio_create there was no check if all broadcast sources were already allocated, which could cause a NULL pointer dereference. Add a check, a test and documentation about possibly error codes of the function. Signed-off-by: Emil Gydesen <[email protected]>
1 parent ca1d457 commit 68652a6

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

include/zephyr/bluetooth/audio/cap.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,12 @@ struct bt_cap_initiator_broadcast_create_param {
542542
* @param[in] param Parameters to start the audio streams.
543543
* @param[out] broadcast_source Pointer to the broadcast source created.
544544
*
545-
* @return 0 on success or negative error value on failure.
545+
* @retval 0 Success
546+
* @retval -EINVAL @p param is invalid or @p broadcast_source is NULL
547+
* @retval -ENOMEM Could not allocate more broadcast sources, subgroups or ISO streams, or the
548+
* provided codec configuration data is too large when merging the BIS and subgroup
549+
* configuration data.
550+
* @retval -ENOEXEC The broadcast source failed to be created for other reasons
546551
*/
547552
int bt_cap_initiator_broadcast_audio_create(
548553
const struct bt_cap_initiator_broadcast_create_param *param,

subsys/bluetooth/audio/cap_initiator.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ int bt_cap_initiator_broadcast_audio_create(
228228
struct bt_bap_broadcast_source_stream_param
229229
bap_stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
230230
struct bt_bap_broadcast_source_param bap_create_param = {0};
231+
int err;
231232

232233
CHECKIF(param == NULL) {
233234
LOG_DBG("param is NULL");
@@ -243,18 +244,36 @@ int bt_cap_initiator_broadcast_audio_create(
243244
return -EINVAL;
244245
}
245246

247+
*broadcast_source = NULL;
246248
for (size_t i = 0; i < ARRAY_SIZE(broadcast_sources); i++) {
247249
if (broadcast_sources[i].bap_broadcast == NULL) {
248250
*broadcast_source = &broadcast_sources[i];
249251
break;
250252
}
251253
}
252254

255+
if (*broadcast_source == NULL) {
256+
LOG_DBG("Failed to allocate a new broadcast source");
257+
return -ENOMEM;
258+
}
259+
253260
cap_initiator_broadcast_to_bap_broadcast_param(param, &bap_create_param,
254261
bap_subgroup_params, bap_stream_params);
255262

256-
return bt_bap_broadcast_source_create(&bap_create_param,
257-
&(*broadcast_source)->bap_broadcast);
263+
err = bt_bap_broadcast_source_create(&bap_create_param,
264+
&(*broadcast_source)->bap_broadcast);
265+
if (err != 0) {
266+
/* Return known errors */
267+
if (err == -EINVAL || err == -ENOMEM) {
268+
return err;
269+
}
270+
271+
LOG_DBG("Unexpected error from bt_bap_broadcast_source_create: %d", err);
272+
273+
return -ENOEXEC;
274+
}
275+
276+
return 0;
258277
}
259278

260279
static struct bt_cap_broadcast_source *get_cap_broadcast_source_by_bap_broadcast_source(

tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ static void test_broadcast_audio_create_inval(void)
299299
stream_params[ARRAY_SIZE(broadcast_source_streams)];
300300
struct bt_cap_initiator_broadcast_subgroup_param subgroup_param;
301301
struct bt_cap_initiator_broadcast_create_param create_param;
302-
struct bt_cap_broadcast_source *broadcast_source;
302+
struct bt_cap_broadcast_source *broadcast_sources[CONFIG_BT_BAP_BROADCAST_SRC_COUNT + 1];
303303
struct bt_audio_codec_cfg invalid_codec = BT_AUDIO_CODEC_LC3_CONFIG(
304304
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, BT_AUDIO_CODEC_CFG_DURATION_10,
305305
BT_AUDIO_LOCATION_FRONT_LEFT, 40U, 1, BT_AUDIO_CONTEXT_TYPE_MEDIA);
@@ -323,7 +323,7 @@ static void test_broadcast_audio_create_inval(void)
323323
create_param.encryption = false;
324324

325325
/* Test NULL parameters */
326-
err = bt_cap_initiator_broadcast_audio_create(NULL, &broadcast_source);
326+
err = bt_cap_initiator_broadcast_audio_create(NULL, &broadcast_sources[0]);
327327
if (err == 0) {
328328
FAIL("bt_cap_initiator_broadcast_audio_create with NULL param did not fail\n");
329329
return;
@@ -345,6 +345,38 @@ static void test_broadcast_audio_create_inval(void)
345345
"fail\n");
346346
return;
347347
}
348+
subgroup_param.codec_cfg = &broadcast_preset_16_2_1.codec_cfg;
349+
350+
/* Test allocating too many sources */
351+
ARRAY_FOR_EACH(broadcast_sources, i) {
352+
err = bt_cap_initiator_broadcast_audio_create(&create_param, &broadcast_sources[i]);
353+
if (i < CONFIG_BT_BAP_BROADCAST_SRC_COUNT) {
354+
if (err != 0) {
355+
FAIL("[%zu]: bt_cap_initiator_broadcast_audio_create failed: %d\n",
356+
i, err);
357+
return;
358+
}
359+
} else {
360+
if (err != -ENOMEM) {
361+
FAIL("bt_cap_initiator_broadcast_audio_create did not fail with "
362+
"-ENOMEM when allocating too many sources: %d\n",
363+
err);
364+
return;
365+
}
366+
}
367+
}
368+
369+
/* Cleanup the created broadcast sources */
370+
ARRAY_FOR_EACH(broadcast_sources, i) {
371+
if (i < CONFIG_BT_BAP_BROADCAST_SRC_COUNT) {
372+
err = bt_cap_initiator_broadcast_audio_delete(broadcast_sources[i]);
373+
if (err != 0) {
374+
FAIL("[%zu]: bt_cap_initiator_broadcast_audio_delete failed: %d\n",
375+
i, err);
376+
return;
377+
}
378+
}
379+
}
348380

349381
/* Since we are just casting the CAP parameters to BAP parameters,
350382
* we can rely on the BAP tests to verify the values

0 commit comments

Comments
 (0)