platform: posix: tear down IPC topology between fuzz testcases - #11066
Open
tmleman wants to merge 1 commit into
Open
platform: posix: tear down IPC topology between fuzz testcases#11066tmleman wants to merge 1 commit into
tmleman wants to merge 1 commit into
Conversation
Without an explicit teardown a fuzz testcase that successfully creates
components, buffers or pipelines leaves them registered in
global_ipc->comp_list. The next LLVMFuzzerTestOneInput() then sees a
non-empty topology it never asked for, which both hides bugs (crashes
that depend on freshly-empty state are missed) and fabricates them
(crashes that only occur because of carry-over from a previous case are
unreproducible when the artifact is replayed on its own).
Add a posix-only teardown helper, called from posix_fuzz_case_begin()
once at the start of every testcase before the input is staged. The
helper:
* Runs a pre-pass that forces every COMP_TYPE_COMPONENT to
COMP_STATE_READY and initialises any NULL bsource_list/bsink_list
pointers, because ipc_comp_free() returns -EINVAL (and silently
leaks the entry) for a component that is not READY or whose buffer
lists were never list_init()'d - the latter happens when a
component was registered but its init failed partway through. The
pre-pass also cancels any active pipeline pipe_task so
ipc_pipeline_free() does not stall waiting for it (up to 100 LL
periods on native_sim).
* Snapshots IDs into a local array per pass rather than walking and
mutating comp_list simultaneously (the SOF free helpers unlink each
entry).
* Frees in dependency order COMPONENT -> BUFFER -> PIPELINE so the
topology layer never dereferences an already-freed parent. The
BUFFER pass is compiled out for IPC4 because ipc4/helper.c never
stores COMP_TYPE_BUFFER and ipc_buffer_free() does not exist there.
* Ends with a force-drain pass that removes anything still on the list
with list_item_del() + rfree(), keeping comp_list guaranteed empty
on return and the harness robust against future COMP_TYPE_*
additions.
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
tmleman
requested review from
dbaluta,
kv2019i,
lbetlej,
lgirdwood,
mmaka1 and
plbossart
as code owners
August 5, 2026 16:58
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves libFuzzer testcase isolation on the POSIX platform by ensuring each LLVMFuzzerTestOneInput() begins with an empty IPC topology, preventing cross-testcase carry-over in global_ipc->comp_list.
Changes:
- Add a POSIX-only
posix_ipc_teardown()helper that attempts to free any leftover IPC-tracked objects from the previous testcase. - Add a pre-pass to make leftover components/pipelines “freeable” (force component state to
COMP_STATE_READY, initialize missing buffer-list heads, cancel activepipe_task). - Call the teardown from
posix_fuzz_case_begin()so cleanup happens before staging new fuzz input.
Suppressed comments (1)
src/platform/posix/ipc.c:149
- The force-drain pass is also capped at POSIX_TEARDOWN_MAX_DEVS, so if more than 256 entries remain it will leave comp_list non-empty. Since this pass deletes entries directly, it can safely walk with list_for_item_safe() and drain the entire list without a fixed-size ID snapshot.
/*
* Force-drain anything remaining (unknown/future COMP_TYPE_*).
* Snapshot the residual list then remove each entry directly.
* The inner union pointer leaks, but comp_list will be empty
* and the next testcase will not observe stale entries.
*/
Comment on lines
+117
to
+121
| for (int pass = 0; pass < (int)ARRAY_SIZE(free_order); pass++) { | ||
| uint16_t type = free_order[pass]; | ||
|
|
||
| n = 0; | ||
| list_for_item(pos, &global_ipc->comp_list) { |
kv2019i
approved these changes
Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Without an explicit teardown a fuzz testcase that successfully creates components, buffers or pipelines leaves them registered in global_ipc->comp_list. The next LLVMFuzzerTestOneInput() then sees a non-empty topology it never asked for, which both hides bugs (crashes that depend on freshly-empty state are missed) and fabricates them (crashes that only occur because of carry-over from a previous case are unreproducible when the artifact is replayed on its own).
Add a posix-only teardown helper, called from posix_fuzz_case_begin() once at the start of every testcase before the input is staged. The helper: