Skip to content

Commit 9e1dd00

Browse files
committed
ipc3: helper: clear component pipeline pointers before freeing pipeline
When ipc_pipeline_free() frees a pipeline, component devices that were connected to it retain stale cd->pipeline pointers. If an IPC (e.g. stream position request) later dereferences that pointer, it triggers a use-after-free. Fix this by iterating all components in the IPC comp_list and setting cd->pipeline = NULL for any component whose pipeline matches the one being freed. This makes the existing NULL checks in handler.c effective and prevents the dangling pointer dereference. Found by fuzzing with AddressSanitizer enabled. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 0f9fa75 commit 9e1dd00

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

src/ipc/ipc3/helper.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ int ipc_pipeline_new(struct ipc *ipc, ipc_pipe_new *_pipe_desc)
439439
int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)
440440
{
441441
struct ipc_comp_dev *ipc_pipe;
442+
struct ipc_comp_dev *icd;
443+
struct list_item *clist;
442444
int ret;
443445

444446
/* check whether pipeline exists */
@@ -457,6 +459,19 @@ int ipc_pipeline_free(struct ipc *ipc, uint32_t comp_id)
457459
if (!cpu_is_me(ipc_pipe->core))
458460
return ipc_process_on_core(ipc_pipe->core, false);
459461

462+
/* Clear stale cd->pipeline pointers on all components and buffers
463+
* that still belong to this pipeline. A well-behaved host driver
464+
* frees components before freeing the pipeline, but if it does not
465+
* (or in fuzz/error paths) the dangling pointer would be a
466+
* use-after-free on any subsequent IPC referencing that component.
467+
*/
468+
list_for_item(clist, &ipc->comp_list) {
469+
icd = container_of(clist, struct ipc_comp_dev, list);
470+
if (icd->type == COMP_TYPE_COMPONENT &&
471+
icd->cd && icd->cd->pipeline == ipc_pipe->pipeline)
472+
icd->cd->pipeline = NULL;
473+
}
474+
460475
/* free buffer and remove from list */
461476
ret = pipeline_free(ipc_pipe->pipeline);
462477
if (ret < 0) {

0 commit comments

Comments
 (0)