--- /dev/null
+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);
--- /dev/null
+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;
+ }
+ }
+
--- /dev/null
+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 */