-
Notifications
You must be signed in to change notification settings - Fork 349
copier: fix NULL converter crash for non-zero sink_queue_id #10257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
copier: fix NULL converter crash for non-zero sink_queue_id #10257
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a NULL pointer dereference crash in the IPC4 copier module that occurs when sink buffer IDs map to non-zero sink_queue_id values but the corresponding converters are not initialized.
Key Changes
- Adds initialization logic for converters based on actual sink buffer queue IDs
- Iterates through all connected sink buffers to determine required converter array indices
- Validates sink_queue_id values are within the expected range
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
Hm, that's does not look right. Converters for output pins 1 to 3 are setup in COPIER_MODULE_CFG_PARAM_SET_SINK_FORMAT handler. The problem here seems is caused by the only output pin has ID 1 instead of 0. This looks more like either a test script problem (wrong pin number in bind operation); or maybe using IPC4_SINK_QUEUE_ID(buf_get_id(sink)) (this gets pin index from buffer id?) is a bad idea and can get wrong pin indices. |
I considered the absence of The problematic aspect here seems to be the sink ID (1). When the copier is bound to AEC, in IPC we get source queue id 0 and sink queue id 1. |
|
Maybe the problem here is that instead of IPC4_SINK_QUEUE_ID(), IPC4_SRC_QUEUE_ID() should be used? The buffer is connected to sink of the copier, so from buffer's point of view, copier's sink is source and IPC4_SRC_QUEUE_ID() should be used to extract copier sink index. |
--- a/src/audio/copier/copier.c
+++ b/src/audio/copier/copier.c
@@ -540,7 +540,7 @@ static int do_conversion_copy(struct comp_dev *dev,
comp_get_copy_limits(src, sink, processed_data);
- i = IPC4_SINK_QUEUE_ID(buf_get_id(sink));
+ i = IPC4_SRC_QUEUE_ID(buf_get_id(sink));
if (i >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT)
return -EINVAL;
buffer_stream_invalidate(src, processed_data->source_bytes);
@@ -617,7 +617,7 @@ static int copier_module_copy(struct processing_module *mod,
uint32_t source_samples;
int sink_queue_id;
- sink_queue_id = IPC4_SINK_QUEUE_ID(buf_get_id(sink_c));
+ sink_queue_id = IPC4_SRC_QUEUE_ID(buf_get_id(sink_c));
if (sink_queue_id >= IPC4_COPIER_MODULE_OUTPUT_PINS_COUNT)
return -EINVAL;I tested it and it works, but maybe due to the naming, it looks like a hack. Although upon closer inspection, it makes sense. We are looking for the source ID for a module that is a sink from our copier perspective. |
|
Looked into code, yes, the problem is caused by using IPC4_SINK_QUEUE_ID(buf_get_id(sink)) in do_conversion_copy() instead of IPC4_SRC_QUEUE_ID(). Here is how pin indices are put into buffer id: So do_conversion_copy() should use IPC4_SRC_QUEUE_ID() to get copier's sink index. |
b272bf3 to
25bbf5c
Compare
Fix NULL pointer dereference crash in copier module by using the correct IPC4 macro to extract queue IDs from buffer IDs. The issue occurred in do_conversion_copy() and copier_module_copy() when accessing cd->converter[i] where i was extracted using IPC4_SINK_QUEUE_ID(). This was incorrect because buffer IDs are constructed as: IPC4_COMP_ID(src_queue, dst_queue) From the buffer's perspective, the copier's sink is actually the source, so IPC4_SRC_QUEUE_ID() should be used to get the correct copier sink index. Using IPC4_SINK_QUEUE_ID() extracted the dst_queue (upper 16 bits) instead of src_queue (lower 16 bits), leading to wrong array indices and NULL pointer crashes when the converter array wasn't initialized for those indices. This resolves crashes in RTC AEC topologies where internal module copiers have buffer IDs that map to non-zero queue IDs. Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
|
@tmleman @kv2019i @abonislawski I will cherry pick this fix for v2.14. Thanks |
This is a follow-up to thesofproject#10257. This fixes all incorrect uses of IPC4_SRC_QUEUE_ID() and IPC4_SINK_QUEUE_ID(). Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
This is a follow-up to thesofproject#10257. This fixes all occurrences of incorrect use of IPC4_SRC_QUEUE_ID() and IPC4_SINK_QUEUE_ID(). IPC4_SRC_QUEUE_ID() expects buffer as a parameter and returns the queue ID of the module that produces data for that buffer. So from the buffer's point of view, such a module and queue is the source (hence the name IPC4_SRC_QUEUE_ID()), however, from the module's point of view, such a queue is a sink. That, unfortunately, makes it easy to make a mistake when deciding whether IPC4_SRC_QUEUE_ID() vs. IPC4_SINK_QUEUE_ID() should be used. Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
This is a follow-up to #10257. This fixes all occurrences of incorrect use of IPC4_SRC_QUEUE_ID() and IPC4_SINK_QUEUE_ID(). IPC4_SRC_QUEUE_ID() expects buffer as a parameter and returns the queue ID of the module that produces data for that buffer. So from the buffer's point of view, such a module and queue is the source (hence the name IPC4_SRC_QUEUE_ID()), however, from the module's point of view, such a queue is a sink. That, unfortunately, makes it easy to make a mistake when deciding whether IPC4_SRC_QUEUE_ID() vs. IPC4_SINK_QUEUE_ID() should be used. Signed-off-by: Serhiy Katsyuba <serhiy.katsyuba@intel.com>
This PR fixes a NULL pointer dereference crash in the IPC4 copier module that occurs when sink buffer IDs map to non-zero
sink_queue_idvalues but corresponding converters are not initialized.Problem Description
The crash occurs in
do_conversion_copy()when accessingcd->converter[i]whereiis extracted from sink buffer IDs usingIPC4_SINK_QUEUE_ID(buf_get_id(sink)).Root Cause
IPC4_SINK_QUEUE_ID()can extract non-zero queue IDs from buffer IDs, even in single-sink scenarioscopier_prepare()only initializesconverter[0]for pin 0converter[1]when onlyconverter[0]exists causes NULL pointer dereferenceCrash Conditions
The crash occurs when all conditions are met:
endpoint_num == 0(module copier, not gateway copier)sink_queue_idviaIPC4_SINK_QUEUE_ID()converter[0]was initialized incopier_prepare()converter[sink_queue_id]wheresink_queue_id != 0Example: Buffer ID
0x10000extracts tosink_queue_id=1, but onlyconverter[0]exists.Current Implementation
copier_prepare()only initializesconverter[0]:This assumes all sink buffers map to
sink_queue_id=0, which is incorrect when buffer IDs encode different queue information.Test Pipeline Description
The crash occurs in RTC AEC topologies with internal module copiers. Example topology:
flowchart TD subgraph Pipeline0 direction LR style Pipeline0 fill:#daf5e5,stroke:#3cb371,stroke-width:2px copier0["COPIER <br/> Module Id: 0x3 <br/> Instance Id: 0x0 <br/> HOST -> DSP <br/> 4/16(16)/48000"] --> aec["RTC AEC <br/> Module Id: 0x2000 <br/> Instance Id: 0x0"] aec --> copier1["COPIER <br/> Module Id: 0x3 <br/> Instance Id: 0x1 <br/> HOST <- DSP <br/> 4/16(16)/48000"] end subgraph Pipeline1 direction LR style Pipeline1 fill:#daf5e5,stroke:#3cb371,stroke-width:2px copier2["COPIER <br/> Module Id: 0x3 <br/> Instance Id: 0x3 <br/> HOST -> DSP <br/> 2/16(16)/48000"] --> copier3["COPIER <br/> Module Id: 0x3 <br/> Instance Id: 0x2"] copier3 --> aec endThe crash occurs in copier3 (Instance 0x2), an internal module copier (
endpoint_num == 0) whose sink buffer ID maps to non-zerosink_queue_id, but the corresponding converter was never initialized.