From 441173fa58636b24cdc6a10ffecc79642db3880c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 2 May 2025 16:36:00 +0200 Subject: [PATCH 1/2] audio: check NULL linked buffer in .trigger() If .trigger() is wrongly called on a pipeline, that isn't connected to a DAI, its edge component will hit a NULL buffer, which then has to be checked. Signed-off-by: Guennadi Liakhovetski --- src/audio/asrc/asrc.c | 14 ++++++++++---- src/audio/selector/selector.c | 6 ++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 57b6f75d47c3..df4f8d39f3cb 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -452,11 +452,14 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) /* In push mode check if sink component is DAI */ do { sinkb = comp_dev_get_first_data_consumer(dev); + if (!sinkb) { + comp_err(asrc_dev, "At end: NULL buffer, no DAI found."); + return -EINVAL; + } dev = comp_buffer_get_sink_component(sinkb); - if (!dev) { - comp_err(asrc_dev, "At end, no DAI found."); + comp_err(asrc_dev, "At end: NULL device, no DAI found."); return -EINVAL; } @@ -470,11 +473,14 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) /* In pull mode check if source component is DAI */ do { sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb) { + comp_err(asrc_dev, "At beginning: NULL buffer, no DAI found."); + return -EINVAL; + } dev = comp_buffer_get_source_component(sourceb); - if (!dev) { - comp_err(asrc_dev, "At beginning, no DAI found."); + comp_err(asrc_dev, "At beginning: NULL device, no DAI found."); return -EINVAL; } diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index e1ca62cab194..6215caccd2a2 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -344,8 +344,14 @@ static int selector_trigger(struct comp_dev *dev, int cmd) comp_dbg(dev, "selector_trigger()"); sourceb = comp_dev_get_first_data_producer(dev); + if (!sourceb) { + comp_err(dev, "source disconnected"); + return -ENODEV; + } ret = comp_set_state(dev, cmd); + if (ret == COMP_STATUS_STATE_ALREADY_SET) + ret = 0; /* TODO: remove in the future after adding support for case when * kpb_init_draining() and kpb_draining_task() are interrupted by From 0e175589ed5c97fa0ce9db91c22e18f4b822484c Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 2 May 2025 16:39:34 +0200 Subject: [PATCH 2/2] ipc3: explicit active component check in ipc_buffer_free() It is possible that both the source and the sink component are inactive in ipc_buffer_free(), Add an explicit check for this. The present code behaves correctly now as well, because it checks for active_comp->state > COMP_STATE_READY, but active component misidentification is confusing. Signed-off-by: Guennadi Liakhovetski --- src/ipc/ipc3/helper.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ipc/ipc3/helper.c b/src/ipc/ipc3/helper.c index adb4d7ec1f16..6eb708a55b91 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -562,7 +562,13 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id) * core, the free must be run in the context of the active * pipeline. */ - active_comp = sink_active ? sink : source; + if (sink_active) + active_comp = sink; + else if (source_active) + active_comp = source; + else + active_comp = NULL; + if (active_comp) { core = active_comp->ipc_config.core;