-
Notifications
You must be signed in to change notification settings - Fork 349
ipc3: get_drv: Check comp_type also when driver is matched with UUID #7891
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
Conversation
|
The fuzzing failure seems relevant. cc: @andyross your work in action! This is funny: I just clicked on the most recent PR looking only for fuzzer startup times in order to close #7629 and I find what looks like an actual catch. |
87da089 to
863eae7
Compare
This was excellent. My quick test if the this kind of fix would cause other problems (if the comp type check would be too strict in some cases) had a weakness that would not show in the normal tests, but the fuzzer found it immediately. |
bab7a52 to
b4563a5
Compare
|
I think this is now ready for review even if CI tests are still running. |
src/ipc/ipc3/helper.c
Outdated
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.
what exactly is this condition: drv->type == SOF_COMP_MODULE_ADAPTER? So it's possible to have a component in topology with UUID, matching SOF_COMP_MODULE_ADAPTER but with a different type? Or how is this possible?
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.
I see what you are doing here, but it doesn't validate that the comp type is the right type. E.g. this still leaves the possibility for a SRC UUID with a VOL ENUM.
@lyakh how terrible would it be if we just moved that busted switch case out to each component and just container_of our way back to the correct pointer for vol and src?
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.
For instance MUX components use module adapter. I could not figure out how dig out what is hidden behind the module adapter framework. The nature of IPC3 is still quite strange to me.
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.
bleh, my container_of approach won't work since the data is parsed and copied, not aliased.
Honestly I am more and more inclined to just suggest we go back to #7830 (with an additional guard for vol) and move that check into a IPC3 only block. There is no easy way fix the protocol without making a major revision (deprecating the enum field) and fixing legacy component init payloads. Also if we ifdef it around IPC3 it will be very clear it can be deleted when IPC3 is removed from the repo.
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.
we can try to modify module_adapter.c to resolve this issue.
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.
@cujomalainey @jsarha it seems to me that we just have to go with the "first principles" here: if we don't trust what we get over IPC, then we need to check everything. E.g. .type is checked in comp_specific_builder() but unrecognised type is just silently ignored and that doesn't seem right to me. Because if we do happen to have comp->ext_data_length != 0 then get_drv() might use UUID to get a matching driver and we'll continue with an invalid type.
Then we also get size from those topology IPCs. And in general it's valid for module-adapter components to have a size of 0. In that case no initialisation data is allocated. So individual drivers must check for that, yes.
src/ipc/ipc3/helper.c
Outdated
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.
goto out with drv == NULL is equivalent to return NULL really, but they do the goto everywhere in this function...
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.
Yes... maybe in the history lock have been kept trough out the function. No point for the label really now. I can drop it, unless we change the approach again...
cujomalainey
left a comment
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.
patch doesn't provide a way to make sure enum is valid.
Also please use my work email in the tag, thanks
|
Now that I look give this another though, this fix is not really good for anything. Now that I am trying to follow the original root cause[1] I am little by little leaning back to my original fix [2] or a variation of it. The actual root cause and the fundamental problem with the init message interpretation is the fact that the sender can send what ever payload to what ever module. Fixing the switch-case in module_adapter_new() is not enough. The comp_common_builder() and comp_specific_builder() will anyway create the 'union ipc_config_specific spec' according to the found ipc type and copy the contents from the actual payload according to it. So about generic fix, I do not think there is any low hanging fruit. One way could be adding the accepted message types to struct comp_driver and give it as an extra parameter to DECLARE_MODULE_ADAPTER(), and checking the type in get_drv(). The above would fix the issue we are working on, but if that really a generic fix? The fuzzer does not obey any message structures and we really cannot make any assumptions of the passed configuration data in the module. I do not see there is really any way around that the modules just have to be made robust enough to not to crash on bad or missing configuration data. [1] #7830 (comment) What do you say @lyakh & @cujomalainey ? |
Looks like we were typing at the same time :) see #7891 (comment) |
|
Can one of the admins verify this patch? |
|
This fix is not very useful since it cannot check message types through module_adapter. |
|
... let's test the concept. |
b4563a5 to
a83bd1b
Compare
|
@jsarha some build issues ? |
a83bd1b to
2cc2302
Compare
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.
this is a rather significant change, and I think it will break at least this check:
sof/src/audio/module_adapter/module_adapter.c
Line 135 in 7027228
| if (drv->type == SOF_COMP_MODULE_ADAPTER) { |
comp_specific_builder() would only affect IPC3. @ranj063 do you think this is a good idea?
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.
@lyakh , but how would I know in comp_specific_builder() what kind of messages the module - found with uuid - actually accepts, unless its somehow built in to the module? I can of course add an extra member to struct comp_driver, but I do not think this issue can not be solved without adding the accepted component message type to each module.
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.
No, don't think it's possible to check the type generically in common code for all components with the current module-adapter API. That's why I'm not proposing that. Instead I'm just proposing to (1) check that the type value in IPC is meaningful - one of the values, that the firmware recognises, and error out otherwise, instead of silently ignoring it, and (2) in each individual component driver check that the type from the IPC is correct
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.
Ok, simple enough.
Add a safe guard against malformed SOF_IPC_TPLG_COMP_NEW messages where the UUID matched driver type does not match the component type in the message. Also moves the !drv check outside of &drivers->lock block. Reported-by: Curtis Malainey <cujomalainey@chromium.org> Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
2cc2302 to
7146f83
Compare
|
This approach would be doable, but it would touch every module. Maybe not something worth doing for phasing out IPC3. Closing this PR. There is much simpler PR for not accepting unknown component types here: #7948 |
Add a safe guard against malformed SOF_IPC_TPLG_COMP_NEW messages where the UUID matched driver type does not match the component type in the message.
Reported-by: Curtis Malainey curtis@malainey.com
related discussions can be found here: #7830