diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-05-19 11:35:13 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-05-19 11:35:13 +0200 |
commit | 4214c5349c20005b7a83916801394eb7270896b2 (patch) | |
tree | fdb111598c33ce1601cead948ac12a4249b09295 | |
parent | 1882b0577b5b67e7b663be4e8126997423b6cb6f (diff) | |
download | lwn-4214c5349c20005b7a83916801394eb7270896b2.tar.gz lwn-4214c5349c20005b7a83916801394eb7270896b2.zip |
ALSA: hda - Fix NULL dereference from CA0132 DSP loader
The CA0132 DSP loader leads to NULL deference since the recent
transition to HDA core code, as it unconditionally accesses
hdac_stream->substream->runtime. For DSP loading, the substream
shouldn't be assigned.
This patch addresses the NULL dereference above in addition to assure
the substream is cleared while DSP loading.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=98151
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/hda/hdac_stream.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 52a894fe478f..4c15d0accc9e 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -139,9 +139,13 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_reset); int snd_hdac_stream_setup(struct hdac_stream *azx_dev) { struct hdac_bus *bus = azx_dev->bus; - struct snd_pcm_runtime *runtime = azx_dev->substream->runtime; + struct snd_pcm_runtime *runtime; unsigned int val; + if (azx_dev->substream) + runtime = azx_dev->substream->runtime; + else + runtime = NULL; /* make sure the run bit is zero for SD */ snd_hdac_stream_clear(azx_dev); /* program the stream_tag */ @@ -189,14 +193,15 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev) * we ignore it; currently set the threshold statically to * 64 frames */ - if (runtime->period_size > 64) + if (runtime && runtime->period_size > 64) azx_dev->delay_negative_threshold = -frames_to_bytes(runtime, 64); else azx_dev->delay_negative_threshold = 0; /* wallclk has 24Mhz clock source */ - azx_dev->period_wallclk = (((runtime->period_size * 24000) / + if (runtime) + azx_dev->period_wallclk = (((runtime->period_size * 24000) / runtime->rate) * 1000); return 0; @@ -611,6 +616,7 @@ int snd_hdac_dsp_prepare(struct hdac_stream *azx_dev, unsigned int format, if (err < 0) goto err_alloc; + azx_dev->substream = NULL; azx_dev->bufsize = byte_size; azx_dev->period_bytes = byte_size; azx_dev->format_val = format; |