| From: Takashi Iwai <tiwai@suse.de> |
| Date: Thu, 14 Apr 2016 18:02:37 +0200 |
| Subject: ALSA: pcm : Call kill_fasync() in stream lock |
| |
| commit 3aa02cb664c5fb1042958c8d1aa8c35055a2ebc4 upstream. |
| |
| Currently kill_fasync() is called outside the stream lock in |
| snd_pcm_period_elapsed(). This is potentially racy, since the stream |
| may get released even during the irq handler is running. Although |
| snd_pcm_release_substream() calls snd_pcm_drop(), this doesn't |
| guarantee that the irq handler finishes, thus the kill_fasync() call |
| outside the stream spin lock may be invoked after the substream is |
| detached, as recently reported by KASAN. |
| |
| As a quick workaround, move kill_fasync() call inside the stream |
| lock. The fasync is rarely used interface, so this shouldn't have a |
| big impact from the performance POV. |
| |
| Ideally, we should implement some sync mechanism for the proper finish |
| of stream and irq handler. But this oneliner should suffice for most |
| cases, so far. |
| |
| Reported-by: Baozeng Ding <sploving1@gmail.com> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| sound/core/pcm_lib.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/sound/core/pcm_lib.c |
| +++ b/sound/core/pcm_lib.c |
| @@ -1856,10 +1856,10 @@ void snd_pcm_period_elapsed(struct snd_p |
| if (substream->timer_running) |
| snd_timer_interrupt(substream->timer, 1); |
| _end: |
| - snd_pcm_stream_unlock_irqrestore(substream, flags); |
| if (runtime->transfer_ack_end) |
| runtime->transfer_ack_end(substream); |
| kill_fasync(&runtime->fasync, SIGIO, POLL_IN); |
| + snd_pcm_stream_unlock_irqrestore(substream, flags); |
| } |
| |
| EXPORT_SYMBOL(snd_pcm_period_elapsed); |