| From bc63880ce258c29784efa162a371734d549ae645 Mon Sep 17 00:00:00 2001 |
| From: Takashi Iwai <tiwai@suse.de> |
| Date: Tue, 28 Feb 2017 22:15:51 +0100 |
| Subject: [PATCH] ALSA: seq: Fix link corruption by event error handling |
| |
| commit f3ac9f737603da80c2da3e84b89e74429836bb6d upstream. |
| |
| The sequencer FIFO management has a bug that may lead to a corruption |
| (shortage) of the cell linked list. When a sequencer client faces an |
| error at the event delivery, it tries to put back the dequeued cell. |
| When the first queue was put back, this forgot the tail pointer |
| tracking, and the link will be screwed up. |
| |
| Although there is no memory corruption, the sequencer client may stall |
| forever at exit while flushing the pending FIFO cells in |
| snd_seq_pool_done(), as spotted by syzkaller. |
| |
| This patch addresses the missing tail pointer tracking at |
| snd_seq_fifo_cell_putback(). Also the patch makes sure to clear the |
| cell->enxt pointer at snd_seq_fifo_event_in() for avoiding a similar |
| mess-up of the FIFO linked list. |
| |
| 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 1d5acbe0c08b..86240d02b530 100644 |
| --- a/sound/core/seq/seq_fifo.c |
| +++ b/sound/core/seq/seq_fifo.c |
| @@ -135,6 +135,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, |
| f->tail = cell; |
| if (f->head == NULL) |
| f->head = cell; |
| + cell->next = NULL; |
| f->cells++; |
| spin_unlock_irqrestore(&f->lock, flags); |
| |
| @@ -214,6 +215,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, |
| spin_lock_irqsave(&f->lock, flags); |
| cell->next = f->head; |
| f->head = cell; |
| + if (!f->tail) |
| + f->tail = cell; |
| f->cells++; |
| spin_unlock_irqrestore(&f->lock, flags); |
| } |
| -- |
| 2.12.0 |
| |