]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 14 Feb 2016 20:50:04 +0000 (12:50 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 14 Feb 2016 20:50:04 +0000 (12:50 -0800)
added patches:
alsa-timer-code-cleanup.patch
alsa-timer-fix-race-between-stop-and-interrupt.patch

queue-4.4/alsa-timer-code-cleanup.patch [new file with mode: 0644]
queue-4.4/alsa-timer-fix-leftover-link-at-closing.patch
queue-4.4/alsa-timer-fix-link-corruption-due-to-double-start-or-stop.patch
queue-4.4/alsa-timer-fix-race-at-concurrent-reads.patch
queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch [new file with mode: 0644]
queue-4.4/alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch
queue-4.4/series

diff --git a/queue-4.4/alsa-timer-code-cleanup.patch b/queue-4.4/alsa-timer-code-cleanup.patch
new file mode 100644 (file)
index 0000000..7d98317
--- /dev/null
@@ -0,0 +1,100 @@
+From c3b1681375dc6e71d89a3ae00cc3ce9e775a8917 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 14 Jan 2016 17:01:46 +0100
+Subject: ALSA: timer: Code cleanup
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer.c |   28 +++++++++++-----------------
+ 1 file changed, 11 insertions(+), 17 deletions(-)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -305,8 +305,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
+@@ -348,7 +347,7 @@ int snd_timer_close(struct snd_timer_ins
+               spin_unlock_irq(&timer->lock);
+               mutex_lock(&register_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 */
+@@ -493,8 +492,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;
+@@ -503,13 +501,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;
+@@ -534,9 +530,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)
+@@ -555,7 +549,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;
+@@ -601,7 +595,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);
+ }
+ /*
index 832847d1e796b0250c4b544501e348e2b4dafcd8..c465eaf846c4984622801aae3517ecd62224a0e6 100644 (file)
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 --- a/sound/core/timer.c
 +++ b/sound/core/timer.c
-@@ -724,8 +724,8 @@ void snd_timer_interrupt(struct snd_time
+@@ -718,8 +718,8 @@ void snd_timer_interrupt(struct snd_time
                        ti->cticks = ti->ticks;
                } else {
                        ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
index 93352de895e3815d1b8e50abf681dd8485ff01c3..5d35ee116c428da4e378253540d19ab341b4b2e5 100644 (file)
@@ -30,7 +30,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 --- a/sound/core/timer.c
 +++ b/sound/core/timer.c
-@@ -452,6 +452,10 @@ static int snd_timer_start_slave(struct
+@@ -451,6 +451,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 <gregkh@linuxfoundation.org>
        timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
        if (timeri->master && timeri->timer) {
                spin_lock(&timeri->timer->lock);
-@@ -476,7 +480,8 @@ int snd_timer_start(struct snd_timer_ins
+@@ -475,7 +479,8 @@ int snd_timer_start(struct snd_timer_ins
                return -EINVAL;
        if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
                result = snd_timer_start_slave(timeri);
@@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
                return result;
        }
        timer = timeri->timer;
-@@ -485,11 +490,18 @@ int snd_timer_start(struct snd_timer_ins
+@@ -484,11 +489,18 @@ int snd_timer_start(struct snd_timer_ins
        if (timer->card && timer->card->shutdown)
                return -ENODEV;
        spin_lock_irqsave(&timer->lock, flags);
@@ -71,18 +71,18 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
        return result;
  }
  
-@@ -505,6 +517,10 @@ static int _snd_timer_stop(struct snd_ti
+@@ -502,6 +514,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);
-@@ -516,6 +532,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);
+@@ -512,6 +528,11 @@ static int _snd_timer_stop(struct snd_ti
        if (!timer)
                return -EINVAL;
        spin_lock_irqsave(&timer->lock, flags);
@@ -94,7 +94,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
        list_del_init(&timeri->ack_list);
        list_del_init(&timeri->active_list);
        if (timer->card && timer->card->shutdown) {
-@@ -587,10 +608,15 @@ int snd_timer_continue(struct snd_timer_
+@@ -581,10 +602,15 @@ int snd_timer_continue(struct snd_timer_
        if (timer->card && timer->card->shutdown)
                return -ENODEV;
        spin_lock_irqsave(&timer->lock, flags);
index b6085d3ab44f1400f3c46edf7e25a342523434de..0e9f1b83e4bdb60d071e6ecc9388b78b72a8fb3b 100644 (file)
@@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 --- a/sound/core/timer.c
 +++ b/sound/core/timer.c
-@@ -1926,6 +1926,7 @@ static ssize_t snd_timer_user_read(struc
+@@ -1920,6 +1920,7 @@ static ssize_t snd_timer_user_read(struc
  {
        struct snd_timer_user *tu;
        long result = 0, unit;
@@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
        int err = 0;
  
        tu = file->private_data;
-@@ -1937,7 +1938,7 @@ static ssize_t snd_timer_user_read(struc
+@@ -1931,7 +1932,7 @@ static ssize_t snd_timer_user_read(struc
  
                        if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
                                err = -EAGAIN;
@@ -38,7 +38,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
                        }
  
                        set_current_state(TASK_INTERRUPTIBLE);
-@@ -1952,42 +1953,37 @@ static ssize_t snd_timer_user_read(struc
+@@ -1946,42 +1947,37 @@ static ssize_t snd_timer_user_read(struc
  
                        if (tu->disconnected) {
                                err = -ENODEV;
diff --git a/queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch b/queue-4.4/alsa-timer-fix-race-between-stop-and-interrupt.patch
new file mode 100644 (file)
index 0000000..29f0fbd
--- /dev/null
@@ -0,0 +1,43 @@
+From ed8b1d6d2c741ab26d60d499d7fbb7ac801f0f51 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 9 Feb 2016 12:02:32 +0100
+Subject: ALSA: timer: Fix race between stop and interrupt
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/timer.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -518,9 +518,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;
+       }
index 3321fcacf040abdf64d501866af7b18d3b73615a..4905302134604cf0478b9081e87f0e72e0263a39 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 --- a/sound/core/timer.c
 +++ b/sound/core/timer.c
-@@ -423,7 +423,7 @@ static void snd_timer_notify1(struct snd
+@@ -422,7 +422,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)
index ad33079d939b5d115b143461e1ad29d288398cbc..329b8d1e4f1be20cca47cc0fdae32e6d27cf3e65 100644 (file)
@@ -20,6 +20,7 @@ parisc-protect-huge-page-pte-changes-with-spinlocks.patch
 parisc-fix-__arch_si_preamble_size.patch
 media-i2c-don-t-export-ir-kbd-i2c-module-alias.patch
 md-raid-only-permit-hot-add-of-compatible-integrity-profiles.patch
+hrtimer-handle-remaining-time-proper-for-time_low_res.patch
 alsa-usb-audio-fix-teac-ud-501-ud-503-nt-503-usb-delay.patch
 alsa-usb-audio-add-quirk-for-microsoft-lifecam-hd-6000.patch
 alsa-usb-audio-fix-oppo-ha-1-vendor-id.patch
@@ -43,11 +44,12 @@ 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-race-at-concurrent-reads.patch
 alsa-timer-fix-wrong-instance-passed-to-slave-callbacks.patch
-hrtimer-handle-remaining-time-proper-for-time_low_res.patch
+alsa-timer-fix-race-between-stop-and-interrupt.patch
 alsa-hda-add-fixup-for-mac-mini-7-1-model.patch
 alsa-hda-fix-static-checker-warning-in-patch_hdmi.c.patch
 revert-alsa-hda-fix-noise-on-gigabyte-z170x-mobo.patch