From: Greg Kroah-Hartman Date: Sun, 14 Feb 2016 20:49:21 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v4.4.2~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e8da09d64ddf8dd6ca171319dd7f9b74d76bae78;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: alsa-timer-code-cleanup.patch alsa-timer-fix-race-between-stop-and-interrupt.patch --- diff --git a/queue-3.10/alsa-timer-code-cleanup.patch b/queue-3.10/alsa-timer-code-cleanup.patch new file mode 100644 index 00000000000..63e087febad --- /dev/null +++ b/queue-3.10/alsa-timer-code-cleanup.patch @@ -0,0 +1,100 @@ +From c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 14 Jan 2016 17:01:46 +0100 +Subject: ALSA: timer: Code cleanup + +From: Takashi Iwai + +commit c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 upstream. + +This is a minor code cleanup without any functional changes: +- Kill keep_flag argument from _snd_timer_stop(), as all callers pass + only it false. +- Remove redundant NULL check in _snd_timer_stop(). + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 28 +++++++++++----------------- + 1 file changed, 11 insertions(+), 17 deletions(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -300,8 +300,7 @@ int snd_timer_open(struct snd_timer_inst + return 0; + } + +-static int _snd_timer_stop(struct snd_timer_instance *timeri, +- int keep_flag, int event); ++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event); + + /* + * close a timer instance +@@ -343,7 +342,7 @@ int snd_timer_close(struct snd_timer_ins + spin_unlock_irq(&timer->lock); + mutex_lock(®ister_mutex); + list_del(&timeri->open_list); +- if (timer && list_empty(&timer->open_list_head) && ++ if (list_empty(&timer->open_list_head) && + timer->hw.close) + timer->hw.close(timer); + /* remove slave links */ +@@ -483,8 +482,7 @@ int snd_timer_start(struct snd_timer_ins + return result; + } + +-static int _snd_timer_stop(struct snd_timer_instance * timeri, +- int keep_flag, int event) ++static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) + { + struct snd_timer *timer; + unsigned long flags; +@@ -493,13 +491,11 @@ static int _snd_timer_stop(struct snd_ti + return -ENXIO; + + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { +- if (!keep_flag) { +- spin_lock_irqsave(&slave_active_lock, flags); +- timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; +- list_del_init(&timeri->ack_list); +- list_del_init(&timeri->active_list); +- spin_unlock_irqrestore(&slave_active_lock, flags); +- } ++ spin_lock_irqsave(&slave_active_lock, flags); ++ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; ++ list_del_init(&timeri->ack_list); ++ list_del_init(&timeri->active_list); ++ spin_unlock_irqrestore(&slave_active_lock, flags); + goto __end; + } + timer = timeri->timer; +@@ -520,9 +516,7 @@ static int _snd_timer_stop(struct snd_ti + } + } + } +- if (!keep_flag) +- timeri->flags &= +- ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); ++ timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); + spin_unlock_irqrestore(&timer->lock, flags); + __end: + if (event != SNDRV_TIMER_EVENT_RESOLUTION) +@@ -541,7 +535,7 @@ int snd_timer_stop(struct snd_timer_inst + unsigned long flags; + int err; + +- err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP); ++ err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP); + if (err < 0) + return err; + timer = timeri->timer; +@@ -585,7 +579,7 @@ int snd_timer_continue(struct snd_timer_ + */ + int snd_timer_pause(struct snd_timer_instance * timeri) + { +- return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE); ++ return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE); + } + + /* diff --git a/queue-3.10/alsa-timer-fix-leftover-link-at-closing.patch b/queue-3.10/alsa-timer-fix-leftover-link-at-closing.patch index 0f26bafee1c..fbfdd3375af 100644 --- a/queue-3.10/alsa-timer-fix-leftover-link-at-closing.patch +++ b/queue-3.10/alsa-timer-fix-leftover-link-at-closing.patch @@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/sound/core/timer.c +++ b/sound/core/timer.c -@@ -702,8 +702,8 @@ void snd_timer_interrupt(struct snd_time +@@ -696,8 +696,8 @@ void snd_timer_interrupt(struct snd_time ti->cticks = ti->ticks; } else { ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; diff --git a/queue-3.10/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch b/queue-3.10/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch index 81e6cc2d5f6..8d740762bad 100644 --- a/queue-3.10/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch +++ b/queue-3.10/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch @@ -30,7 +30,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/sound/core/timer.c +++ b/sound/core/timer.c -@@ -444,6 +444,10 @@ static int snd_timer_start_slave(struct +@@ -443,6 +443,10 @@ static int snd_timer_start_slave(struct unsigned long flags; spin_lock_irqsave(&slave_active_lock, flags); @@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; if (timeri->master && timeri->timer) { spin_lock(&timeri->timer->lock); -@@ -468,18 +472,26 @@ int snd_timer_start(struct snd_timer_ins +@@ -467,18 +471,26 @@ int snd_timer_start(struct snd_timer_ins return -EINVAL; if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { result = snd_timer_start_slave(timeri); @@ -70,18 +70,18 @@ Signed-off-by: Greg Kroah-Hartman return result; } -@@ -495,6 +507,10 @@ static int _snd_timer_stop(struct snd_ti +@@ -492,6 +504,10 @@ static int _snd_timer_stop(struct snd_ti + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - if (!keep_flag) { - spin_lock_irqsave(&slave_active_lock, flags); -+ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { -+ spin_unlock_irqrestore(&slave_active_lock, flags); -+ return -EBUSY; -+ } - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->ack_list); - list_del_init(&timeri->active_list); -@@ -506,6 +522,11 @@ static int _snd_timer_stop(struct snd_ti + spin_lock_irqsave(&slave_active_lock, flags); ++ if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { ++ spin_unlock_irqrestore(&slave_active_lock, flags); ++ return -EBUSY; ++ } + timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); +@@ -502,6 +518,11 @@ static int _snd_timer_stop(struct snd_ti if (!timer) return -EINVAL; spin_lock_irqsave(&timer->lock, flags); @@ -93,7 +93,7 @@ Signed-off-by: Greg Kroah-Hartman list_del_init(&timeri->ack_list); list_del_init(&timeri->active_list); if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && -@@ -571,10 +592,15 @@ int snd_timer_continue(struct snd_timer_ +@@ -565,10 +586,15 @@ int snd_timer_continue(struct snd_timer_ if (! timer) return -EINVAL; spin_lock_irqsave(&timer->lock, flags); diff --git a/queue-3.10/alsa-timer-fix-race-between-stop-and-interrupt.patch b/queue-3.10/alsa-timer-fix-race-between-stop-and-interrupt.patch new file mode 100644 index 00000000000..e554aa1f3ba --- /dev/null +++ b/queue-3.10/alsa-timer-fix-race-between-stop-and-interrupt.patch @@ -0,0 +1,43 @@ +From ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 9 Feb 2016 12:02:32 +0100 +Subject: ALSA: timer: Fix race between stop and interrupt + +From: Takashi Iwai + +commit ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 upstream. + +A slave timer element also unlinks at snd_timer_stop() but it takes +only slave_active_lock. When a slave is assigned to a master, +however, this may become a race against the master's interrupt +handling, eventually resulting in a list corruption. The actual bug +could be seen with a syzkaller fuzzer test case in BugLink below. + +As a fix, we need to take timeri->timer->lock when timer isn't NULL, +i.e. assigned to a master, while the assignment to a master itself is +protected by slave_active_lock. + +BugLink: http://lkml.kernel.org/r/CACT4Y+Y_Bm+7epAb=8Wi=AaWd+DYS7qawX52qxdCfOfY49vozQ@mail.gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -508,9 +508,13 @@ static int _snd_timer_stop(struct snd_ti + spin_unlock_irqrestore(&slave_active_lock, flags); + return -EBUSY; + } ++ if (timeri->timer) ++ spin_lock(&timeri->timer->lock); + timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); ++ if (timeri->timer) ++ spin_unlock(&timeri->timer->lock); + spin_unlock_irqrestore(&slave_active_lock, flags); + goto __end; + } diff --git a/queue-3.10/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch b/queue-3.10/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch index 7625ebb51fe..384e8293370 100644 --- a/queue-3.10/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch +++ b/queue-3.10/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch @@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/sound/core/timer.c +++ b/sound/core/timer.c -@@ -415,7 +415,7 @@ static void snd_timer_notify1(struct snd +@@ -414,7 +414,7 @@ static void snd_timer_notify1(struct snd spin_lock_irqsave(&timer->lock, flags); list_for_each_entry(ts, &ti->slave_active_head, active_list) if (ts->ccallback) diff --git a/queue-3.10/series b/queue-3.10/series index 6636b5c87f3..3a153362567 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -35,11 +35,13 @@ asoc-dpcm-fix-the-be-state-on-hw_free.patch alsa-seq-fix-yet-another-races-among-alsa-timer-accesses.patch alsa-seq-fix-race-at-closing-in-virmidi-driver.patch alsa-seq-fix-lockdep-warnings-due-to-double-mutex-locks.patch +alsa-timer-code-cleanup.patch alsa-timer-fix-leftover-link-at-closing.patch alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch alsa-hda-fix-speaker-output-from-vaio-aio-machines.patch alsa-dummy-implement-timer-backend-switching-more-safely.patch +alsa-timer-fix-race-between-stop-and-interrupt.patch saa7134-alsa-only-frees-registered-sound-cards.patch usb-ti_usb_3410_502-fix-id-table-size.patch usb-serial-visor-fix-crash-on-detecting-device-without-write_urbs.patch