Skip to content

Commit 7342818

Browse files
committed
audio: tdfb: Improve robustness for invalid configuration
Add several validity checks against malformed configuration blobs and malformed IPC control payloads: - Verify that the self-declared config->size matches the size reported by the data-blob handler. The blob size is now stored in cd->config_size (set in both tdfb_prepare and the runtime blob-update path) so tdfb_init_coef can confirm the two agree before any further offset arithmetic that depends on config->size. - Reject angle_enum_mult == 0, which would otherwise collapse the azimuth target computation to a constant. - Reject filter_angles[].filter_index values that are negative or that would make the per-bank seek run past the total filter-block count. - Reject negative input_channel_select[] entries; the field is int16_t and an untrusted blob can supply a value that bypasses the existing '> max_ch' check but is still used as an array index. - Increase the local time-difference array in theoretical_time_differences() from PLATFORM_MAX_CHANNELS (4 or 8 per platform) to SOF_TDFB_MAX_MICROPHONES (16), matching the validated upper bound on num_mic_locations. - Clamp cdata->num_elems to SOF_IPC_MAX_CHANNELS in the IPC3 GET handler so the chanv[] write loop cannot run past the payload, matching the volume_ipc3 convention. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 3f7738d commit 7342818

4 files changed

Lines changed: 29 additions & 5 deletions

File tree

src/audio/tdfb/tdfb.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch,
323323
int i;
324324

325325
/* Sanity checks */
326+
if (config->size != cd->config_size) {
327+
comp_err(dev, "Incorrect configuration blob size");
328+
return -EINVAL;
329+
}
330+
326331
if (config->num_output_channels > PLATFORM_MAX_CHANNELS ||
327332
!config->num_output_channels) {
328333
comp_err(dev, "invalid num_output_channels %d",
@@ -348,6 +353,11 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch,
348353
return -EINVAL;
349354
}
350355

356+
if (!config->angle_enum_mult) {
357+
comp_err(dev, "invalid angle_enum_mult");
358+
return -EINVAL;
359+
}
360+
351361
if (config->beam_off_defined > 1) {
352362
comp_err(dev, "invalid beam_off_defined %d",
353363
config->beam_off_defined);
@@ -423,6 +433,12 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch,
423433
cd->filter_angles[min_delta_idx].azimuth, idx);
424434
}
425435

436+
if (idx < 0 || idx + (int)config->num_filters > num_filters) {
437+
comp_err(dev, "invalid filter_index %d for angle %d",
438+
idx, cd->filter_angles[min_delta_idx].azimuth);
439+
return -EINVAL;
440+
}
441+
426442
/* Seek to proper filter for requested angle or beam off configuration */
427443
coefp = tdfb_filter_seek(config, idx);
428444

@@ -451,6 +467,11 @@ static int tdfb_init_coef(struct processing_module *mod, int source_nch,
451467
for (i = 0; i < config->num_filters; i++) {
452468
if (cd->input_channel_select[i] > max_ch)
453469
max_ch = cd->input_channel_select[i];
470+
471+
if (cd->input_channel_select[i] < 0) {
472+
comp_err(dev, "invalid channel select for filter %d", i);
473+
return -EINVAL;
474+
}
454475
}
455476

456477
/* The stream must contain at least the number of channels that is
@@ -641,7 +662,7 @@ static int tdfb_process(struct processing_module *mod,
641662

642663
/* Check for changed configuration */
643664
if (comp_is_new_data_blob_available(cd->model_handler)) {
644-
cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL);
665+
cd->config = comp_get_data_blob(cd->model_handler, &cd->config_size, NULL);
645666
ret = tdfb_setup(mod, audio_stream_get_channels(source),
646667
audio_stream_get_channels(sink),
647668
audio_stream_get_frm_fmt(source));
@@ -705,7 +726,6 @@ static int tdfb_prepare(struct processing_module *mod,
705726
struct comp_buffer *sourceb, *sinkb;
706727
struct comp_dev *dev = mod->dev;
707728
enum sof_ipc_frame frame_fmt;
708-
size_t data_size;
709729
int source_channels;
710730
int sink_channels;
711731
int rate;
@@ -735,8 +755,8 @@ static int tdfb_prepare(struct processing_module *mod,
735755
rate = audio_stream_get_rate(&sourceb->stream);
736756

737757
/* Initialize filter */
738-
cd->config = comp_get_data_blob(cd->model_handler, &data_size, NULL);
739-
if (!cd->config || !data_size) {
758+
cd->config = comp_get_data_blob(cd->model_handler, &cd->config_size, NULL);
759+
if (!cd->config || !cd->config_size) {
740760
comp_err(dev, "Missing a configuration blob.");
741761
ret = -EINVAL;
742762
goto out;

src/audio/tdfb/tdfb_comp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct tdfb_comp_data {
8888
int16_t *output_stream_mix; /**< for each FIR define stream */
8989
int16_t az_value; /**< beam steer azimuth as in control enum */
9090
int16_t az_value_estimate; /**< beam steer azimuth as in control enum */
91+
size_t config_size; /**< size of the configuration blob */
9192
size_t fir_delay_size; /**< allocated size */
9293
unsigned int max_frames; /**< max frames to process */
9394
bool direction_updates:1; /**< set true if direction angle control is updated */

src/audio/tdfb/tdfb_direction.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ static int16_t distance_from_source(struct tdfb_comp_data *cd, int mic_n,
386386

387387
static void theoretical_time_differences(struct tdfb_comp_data *cd, int16_t az)
388388
{
389-
int16_t d[PLATFORM_MAX_CHANNELS];
389+
int16_t d[SOF_TDFB_MAX_MICROPHONES];
390390
int16_t src_x;
391391
int16_t src_y;
392392
int16_t sin_az;

src/audio/tdfb/tdfb_ipc3.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ static int tdfb_cmd_get_value(struct processing_module *mod, struct sof_ipc_ctrl
112112
{
113113
struct tdfb_comp_data *cd = module_get_private_data(mod);
114114

115+
if (cdata->num_elems == 0 || cdata->num_elems > SOF_IPC_MAX_CHANNELS)
116+
return -EINVAL;
117+
115118
switch (cdata->cmd) {
116119
case SOF_CTRL_CMD_ENUM:
117120
comp_dbg(mod->dev, "SOF_CTRL_CMD_ENUM index=%d",

0 commit comments

Comments
 (0)