Skip to content

Commit 94ca99b

Browse files
committed
ipc: fix component teardown crashes and memory leaks
Fuzzing identified several segmentation faults and memory corruptions in ipc_comp_free() when processing malformed IPC messages or handling uninitialized component lists. This patch implements three defensive structural fixes to harden teardown logic: 1. Validates that `icd->cd` is not NULL before checking component state to avoid early NULL pointer dereferences on broken components. 2. Resolves a deliberate memory leak ("eat the resulting memory leak on error") when encountering uninitialized buffer lists. Instead of leaking the structure and leaving it hanging in `ipc->comp_list` (which triggers secondary use-after-free assertions and segfaults in subsequent IPC calls), the component is now properly removed and freed. 3. Moves `list_item_del(&icd->list)` to occur immediately before `comp_free(icd->cd)`. This guarantees that other tasks or scheduling interrupts cannot discover and access a partially destructed component via the global IPC list. Signed-off-by: Liam Girdwood <[email protected]>
1 parent 9c5a577 commit 94ca99b

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

src/ipc/ipc-helper.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,13 @@ __cold int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
303303
return -ENODEV;
304304
}
305305

306+
if (!icd->cd) {
307+
tr_err(&ipc_tr, "comp id: 0x%x cd is NULL", comp_id);
308+
list_item_del(&icd->list);
309+
rfree(icd);
310+
return -EINVAL;
311+
}
312+
306313
/* check core */
307314
if (!cpu_is_me(icd->core))
308315
return ipc_process_on_core(icd->core, false);
@@ -324,12 +331,16 @@ __cold int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
324331
* (which is an invalid list!) if the component's
325332
* lifecycle hasn't reached that point. There's no
326333
* single place to ensure a valid/empty list, so we
327-
* have to do it here and eat the resulting memory
328-
* leak on error. Bug-free host drivers won't do
329-
* this, this was found via fuzzing.
334+
* have to do it here.
335+
* Bug-free host drivers won't do this, this was found
336+
* via fuzzing.
330337
*/
331338
tr_err(&ipc_tr, "uninitialized buffer lists on comp 0x%x\n",
332339
icd->id);
340+
list_item_del(&icd->list);
341+
comp_free(icd->cd);
342+
icd->cd = NULL;
343+
rfree(icd);
333344
return -EINVAL;
334345
}
335346

@@ -348,12 +359,14 @@ __cold int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
348359

349360
irq_local_enable(flags);
350361

362+
/* remove from list first so it cannot be found while being freed */
363+
list_item_del(&icd->list);
364+
351365
/* free component and remove from list */
352366
comp_free(icd->cd);
353367

354368
icd->cd = NULL;
355369

356-
list_item_del(&icd->list);
357370
rfree(icd);
358371

359372
return 0;

0 commit comments

Comments
 (0)