| From 270a8a42abff5ddbdf34ac202050ac9fad8deefc Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Fri, 24 Mar 2017 17:07:57 +0100 |
| Subject: [PATCH] ALSA: seq: Fix race during FIFO resize |
| |
| commit 2d7d54002e396c180db0c800c1046f0a3c471597 upstream. |
| |
| When a new event is queued while processing to resize the FIFO in |
| snd_seq_fifo_clear(), it may lead to a use-after-free, as the old pool |
| that is being queued gets removed. For avoiding this race, we need to |
| close the pool to be deleted and sync its usage before actually |
| deleting it. |
| |
| The issue was spotted by syzkaller. |
| |
| Reported-by: Dmitry Vyukov <dvyukov@google.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c |
| index 3f4efcb85df5..3490d21ab9e7 100644 |
| --- a/sound/core/seq/seq_fifo.c |
| +++ b/sound/core/seq/seq_fifo.c |
| @@ -265,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) |
| /* NOTE: overflow flag is not cleared */ |
| spin_unlock_irqrestore(&f->lock, flags); |
| |
| + /* close the old pool and wait until all users are gone */ |
| + snd_seq_pool_mark_closing(oldpool); |
| + snd_use_lock_sync(&f->use_lock); |
| + |
| /* release cells in old pool */ |
| for (cell = oldhead; cell; cell = next) { |
| next = cell->next; |
| -- |
| 2.12.0 |
| |