Skip to content

Commit 94776bf

Browse files
committed
audio: pipeline: guard NULL buffer peer in pipeline_get_dai_comp
The IPC fuzzer built an IPC3 pipeline whose component owned a half-connected buffer - present on the component's buffer list but with no component attached to its opposite end - and then issued a SOF_IPC_STREAM_POSITION request. ipc_stream_position() calls pipeline_get_timestamp(), which walks the graph with pipeline_get_dai_comp() to locate the DAI endpoint. For each hop the walk takes the buffer's peer component via buffer_get_comp() and immediately dereferences comp->pipeline. For a dangling buffer buffer_get_comp() returns NULL, so the read faults at NULL + 8 (the ->pipeline field). A comp_buffer only carries a peer on a side once both ends are attached, but the IPC3 graph is assembled incrementally (each COMP_CONNECT attaches a single end) so a buffer can be left half-connected. The STREAM_POSITION path reaches this walk directly, independent of the trigger path, and does not go through the pipeline-run connectivity checks: a pipeline can be completed and then have a half-connected buffer attached by a later COMP_CONNECT, and a subsequent POSITION request walks the dangling edge. Guard the peer before dereferencing it, mirroring the existing checks in the tree: the IPC4 sibling pipeline_get_dai_comp_latency() already checks "if (!source || !source->pipeline)", and the XRUN rewind walk in pipeline_trigger_xrun() checks "if (!buffer_comp || !buffer_comp->pipeline)". A fully-connected buffer always has a non-NULL peer and a cross-pipeline peer keeps a non-NULL pointer, so only a genuinely dangling buffer is rejected and valid topologies are unaffected. pipeline_get_timestamp() already tolerates a NULL DAI result. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
1 parent 8d59dd2 commit 94776bf

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

src/audio/pipeline/pipeline-graph.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,10 @@ struct comp_dev *pipeline_get_dai_comp(uint32_t pipeline_id, int dir)
506506
buffer = buffer_from_list(blist->next, dir);
507507
comp = buffer_get_comp(buffer, dir);
508508

509-
/* buffer_comp is in another pipeline and it is not complete */
510-
if (!comp->pipeline)
509+
/* A half-connected buffer has no peer component on this side, or
510+
* buffer_comp is in another pipeline and it is not complete.
511+
*/
512+
if (!comp || !comp->pipeline)
511513
return NULL;
512514

513515
crt = ipc_get_ppl_comp(ipc, comp->pipeline->pipeline_id, dir);

0 commit comments

Comments
 (0)