| From d3268a40d4b19ff7bee23f52eabbc4e96bb685e8 Mon Sep 17 00:00:00 2001 |
| From: Qais Yousef <qais.yousef@imgtec.com> |
| Date: Wed, 14 Jan 2015 08:47:29 +0000 |
| Subject: ASoC: soc-compress.c: fix NULL dereference |
| |
| From: Qais Yousef <qais.yousef@imgtec.com> |
| |
| commit d3268a40d4b19ff7bee23f52eabbc4e96bb685e8 upstream. |
| |
| In soc_new_compress() when rtd->dai_link->dynamic 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 using rtd->dai_link->dpcm_playback and rtd->dai_link->dpcm_capture as |
| playback_count and capture_count to snd_pcm_new_internal(). |
| |
| Signed-off-by: Qais Yousef <qais.yousef@imgtec.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/soc/soc-compress.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| --- a/sound/soc/soc-compress.c |
| +++ b/sound/soc/soc-compress.c |
| @@ -666,7 +666,8 @@ int soc_new_compress(struct snd_soc_pcm_ |
| rtd->dai_link->stream_name); |
| |
| ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, |
| - 1, 0, &be_pcm); |
| + rtd->dai_link->dpcm_playback, |
| + rtd->dai_link->dpcm_capture, &be_pcm); |
| if (ret < 0) { |
| dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n", |
| rtd->dai_link->name); |
| @@ -675,8 +676,10 @@ int soc_new_compress(struct snd_soc_pcm_ |
| |
| 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; |
| + if (rtd->dai_link->dpcm_playback) |
| + be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; |
| + else if (rtd->dai_link->dpcm_capture) |
| + 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)); |