Skip to content

Commit c0037d9

Browse files
lrgirdwolgirdwood
authored andcommitted
selector: re-validate configuration on control set
A new configuration accepted at runtime through the control set path was copied in without the validation done when parameters are applied, so a later out-of-range channel count could overflow the channel table. Validate the blob size and channel fields before accepting it. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 768faad commit c0037d9

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

src/audio/selector/selector.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,16 +231,86 @@ static int selector_ctrl_set_data(struct comp_dev *dev,
231231
struct sof_ipc_ctrl_data *cdata)
232232
{
233233
struct comp_data *cd = comp_get_drvdata(dev);
234+
struct comp_buffer *src;
234235
struct sof_sel_config *cfg;
236+
uint32_t src_channels;
235237
int ret = 0;
236238

237239
switch (cdata->cmd) {
238240
case SOF_CTRL_CMD_BINARY:
239241
comp_dbg(dev, "SOF_CTRL_CMD_BINARY");
240242

243+
if (cdata->data->size < sizeof(struct sof_sel_config)) {
244+
comp_err(dev, "invalid config blob size %u", cdata->data->size);
245+
return -EINVAL;
246+
}
247+
241248
cfg = (struct sof_sel_config *)
242249
ASSUME_ALIGNED(&cdata->data->data, 4);
243250

251+
/*
252+
* The config validated at .params() time can be replaced here at
253+
* runtime, so re-validate the new channel counts and selected
254+
* channel before accepting them; otherwise an out-of-range value
255+
* later indexes past the source channels in the copy routine.
256+
*/
257+
switch (cfg->in_channels_count) {
258+
case 0:
259+
case SEL_SOURCE_1CH:
260+
case SEL_SOURCE_2CH:
261+
case SEL_SOURCE_4CH:
262+
break;
263+
default:
264+
comp_err(dev, "invalid in_channels_count %u",
265+
cfg->in_channels_count);
266+
return -EINVAL;
267+
}
268+
269+
switch (cfg->out_channels_count) {
270+
case 0:
271+
case SEL_SINK_1CH:
272+
case SEL_SINK_2CH:
273+
case SEL_SINK_4CH:
274+
break;
275+
default:
276+
comp_err(dev, "invalid out_channels_count %u",
277+
cfg->out_channels_count);
278+
return -EINVAL;
279+
}
280+
281+
/* sel_channel indexes the source channels, so it must be below
282+
* the source channel count, otherwise the copy routine reads
283+
* past the end of each source frame. The copy routine strides by
284+
* the live producer stream channel count, so when the source is
285+
* already connected that live count is the authority for both the
286+
* selected channel and any fixed input count; before connection
287+
* fall back to the configured input count. Always cap by the
288+
* maximum supported source width.
289+
*/
290+
src = comp_dev_get_first_data_producer(dev);
291+
if (src)
292+
src_channels = audio_stream_get_channels(&src->stream);
293+
else
294+
src_channels = cfg->in_channels_count;
295+
296+
/* A fixed (non-zero) input count must not exceed the live source
297+
* width, otherwise sel_channel could be accepted below the
298+
* requested count yet still index past the actual stream.
299+
*/
300+
if (src && cfg->in_channels_count &&
301+
cfg->in_channels_count > src_channels) {
302+
comp_err(dev, "in_channels_count %u exceeds source channels %u",
303+
cfg->in_channels_count, src_channels);
304+
return -EINVAL;
305+
}
306+
307+
if (cfg->sel_channel >= SEL_SOURCE_4CH ||
308+
(src_channels && cfg->sel_channel >= src_channels)) {
309+
comp_err(dev, "invalid sel_channel %u (source channels %u)",
310+
cfg->sel_channel, src_channels);
311+
return -EINVAL;
312+
}
313+
244314
/* Just set the configuration */
245315
cd->config.in_channels_count = cfg->in_channels_count;
246316
cd->config.out_channels_count = cfg->out_channels_count;

src/include/sof/audio/selector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct comp_dev;
3232

3333
#if CONFIG_IPC_MAJOR_3
3434
/** \brief Supported channel count on input. */
35+
#define SEL_SOURCE_1CH 1
3536
#define SEL_SOURCE_2CH 2
3637
#define SEL_SOURCE_4CH 4
3738

0 commit comments

Comments
 (0)