From 4a7756137df3efd31eef5b29869f6567c932e52c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Sun, 24 Nov 2019 23:16:30 -0800 Subject: [PATCH 1/2] ALSA: pcm: add locks for accessing runtime resource Add spin lock to resolve race conditions while accessing substream runtime resource. CRs-fixed: 2112713 Change-Id: I8db743303ceb50205d62adfc02caf6ecab635d47 Signed-off-by: Karthikeyan Mani Signed-off-by: Meng Wang --- include/sound/pcm.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index bbe6eb1ff5d2..cf563e968513 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -475,6 +475,9 @@ struct snd_pcm_substream { #endif /* CONFIG_SND_VERBOSE_PROCFS */ /* misc flags */ unsigned int hw_opened: 1; +#ifdef CONFIG_AUDIO_QGKI + spinlock_t runtime_lock; +#endif }; #define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0) From d15c33d652fae895682a2ed0c6009b28ac468084 Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Sun, 24 Nov 2019 23:20:29 -0800 Subject: [PATCH 2/2] ALSA: pcm: use lock to protect substream runtime resource Use a spinlock to protect runtime resource in substream against race conditions which may lead to use-after-free. CRs-fixed: 2112713 Change-Id: I37dee68cad5eae05b21cfade3dabc0c2b79be6b8 Signed-off-by: Karthikeyan Mani Signed-off-by: Meng Wang --- sound/core/pcm.c | 12 ++++++++++++ sound/core/pcm_timer.c | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 9a72d641743d..15d4ff893aba 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -691,6 +691,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } } substream->group = &substream->self_group; +#ifdef CONFIG_AUDIO_QGKI + spin_lock_init(&substream->runtime_lock); +#endif snd_pcm_group_init(&substream->self_group); list_add_tail(&substream->link_list, &substream->self_group.substreams); atomic_set(&substream->mmap_count, 0); @@ -979,9 +982,15 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, void snd_pcm_detach_substream(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; +#ifdef CONFIG_AUDIO_QGKI + unsigned long flags = 0; +#endif if (PCM_RUNTIME_CHECK(substream)) return; +#ifdef CONFIG_AUDIO_QGKI + spin_lock_irqsave(&substream->runtime_lock, flags); +#endif runtime = substream->runtime; if (runtime->private_free != NULL) runtime->private_free(runtime); @@ -1000,6 +1009,9 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) put_pid(substream->pid); substream->pid = NULL; substream->pstr->substream_opened--; +#ifdef CONFIG_AUDIO_QGKI + spin_unlock_irqrestore(&substream->runtime_lock, flags); +#endif } static ssize_t show_pcm_class(struct device *dev, diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index 7928bda235c1..f420b501852b 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c @@ -52,9 +52,23 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) { struct snd_pcm_substream *substream; +#ifdef CONFIG_AUDIO_QGKI + unsigned long ret = 0, flags = 0; +#endif substream = timer->private_data; +#ifdef CONFIG_AUDIO_QGKI + spin_lock_irqsave(&substream->runtime_lock, flags); + if (substream->runtime) + ret = substream->runtime->timer_resolution; + else + ret = 0; + spin_unlock_irqrestore(&substream->runtime_lock, flags); + + return ret; +#else return substream->runtime ? substream->runtime->timer_resolution : 0; +#endif } static int snd_pcm_timer_start(struct snd_timer * timer)