Skip to content

ASoC: soc-pcm: fix handling of NULL be_substream - #4085

Closed
kv2019i wants to merge 3 commits into
thesofproject:topic/sof-devfrom
kv2019i:202212-fix-echo-ref
Closed

kv2019i wants to merge 3 commits into
thesofproject:topic/sof-devfrom
kv2019i:202212-fix-echo-ref

Conversation

@kv2019i

@kv2019i kv2019i commented Dec 8, 2022

Copy link
Copy Markdown
Collaborator

Fix a few regressions related to handling cases where there are multiple BEs but one of the BE substreams is NULL.

This happens e.g. with echo reference PCM when it is opened with the playback stream not running. FW will return -ENODATA in this case, but with curent kernel, the kernel with hit an OOPS.

Comment thread sound/soc/soc-pcm.c
return -EINVAL;
}
if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) {
if (be_substream && fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting. In this case we are creating a loophole that misaligned 'atomicity' can slip through?

@plbossart plbossart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand how this configuration might work @kv2019i, with no be_substream there would be no trigger. This is super-weird.

Comment thread sound/soc/soc-pcm.c
Comment thread sound/soc/soc-pcm.c
@plbossart

ghost commented Dec 9, 2022

Copy link
Copy Markdown
Member

@kv2019i see suggested extension in plbossart@3998038 and configuration changes in #4092

Kai Vehmanen added 3 commits December 14, 2022 18:44
Fix a NULL dereference in dpcm_process_paths() in a case where
there are multiple BEs, but one of them does not have a substream.

[ 94.483796] RIP: 0010:dpcm_process_paths+0x1c4/0x585
...
[ 94.483882] dpcm_fe_dai_open+0x8f/0x791
[ 94.483901] snd_pcm_open_substream+0x554/0x7f2
[ 94.483911] snd_pcm_open+0xd2/0x1fa

Fixes: bbf7d3b ("ASoC: soc-pcm: align BE 'atomicity' with that of the FE")
Link: thesofproject#4083
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Fix a NULL dereference in snd_soc_dpcm_stream_lock_irqsave_nested() in a
case where there are multiple BEs, but one of them does not have a
substream.

Fixes: b2ae806 ("ASoC: soc-pcm: serialize BE triggers")
Link: thesofproject#4083
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
When performing actions on BEs using for_each_dpcm_be(), there
are multiple places where the BE substream is assumed to be non-NULL.
It is possible however to define such topologies in machine drivers
and the soc_pcm functions should handle such errors gracefully
without kernel oops on NULL dereference.

Link: thesofproject#4083
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
@kv2019i
kv2019i force-pushed the 202212-fix-echo-ref branch from b78b280 to 80afc9e Compare December 14, 2022 18:21
@kv2019i

ghost commented Dec 14, 2022

Copy link
Copy Markdown
Collaborator Author

@plbossart wrote:

@kv2019i see suggested extension in plbossart@3998038 and configuration changes in #4092

V2 uploaded with a patch added.

Given the original oops is fixed with other means, I'm now wondering whether I should squash all three patches and remove the Fixes-tag. And just keep a link to the SOF issue for reference. That might be more appropriate now.

ghost left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One case that remains questionable.
I'd keep the fixes tag, it's fine IMHO.

Comment thread sound/soc/soc-pcm.c
be_substream->runtime = NULL;
if (be_substream) {
__soc_pcm_close(be, be_substream);
be_substream->runtime = NULL;

ghost Dec 14, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 1569 is still using the be_substream. Not clear to me why you chose to protect the close() but not the hw_free()?

ghost Dec 14, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually you do protect the hw_free in the other case line 1946 now, so it's inconsistent.

ghost Dec 15, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart Ran out of time, but I now realized some of the checks are superfluous as "be->dpcm[stream].state" can only be in limited states when BE substream is NULL. Need to go through all the additions. E.g. I think the case of L1946 is not needed.

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In dpcm_be_dai_stop(), be->dpcm[stream].users will be NULL as the BE is skipped in dai_startup(), so this check is not needed.

ghost left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@plbossart I went through all cases and it seems it was no accident we only hit a NULL deref in the two places (covered by first two patches) in soc-pcm.c. The other code locations where be_substream is used, are already protected via either stream-state or users-count (see comments inline). So I'm thinking of going back to the original two patches.

Comment thread sound/soc/soc-pcm.c
be_substream->runtime = NULL;
if (be_substream) {
__soc_pcm_close(be, be_substream);
be_substream->runtime = NULL;

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In dpcm_be_dai_stop(), be->dpcm[stream].users will be NULL as the BE is skipped in dai_startup(), so this check is not needed.

Comment thread sound/soc/soc-pcm.c

__soc_pcm_hw_free(be, be_substream);
if (be_substream)
__soc_pcm_hw_free(be, be_substream);

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here checks on "be->dpcm[stream].state" at L1935 protect against NULL be_substream usage.

Comment thread sound/soc/soc-pcm.c

if (!be_substream)
continue;

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, checks on stream state on L2013 help to avoid NULL usage.

Comment thread sound/soc/soc-pcm.c

if (!be_substream)
continue;

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here, checks on L2050.

Comment thread sound/soc/soc-pcm.c

if (!be_substream)
continue;

ghost Dec 16, 2022

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here likewise, L2418.

@plbossart

ghost commented Dec 16, 2022

Copy link
Copy Markdown
Member

@plbossart I went through all cases and it seems it was no accident we only hit a NULL deref in the two places (covered by first two patches) in soc-pcm.c. The other code locations where be_substream is used, are already protected via either stream-state or users-count (see comments inline). So I'm thinking of going back to the original two patches.

I don't have the time today to look into this is details, so will trust your analysis @kv2019i. Maybe just add a comment in the commit message that all other cases are already protected via either stream-state or users-count.

@plbossart

ghost commented Apr 17, 2023

Copy link
Copy Markdown
Member

@kv2019i what do you want to do with this PR? Merge it as it and send upstream, or close it?

@kv2019i

ghost commented May 9, 2023

Copy link
Copy Markdown
Collaborator Author

Closing until I have bandwidth to work on this.

@kv2019i kv2019i closed this May 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants