Skip to content

Commit

Permalink
ipc3: Add size checks on ipc subtypes
Browse files Browse the repository at this point in the history
We have a few gaps in input validation from the kernel. Right now we
check the IPC doesn't claim its larger the window, this patch adds the
following checks:

1. That the IPC size is at least large enough for any downcast type on
   comp new
2. That any reported size for a process total size is less than the IPC
   window.

Also adjust the other helper to be  a bit safer and more direct

Signed-off-by: Curtis Malainey <cujomalainey@chromium.org>
  • Loading branch information
cujomalainey authored and kv2019i committed Aug 8, 2024
1 parent 6a448db commit 3f873a6
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/include/sof/ipc/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ struct ipc_msg;

/* validates internal non tail structures within IPC command structure */
#define IPC_IS_SIZE_INVALID(object) \
(object).hdr.size == sizeof(object) ? 0 : 1
((object).hdr.size != sizeof(object))

#define IPC_TAIL_IS_SIZE_INVALID(object) \
((object).comp.hdr.size + (object).comp.ext_data_length < sizeof(object))

/* ipc trace context, used by multiple units */
extern struct tr_ctx ipc_tr;
Expand Down
20 changes: 20 additions & 0 deletions src/ipc/ipc3/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ static int comp_specific_builder(struct sof_ipc_comp *comp,
case SOF_COMP_SG_HOST:
case SOF_COMP_DAI:
case SOF_COMP_SG_DAI:
if (IPC_TAIL_IS_SIZE_INVALID(*file))
return -EBADMSG;
config->file.channels = file->channels;
config->file.fn = file->fn;
config->file.frame_fmt = file->frame_fmt;
Expand All @@ -225,30 +227,40 @@ static int comp_specific_builder(struct sof_ipc_comp *comp,
#else
case SOF_COMP_HOST:
case SOF_COMP_SG_HOST:
if (IPC_TAIL_IS_SIZE_INVALID(*host))
return -EBADMSG;
config->host.direction = host->direction;
config->host.no_irq = host->no_irq;
config->host.dmac_config = host->dmac_config;
break;
case SOF_COMP_DAI:
case SOF_COMP_SG_DAI:
if (IPC_TAIL_IS_SIZE_INVALID(*dai))
return -EBADMSG;
config->dai.dai_index = dai->dai_index;
config->dai.direction = dai->direction;
config->dai.type = dai->type;
break;
#endif
case SOF_COMP_VOLUME:
if (IPC_TAIL_IS_SIZE_INVALID(*vol))
return -EBADMSG;
config->volume.channels = vol->channels;
config->volume.initial_ramp = vol->initial_ramp;
config->volume.max_value = vol->max_value;
config->volume.min_value = vol->min_value;
config->volume.ramp = vol->ramp;
break;
case SOF_COMP_SRC:
if (IPC_TAIL_IS_SIZE_INVALID(*src))
return -EBADMSG;
config->src.rate_mask = src->rate_mask;
config->src.sink_rate = src->sink_rate;
config->src.source_rate = src->source_rate;
break;
case SOF_COMP_TONE:
if (IPC_TAIL_IS_SIZE_INVALID(*tone))
return -EBADMSG;
config->tone.ampl_mult = tone->ampl_mult;
config->tone.amplitude = tone->amplitude;
config->tone.freq_mult = tone->freq_mult;
Expand All @@ -260,6 +272,8 @@ static int comp_specific_builder(struct sof_ipc_comp *comp,
config->tone.sample_rate = tone->sample_rate;
break;
case SOF_COMP_ASRC:
if (IPC_TAIL_IS_SIZE_INVALID(*asrc))
return -EBADMSG;
config->asrc.source_rate = asrc->source_rate;
config->asrc.sink_rate = asrc->sink_rate;
config->asrc.asynchronous_mode = asrc->asynchronous_mode;
Expand All @@ -276,6 +290,12 @@ static int comp_specific_builder(struct sof_ipc_comp *comp,
case SOF_COMP_SMART_AMP:
case SOF_COMP_MODULE_ADAPTER:
case SOF_COMP_NONE:
if (IPC_TAIL_IS_SIZE_INVALID(*proc))
return -EBADMSG;

if (proc->comp.hdr.size + proc->comp.ext_data_length > SOF_IPC_MSG_MAX_SIZE)
return -EBADMSG;

config->process.type = proc->type;
config->process.size = proc->size;
#if CONFIG_LIBRARY || UNIT_TEST
Expand Down

0 comments on commit 3f873a6

Please sign in to comment.