-
Notifications
You must be signed in to change notification settings - Fork 133
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
ASoC: SOF: Check runtime for nullity in rx IPCs #5214
Conversation
There is a failure case where the DSP reports the status of a stream after the kernel has given up and closed out the pcm. When this happens the runtime parameter on the substream is nulled out by ASoC in the pcm_close call back. This results in a NULL pointer derefence if not checked. Signed-off-by: Curtis Malainey <[email protected]>
Note: I have been unable to get the SOF kernel to boot on a device so this is untested. @dbaluta I had a hard time checking if this is also needed for the compressed offload use case. Can you confirm? |
Confirmed my kernel issues are unrelated to this change. |
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, it is valid, given that we never clear the sps->substream
, it is not going to be NULL after the first audio activity.
return -ESTRPIPE; | ||
|
||
struct sof_compr_stream *sstream = runtime->private_data; | ||
|
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 would probably add this as well:
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 62ce707abaa6..7a55bc65bdf1 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -511,6 +511,8 @@ static int sof_pcm_close(struct snd_soc_component *component,
*/
}
+ spcm->stream[substream->stream].substream = NULL;
+
return 0;
}
We never clear the substream, just set it... This alone might work?
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 this won't fix it. This would still result in the same bug because you would just then just hit a NULL pointer on the cstream.
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.
the sps->cstream is cleared to NULL in compress.c, only the PCM substream missed the reset to NULL.
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.
the sps->cstream is cleared to NULL in compress.c, only the PCM substream missed the reset to NULL.
Right, you would hit different NULL as in sof_ipc_msg_data()
the check for sps->cstream == NULL
is missing and assumed to be non NULL if substream was NULL.
sof_set_stream_data_offset()
does this correctly...
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 might work for the compress stream case:
diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c
index 794c7bbccbaf..bcfb4114e4b6 100644
--- a/sound/soc/sof/stream-ipc.c
+++ b/sound/soc/sof/stream-ipc.c
@@ -43,7 +43,7 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev,
return -ESTRPIPE;
posn_offset = stream->posn_offset;
- } else {
+ } else if (sps->cstream) {
struct sof_compr_stream *sstream = sps->cstream->runtime->private_data;
@@ -51,6 +51,9 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev,
return -ESTRPIPE;
posn_offset = sstream->posn_offset;
+ } else {
+ dev_err(sdev->dev, "%s: No stream opened\n", __func__);
+ return -EINVAL;
}
snd_sof_dsp_mailbox_read(sdev, posn_offset, p, sz);
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.
Good find.
Please read the commit message fully, I understand SOF never clears runtime, but ASoC does NULL it out. See |
@cujomalainey, I have said nothing about runtime (and yes, ASoC clears it) I was saying the |
Apologies it sounds like your original message was a counter to patch in that the fix was not needed. |
I personally think this is the proper fix, also friendly ping for reviews since CI failures are in unrelated modules to the change. |
Have you by any chance tested my proposal? diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 62ce707abaa6..7a55bc65bdf1 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -511,6 +511,8 @@ static int sof_pcm_close(struct snd_soc_component *component,
*/
}
+ spcm->stream[substream->stream].substream = NULL;
+
return 0;
}
diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c
index 794c7bbccbaf..8262443ac89a 100644
--- a/sound/soc/sof/stream-ipc.c
+++ b/sound/soc/sof/stream-ipc.c
@@ -43,7 +43,7 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev,
return -ESTRPIPE;
posn_offset = stream->posn_offset;
- } else {
+ } else if (sps->cstream) {
struct sof_compr_stream *sstream = sps->cstream->runtime->private_data;
@@ -51,6 +51,10 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev,
return -ESTRPIPE;
posn_offset = sstream->posn_offset;
+
+ } else {
+ dev_err(sdev->dev, "%s: No stream opened\n", __func__);
+ return -EINVAL;
}
snd_sof_dsp_mailbox_read(sdev, posn_offset, p, sz); I don't have the setup to reproduce this issue. |
@ujfalusi can you add more context why this proposal is better than the current PR, i.e. what is your proposal checking that the current PR does not. This will help us align quickly since we have a crash. |
The |
Technically viable, but this is changing lifetypes of a pointer, I think a simple and safe fix to stop the bleeding to should go out first. If you want to make a longer term fix then be my guest but that should not block a fix for a bug in the field. |
The bug is that the lifetime of if for any reason the firmware sends a position notification before the first playback is started (sps->stream/cstream is still NULL) then we will have NULL dereference with the sps->cstream, but not in sof_set_stream_data_offset(), which handles things correctly. |
Fair point, I was viewing it as substream existed before PCM open, if that is not the case then yours makes sense. |
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]>
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]>
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: thesofproject#5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The nullity of sps->cstream should be checked similarly as it is done in sof_set_stream_data_offset() function. Assuming that it is not NULL if sps->stream is NULL is incorrect and can lead to NULL pointer dereference. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
The spcm->stream[substream->stream].substream is set during open and was left untouched. After the first PCM stream it will never be NULL and we have code which checks for substream NULLity as indication if the stream is active or not. For the compressed cstream pointer the same has been done, this change will correct the handling of PCM streams. Fixes: ef8ba9f ("ASoC: SOF: Add support for compress API for stream data/offset") Cc: [email protected] Reported-by: Curtis Malainey <[email protected]> Closes: #5214 Signed-off-by: Peter Ujfalusi <[email protected]> Reviewed-by: Daniel Baluta <[email protected]> Reviewed-by: Ranjani Sridharan <[email protected]> Reviewed-by: Bard Liao <[email protected]> Reviewed-by: Curtis Malainey <[email protected]>
There is a failure case where the DSP reports the status of a stream after the kernel has given up and closed out the pcm. When this happens the runtime parameter on the substream is nulled out by ASoC in the pcm_close call back. This results in a NULL pointer derefence if not checked.