]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 Aug 2017 18:33:14 +0000 (11:33 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 Aug 2017 18:33:14 +0000 (11:33 -0700)
added patches:
alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch
alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch
alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch

queue-4.4/alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch [new file with mode: 0644]
queue-4.4/alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch [new file with mode: 0644]
queue-4.4/alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch b/queue-4.4/alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch
new file mode 100644 (file)
index 0000000..c02ee25
--- /dev/null
@@ -0,0 +1,126 @@
+From 7e1d90f60a0d501c8503e636942ca704a454d910 Mon Sep 17 00:00:00 2001
+From: Daniel Mentz <danielmentz@google.com>
+Date: Mon, 14 Aug 2017 14:46:01 -0700
+Subject: ALSA: seq: 2nd attempt at fixing race creating a queue
+
+From: Daniel Mentz <danielmentz@google.com>
+
+commit 7e1d90f60a0d501c8503e636942ca704a454d910 upstream.
+
+commit 4842e98f26dd80be3623c4714a244ba52ea096a8 ("ALSA: seq: Fix race at
+creating a queue") attempted to fix a race reported by syzkaller. That
+fix has been described as follows:
+
+"
+When a sequencer queue is created in snd_seq_queue_alloc(),it adds the
+new queue element to the public list before referencing it.  Thus the
+queue might be deleted before the call of snd_seq_queue_use(), and it
+results in the use-after-free error, as spotted by syzkaller.
+
+The fix is to reference the queue object at the right time.
+"
+
+Even with that fix in place, syzkaller reported a use-after-free error.
+It specifically pointed to the last instruction "return q->queue" in
+snd_seq_queue_alloc(). The pointer q is being used after kfree() has
+been called on it.
+
+It turned out that there is still a small window where a race can
+happen. The window opens at
+snd_seq_ioctl_create_queue()->snd_seq_queue_alloc()->queue_list_add()
+and closes at
+snd_seq_ioctl_create_queue()->queueptr()->snd_use_lock_use(). Between
+these two calls, a different thread could delete the queue and possibly
+re-create a different queue in the same location in queue_list.
+
+This change prevents this situation by calling snd_use_lock_use() from
+snd_seq_queue_alloc() prior to calling queue_list_add(). It is then the
+caller's responsibility to call snd_use_lock_free(&q->use_lock).
+
+Fixes: 4842e98f26dd ("ALSA: seq: Fix race at creating a queue")
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Daniel Mentz <danielmentz@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/seq_clientmgr.c |    9 ++++-----
+ sound/core/seq/seq_queue.c     |   14 +++++++++-----
+ sound/core/seq/seq_queue.h     |    2 +-
+ 3 files changed, 14 insertions(+), 11 deletions(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -1530,15 +1530,14 @@ static int snd_seq_ioctl_create_queue(st
+                                     void __user *arg)
+ {
+       struct snd_seq_queue_info info;
+-      int result;
+       struct snd_seq_queue *q;
+       if (copy_from_user(&info, arg, sizeof(info)))
+               return -EFAULT;
+-      result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
+-      if (result < 0)
+-              return result;
++      q = snd_seq_queue_alloc(client->number, info->locked, info->flags);
++      if (IS_ERR(q))
++              return PTR_ERR(q);
+       q = queueptr(result);
+       if (q == NULL)
+@@ -1552,7 +1551,7 @@ static int snd_seq_ioctl_create_queue(st
+       if (! info.name[0])
+               snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue);
+       strlcpy(q->name, info.name, sizeof(q->name));
+-      queuefree(q);
++      snd_use_lock_free(&q->use_lock);
+       if (copy_to_user(arg, &info, sizeof(info)))
+               return -EFAULT;
+--- a/sound/core/seq/seq_queue.c
++++ b/sound/core/seq/seq_queue.c
+@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void)
+ static void queue_use(struct snd_seq_queue *queue, int client, int use);
+ /* allocate a new queue -
+- * return queue index value or negative value for error
++ * return pointer to new queue or ERR_PTR(-errno) for error
++ * The new queue's use_lock is set to 1. It is the caller's responsibility to
++ * call snd_use_lock_free(&q->use_lock).
+  */
+-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
+ {
+       struct snd_seq_queue *q;
+       q = queue_new(client, locked);
+       if (q == NULL)
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       q->info_flags = info_flags;
+       queue_use(q, client, 1);
++      snd_use_lock_use(&q->use_lock);
+       if (queue_list_add(q) < 0) {
++              snd_use_lock_free(&q->use_lock);
+               queue_delete(q);
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+       }
+-      return q->queue;
++      return q;
+ }
+ /* delete a queue - queue must be owned by the client */
+--- a/sound/core/seq/seq_queue.h
++++ b/sound/core/seq/seq_queue.h
+@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void);
+ /* create new queue (constructor) */
+-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags);
+ /* delete queue (destructor) */
+ int snd_seq_queue_delete(int client, int queueid);
diff --git a/queue-4.4/alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch b/queue-4.4/alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch
new file mode 100644 (file)
index 0000000..3e8b5fd
--- /dev/null
@@ -0,0 +1,65 @@
+From 0f174b3525a43bd51f9397394763925e0ebe7bc7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 16 Aug 2017 14:18:37 +0200
+Subject: ALSA: usb-audio: Add mute TLV for playback volumes on C-Media devices
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 0f174b3525a43bd51f9397394763925e0ebe7bc7 upstream.
+
+C-Media devices (at least some models) mute the playback stream when
+volumes are set to the minimum value.  But this isn't informed via TLV
+and the user-space, typically PulseAudio, gets confused as if it's
+still played in a low volume.
+
+This patch adds the new flag, min_mute, to struct usb_mixer_elem_info
+for indicating that the mixer element is with the minimum-mute volume.
+This flag is set for known C-Media devices in
+snd_usb_mixer_fu_apply_quirk() in turn.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196669
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/mixer.c        |    2 ++
+ sound/usb/mixer.h        |    1 +
+ sound/usb/mixer_quirks.c |    6 ++++++
+ 3 files changed, 9 insertions(+)
+
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -541,6 +541,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kco
+       if (size < sizeof(scale))
+               return -ENOMEM;
++      if (cval->min_mute)
++              scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
+       scale[2] = cval->dBmin;
+       scale[3] = cval->dBmax;
+       if (copy_to_user(_tlv, scale, sizeof(scale)))
+--- a/sound/usb/mixer.h
++++ b/sound/usb/mixer.h
+@@ -64,6 +64,7 @@ struct usb_mixer_elem_info {
+       int cached;
+       int cache_val[MAX_CHANNELS];
+       u8 initialized;
++      u8 min_mute;
+       void *private_data;
+ };
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct
+               if (unitid == 7 && cval->control == UAC_FU_VOLUME)
+                       snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
+               break;
++      /* lowest playback value is muted on C-Media devices */
++      case USB_ID(0x0d8c, 0x000c):
++      case USB_ID(0x0d8c, 0x0014):
++              if (strstr(kctl->id.name, "Playback"))
++                      cval->min_mute = 1;
++              break;
+       }
+ }
diff --git a/queue-4.4/alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch b/queue-4.4/alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch
new file mode 100644 (file)
index 0000000..6d62db8
--- /dev/null
@@ -0,0 +1,35 @@
+From a8e800fe0f68bc28ce309914f47e432742b865ed Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 14 Aug 2017 14:35:50 +0200
+Subject: ALSA: usb-audio: Apply sample rate quirk to Sennheiser headset
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit a8e800fe0f68bc28ce309914f47e432742b865ed upstream.
+
+A Senheisser headset requires the typical sample-rate quirk for
+avoiding spurious errors from inquiring the current sample rate like:
+ usb 1-1: 2:1: cannot get freq at ep 0x4
+ usb 1-1: 3:1: cannot get freq at ep 0x83
+
+The USB ID 1395:740a has to be added to the entries in
+snd_usb_get_sample_rate_quirk().
+
+Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1052580
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/quirks.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1143,6 +1143,7 @@ bool snd_usb_get_sample_rate_quirk(struc
+       case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
+       case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
+       case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
++      case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
+       case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
+       case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
+       case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
index 1da3b896e46ede111be8c0d97a2254aa09a9706a..a12dd9572f6ff501befe0b7fa82040823676af55 100644 (file)
@@ -4,3 +4,6 @@ parisc-pci-memory-bar-assignment-fails-with-64bit-kernels-on-dino-cujo.patch
 crypto-x86-sha1-fix-reads-beyond-the-number-of-blocks-passed.patch
 input-elan_i2c-add-elan0608-to-the-acpi-table.patch
 input-elan_i2c-add-antoher-lenovo-acpi-id-for-upcoming-lenovo-nb.patch
+alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch
+alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch
+alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch