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
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.
*/
kv2019i
approved these changes
Aug 6, 2026
tmleman
force-pushed
the
topic/upstream/pr/fuzzing/enhancement/part7
branch
from
August 7, 2026 07:38
8e0e442 to
b1d8c55
Compare
tmleman
requested review from
abonislawski,
serhiy-katsyuba-intel,
softwarecki and
wjablon1
August 7, 2026 07:39
tmleman
force-pushed
the
topic/upstream/pr/fuzzing/enhancement/part7
branch
from
August 7, 2026 07:39
b1d8c55 to
24df679
Compare
serhiy-katsyuba-intel
approved these changes
Aug 7, 2026
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).
* Drains each type in batches: it snapshots up to POSIX_TEARDOWN_BATCH
ids, frees them with the typed helper, and repeats until no entry of
that type remains, so the number of objects a testcase creates is not
bounded by the snapshot size (walking and freeing comp_list in one
pass is unsafe because the SOF free helpers unlink each entry). A
batch that frees nothing ends the loop so it cannot spin forever.
* 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 walks the whole residual list with
list_for_item_safe() and removes each entry with list_item_del() +
rfree(), so comp_list is guaranteed empty on return regardless of how
many objects remained or of any future COMP_TYPE_* the typed passes
do not cover.
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
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: