Skip to content

Commit 3347ddc

Browse files
tmlemanlgirdwood
authored andcommitted
audio: up_down_mixer: fix use-after-free on init allocation failure
up_down_mixer_init() called comp_free(dev) when mod_zalloc() failed and then returned -ENOMEM. That is a lifecycle violation: a module's init() callback must never free its own comp_dev. On init failure the module adapter framework already unwinds the component: module_init() -> mod_free_all(mod) module_adapter_new_ext() -> module_adapter_mem_free(mod) (err path) The stray comp_free(dev) ran a second, full teardown (module_adapter_free -> module .free callback + mod_free_all() + module_adapter_mem_free() + freeing dev) that collided with the framework cleanup in two ways: 1. NULL dereference: comp_free() invoked the module .free callback (up_down_mixer_free) before mod->priv.private had been assigned, so module_get_private_data() returned NULL and the callback dereferenced it. This is the SEGV observed first. 2. Use-after-free / double free: comp_free() had already freed (and, under CONFIG_SYS_HEAP_SANITIZER_ASAN, poisoned) the module resources and the comp_dev. Control then returned to module_init(), which called mod_free_all() on that freed memory, after which the module_adapter_new_ext() error path freed it once more via module_adapter_mem_free(). Fix by removing the comp_free(dev) call and simply returning -ENOMEM, which is exactly what every other module does on this path (aria, asrc, copier, crossover, drc, ...): propagate the error and let the adapter framework own the cleanup. As defensive hardening, also guard up_down_mixer_free() against a NULL private pointer. The bug was latent: with the static Zephyr memory pools these small allocations never failed, so the error path was never taken. It became reachable only after the native_sim host-heap change routed module allocations onto the C library allocator, where sustained memory pressure over many iterations eventually makes mod_zalloc() fail. Found by the IPC4 libFuzzer target on native_sim under AddressSanitizer. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 473206f commit 3347ddc

1 file changed

Lines changed: 4 additions & 3 deletions

File tree

‎src/audio/up_down_mixer/up_down_mixer.c‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ static int up_down_mixer_free(struct processing_module *mod)
329329
{
330330
struct up_down_mixer_data *cd = module_get_private_data(mod);
331331

332+
if (!cd)
333+
return 0;
334+
332335
mod_free(mod, cd->buf_in);
333336
mod_free(mod, cd->buf_out);
334337
mod_free(mod, cd);
@@ -346,10 +349,8 @@ static int up_down_mixer_init(struct processing_module *mod)
346349
int ret;
347350

348351
cd = mod_zalloc(mod, sizeof(*cd));
349-
if (!cd) {
350-
comp_free(dev);
352+
if (!cd)
351353
return -ENOMEM;
352-
}
353354

354355
mod_data->private = cd;
355356

0 commit comments

Comments
 (0)