From 6b80e8a1d477bd41d50a482600594f081ffc9278 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Wed, 2 Sep 2026 15:46:13 +0200 Subject: [PATCH] audio: module_adapter: clear pipeline back-pointers on create failure A module's init op can store its comp_dev into the parent pipeline's source_comp/sink_comp before module creation completes. When a later step of module_adapter_new_ext fails, the dev is freed on the err: path before it has been added to the IPC component list, so ipc_comp_free back-pointer cleanup never runs for it and pipeline->source_comp/sink_comp is left pointing at freed memory. A subsequent SET_PIPELINE_STATE then dereferences the freed component in ipc4 pipeline_get_host_dev. Found by the IPC4 libFuzzer target under AddressSanitizer. Clear pipeline->source_comp/sink_comp/sched_comp that reference the dev being freed on the creation-failure path, mirroring the cleanup ipc_comp_free already performs for registered components. Signed-off-by: Tomasz Leman --- src/audio/module_adapter/module_adapter.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index f94d5fe4f572..68ad4174175e 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -336,6 +336,21 @@ struct comp_dev *module_adapter_new_ext(const struct comp_driver *drv, if (dev->task) schedule_task_free(dev->task); #endif + /* When module_init is called in this function, it can store this dev in its pipeline. + * This happens in the case of the copier (copier_dai_init and copier_host_create). + * The pointers remain set even after a failure. The dev is freed below on this + * creation-failure path before it was added to the IPC component list, so ipc_comp_free()'s + * back-pointer cleanup will never run for it. Clear the stale references now to prevent + * a later use-after-free when the pipeline is prepared or triggered. + */ + if (dev->pipeline) { + if (dev->pipeline->source_comp == dev) + dev->pipeline->source_comp = NULL; + if (dev->pipeline->sink_comp == dev) + dev->pipeline->sink_comp = NULL; + if (dev->pipeline->sched_comp == dev) + dev->pipeline->sched_comp = NULL; + } module_adapter_mem_free(mod); return NULL; }