[alsa-devel] [PATCH] ALSA: ASoC: soc-compress.c: fix NULL dereference
In soc_new_compress() when rtd->dai_link->daynmic is set, we create the pcm substreams with this call:
ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 1, 0, &be_pcm);
which passes 0 as capture_count leading to
be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream
being NULL, hence when trying to set rtd a few lines below we get an oops. Fix by removing this line of code since CAPTURE substream will always be NULL.
Signed-off-by: Qais Yousef qais.yousef@imgtec.com Cc: Vinod Koul vinod.koul@intel.com Cc: Liam Girdwood lgirdwood@gmail.com Cc: Mark Brown broonie@kernel.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.de Cc: linux-kernel@vger.kernel.org --- Not sure if this is the correct fix but that's what I could come up with my limited knowledge.
I think the more correct solution would be to use the value of rtd->dai_link->dpcm_playback and rtd->dai_link->dpcm_capture in the args of snd_pcm_new_internal() for playback_count and capture_count.
sound/soc/soc-compress.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 590a82f01d0b..7ab39f65384c 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -669,7 +669,6 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) rtd->pcm = be_pcm; rtd->fe_compr = 1; be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; - be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); } else memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
On Tue, Dec 23, 2014 at 09:09:27AM +0000, Qais Yousef wrote:
In soc_new_compress() when rtd->dai_link->daynmic is set, we create the pcm substreams with this call:
ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 1, 0, &be_pcm);
which passes 0 as capture_count leading to
be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream
being NULL, hence when trying to set rtd a few lines below we get an oops. Fix by removing this line of code since CAPTURE substream will always be NULL.
Why will the capture stream always be NULL? There should be no intrinsic reason why we can't have hardware support for capturing compressed audio.
On 12/29/2014 04:13 PM, Mark Brown wrote:
On Tue, Dec 23, 2014 at 09:09:27AM +0000, Qais Yousef wrote:
In soc_new_compress() when rtd->dai_link->daynmic is set, we create the pcm substreams with this call:
ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, 1, 0, &be_pcm);
which passes 0 as capture_count leading to
be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream
being NULL, hence when trying to set rtd a few lines below we get an oops. Fix by removing this line of code since CAPTURE substream will always be NULL.
Why will the capture stream always be NULL? There should be no intrinsic reason why we can't have hardware support for capturing compressed audio.
I think because we pass 0 as capture_count in snd_pcm_new_internal(). If I read the code correctly this will lead to _snd_pcm_new() to be called which in return will call snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count) which will cause no substream to be allocated for the capture case, hence being NULL. I get an oops in my experimental driver when I set dynamic = 1 in FE dai link. If I did something wrong there that caused this, it's not obvious to me how.
Maybe a better fix would be to replace the 1 and 0 in snd_pcm_new_internal() call with rtd->dai_link->dpcm_playback and rtd->dai_link->dpcm_capture.
participants (2)
-
Mark Brown
-
Qais Yousef