Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/audio/smart_amp/smart_amp.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,11 @@ static int smart_amp_get_config(struct processing_module *mod,
comp_dbg(dev, "actual blob size = %zu, expected blob size = %zu",
bs, sizeof(struct sof_smart_amp_config));

if (bs == 0 || bs > size)
/* bs is the host-set config.size and is used as the memcpy source
* length from the fixed-size sad->config, so bound it by the struct
* size as well as the destination buffer
*/
if (bs == 0 || bs > size || bs > sizeof(struct sof_smart_amp_config))
return -EINVAL;

ret = memcpy_s(cdata->data->data, size, &sad->config, bs);
Expand Down Expand Up @@ -521,8 +525,15 @@ static int smart_amp_ff_process(struct processing_module *mod,
return 0;
}

if (frames > SMART_AMP_FF_BUF_DB_SZ) {
comp_err(dev, "feed forward frame size overflow: %u", frames);
/*
* The remap functions write frames * ff_mod.channels samples into
* ff_mod.buf, which holds SMART_AMP_FF_BUF_DB_SZ samples. Bound the
* total sample count, not just the frame count, so an unexpected
* channel count cannot overflow the buffer.
*/
if ((uint64_t)frames * sad->ff_mod.channels > SMART_AMP_FF_BUF_DB_SZ) {
comp_err(dev, "feed forward frame size overflow: %u frames, %u ch",
frames, sad->ff_mod.channels);
sad->ff_mod.consumed = frames;
return -EINVAL;
}
Expand Down Expand Up @@ -556,8 +567,10 @@ static int smart_amp_fb_process(struct processing_module *mod,
return 0;
}

if (frames > SMART_AMP_FB_BUF_DB_SZ) {
comp_err(dev, "feedback frame size overflow: %u", frames);
/* bound total samples (frames * channels) against the buffer size */
if ((uint64_t)frames * sad->fb_mod.channels > SMART_AMP_FB_BUF_DB_SZ) {
comp_err(dev, "feedback frame size overflow: %u frames, %u ch",
frames, sad->fb_mod.channels);
sad->fb_mod.consumed = frames;
return -EINVAL;
}
Expand Down
9 changes: 6 additions & 3 deletions src/audio/smart_amp/smart_amp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ static void remap_s32_to_s32(struct smart_amp_mod_stream *src_mod, uint32_t fram
n = MIN(num_samples_remaining, nmax);

for (ch = 0; ch < src_mod->channels; ch++) {
if (chan_map[ch] == -1)
/* skip unmapped (-1) and out-of-range source channels */
if (chan_map[ch] < 0 || chan_map[ch] >= src_ch)
continue;

mod_ptr = mod_ptr_base + ch;
Expand Down Expand Up @@ -103,7 +104,8 @@ static void remap_s16_to_s16(struct smart_amp_mod_stream *src_mod, uint32_t fram
n = MIN(num_samples_remaining, nmax);

for (ch = 0; ch < src_mod->channels; ch++) {
if (chan_map[ch] == -1)
/* skip unmapped (-1) and out-of-range source channels */
if (chan_map[ch] < 0 || chan_map[ch] >= src_ch)
continue;

mod_ptr = mod_ptr_base + ch;
Expand Down Expand Up @@ -147,7 +149,8 @@ static void remap_s16_to_b32(struct smart_amp_mod_stream *src_mod, uint32_t fram
n = MIN(num_samples_remaining, nmax);

for (ch = 0; ch < src_mod->channels; ch++) {
if (chan_map[ch] == -1)
/* skip unmapped (-1) and out-of-range source channels */
if (chan_map[ch] < 0 || chan_map[ch] >= src_ch)
continue;

mod_ptr = mod_ptr_base + ch;
Expand Down
11 changes: 11 additions & 0 deletions src/audio/smart_amp/smart_amp_maxim_dsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,17 @@ static int maxim_dsm_get_param(struct smart_amp_mod_struct_t *hspk,
return -EINVAL;
}

/* Host controls msg_index and therefore data_pos; make sure the
* fragment stays inside caldata->data to avoid leaking adjacent
* heap back to the host.
*/
if (caldata->data_pos >= caldata->data_size ||
bs > caldata->data_size - caldata->data_pos) {
comp_err(dev, "[DSM] invalid data_pos %u, size %zu, total %u",
caldata->data_pos, bs, caldata->data_size);
return -EINVAL;
}

/* copy required size of data */
ret = memcpy_s(cdata->data->data, size,
(char *)caldata->data + caldata->data_pos,
Expand Down
10 changes: 10 additions & 0 deletions src/samples/audio/smart_amp_test_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,16 @@ static int smart_amp_prepare(struct comp_dev *dev)

sad->in_channels = audio_stream_get_channels(&sad->source_buf->stream);

/* out_channels bounds the processing loop that indexes the
* PLATFORM_MAX_CHANNELS-sized channel map, so reject a larger count
*/
if (sad->out_channels > PLATFORM_MAX_CHANNELS ||
sad->in_channels > PLATFORM_MAX_CHANNELS) {
comp_err(dev, "invalid channel count, in %u out %u",
sad->in_channels, sad->out_channels);
return -EINVAL;
}

if (sad->feedback_buf) {
audio_stream_set_channels(&sad->feedback_buf->stream,
sad->config.feedback_channels);
Expand Down
Loading