From ea63e134a8528aef9e04d7c72fb3a7821069f89d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 18 May 2020 15:07:16 +0200 Subject: [PATCH] 4.4-stable patches added patches: alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch --- ...imit-int-mic-boost-for-thinkpad-t530.patch | 66 +++++++++ ...fer-resize-under-concurrent-accesses.patch | 131 ++++++++++++++++++ queue-4.4/series | 2 + 3 files changed, 199 insertions(+) create mode 100644 queue-4.4/alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch create mode 100644 queue-4.4/alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch diff --git a/queue-4.4/alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch b/queue-4.4/alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch new file mode 100644 index 00000000000..d4259e361bb --- /dev/null +++ b/queue-4.4/alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch @@ -0,0 +1,66 @@ +From b590b38ca305d6d7902ec7c4f7e273e0069f3bcc Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 14 May 2020 18:05:33 +0200 +Subject: ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 + +From: Takashi Iwai + +commit b590b38ca305d6d7902ec7c4f7e273e0069f3bcc upstream. + +Lenovo Thinkpad T530 seems to have a sensitive internal mic capture +that needs to limit the mic boost like a few other Thinkpad models. +Although we may change the quirk for ALC269_FIXUP_LENOVO_DOCK, this +hits way too many other laptop models, so let's add a new fixup model +that limits the internal mic boost on top of the existing quirk and +apply to only T530. + +BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1171293 +Cc: +Link: https://lore.kernel.org/r/20200514160533.10337-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4840,6 +4840,7 @@ enum { + ALC269_FIXUP_HP_LINE1_MIC1_LED, + ALC269_FIXUP_INV_DMIC, + ALC269_FIXUP_LENOVO_DOCK, ++ ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, + ALC269_FIXUP_NO_SHUTUP, + ALC286_FIXUP_SONY_MIC_NO_PRESENCE, + ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, +@@ -5106,6 +5107,12 @@ static const struct hda_fixup alc269_fix + .chained = true, + .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT + }, ++ [ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc269_fixup_limit_int_mic_boost, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_LENOVO_DOCK, ++ }, + [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_pincfg_no_hp_to_lineout, +@@ -5760,7 +5767,7 @@ static const struct snd_pci_quirk alc269 + SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), +- SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), ++ SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST), + SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), +@@ -5870,6 +5877,7 @@ static const struct hda_model_fixup alc2 + {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"}, + {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"}, + {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, ++ {.id = ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST, .name = "lenovo-dock-limit-boost"}, + {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, + {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"}, + {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, diff --git a/queue-4.4/alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch b/queue-4.4/alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch new file mode 100644 index 00000000000..08e087ceb0e --- /dev/null +++ b/queue-4.4/alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch @@ -0,0 +1,131 @@ +From c1f6e3c818dd734c30f6a7eeebf232ba2cf3181d Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 7 May 2020 13:44:56 +0200 +Subject: ALSA: rawmidi: Fix racy buffer resize under concurrent accesses + +From: Takashi Iwai + +commit c1f6e3c818dd734c30f6a7eeebf232ba2cf3181d upstream. + +The rawmidi core allows user to resize the runtime buffer via ioctl, +and this may lead to UAF when performed during concurrent reads or +writes: the read/write functions unlock the runtime lock temporarily +during copying form/to user-space, and that's the race window. + +This patch fixes the hole by introducing a reference counter for the +runtime buffer read/write access and returns -EBUSY error when the +resize is performed concurrently against read/write. + +Note that the ref count field is a simple integer instead of +refcount_t here, since the all contexts accessing the buffer is +basically protected with a spinlock, hence we need no expensive atomic +ops. Also, note that this busy check is needed only against read / +write functions, and not in receive/transmit callbacks; the race can +happen only at the spinlock hole mentioned in the above, while the +whole function is protected for receive / transmit callbacks. + +Reported-by: butt3rflyh4ck +Cc: +Link: https://lore.kernel.org/r/CAFcO6XMWpUVK_yzzCpp8_XP7+=oUpQvuBeCbMffEDkpe8jWrfg@mail.gmail.com +Link: https://lore.kernel.org/r/s5heerw3r5z.wl-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + include/sound/rawmidi.h | 1 + + sound/core/rawmidi.c | 31 +++++++++++++++++++++++++++---- + 2 files changed, 28 insertions(+), 4 deletions(-) + +--- a/include/sound/rawmidi.h ++++ b/include/sound/rawmidi.h +@@ -76,6 +76,7 @@ struct snd_rawmidi_runtime { + size_t avail_min; /* min avail for wakeup */ + size_t avail; /* max used buffer for wakeup */ + size_t xruns; /* over/underruns counter */ ++ int buffer_ref; /* buffer reference count */ + /* misc */ + spinlock_t lock; + wait_queue_head_t sleep; +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -108,6 +108,17 @@ static void snd_rawmidi_input_event_work + runtime->event(runtime->substream); + } + ++/* buffer refcount management: call with runtime->lock held */ ++static inline void snd_rawmidi_buffer_ref(struct snd_rawmidi_runtime *runtime) ++{ ++ runtime->buffer_ref++; ++} ++ ++static inline void snd_rawmidi_buffer_unref(struct snd_rawmidi_runtime *runtime) ++{ ++ runtime->buffer_ref--; ++} ++ + static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) + { + struct snd_rawmidi_runtime *runtime; +@@ -654,6 +665,11 @@ int snd_rawmidi_output_params(struct snd + if (!newbuf) + return -ENOMEM; + spin_lock_irq(&runtime->lock); ++ if (runtime->buffer_ref) { ++ spin_unlock_irq(&runtime->lock); ++ kvfree(newbuf); ++ return -EBUSY; ++ } + oldbuf = runtime->buffer; + runtime->buffer = newbuf; + runtime->buffer_size = params->buffer_size; +@@ -962,8 +978,10 @@ static long snd_rawmidi_kernel_read1(str + long result = 0, count1; + struct snd_rawmidi_runtime *runtime = substream->runtime; + unsigned long appl_ptr; ++ int err = 0; + + spin_lock_irqsave(&runtime->lock, flags); ++ snd_rawmidi_buffer_ref(runtime); + while (count > 0 && runtime->avail) { + count1 = runtime->buffer_size - runtime->appl_ptr; + if (count1 > count) +@@ -982,16 +1000,19 @@ static long snd_rawmidi_kernel_read1(str + if (userbuf) { + spin_unlock_irqrestore(&runtime->lock, flags); + if (copy_to_user(userbuf + result, +- runtime->buffer + appl_ptr, count1)) { +- return result > 0 ? result : -EFAULT; +- } ++ runtime->buffer + appl_ptr, count1)) ++ err = -EFAULT; + spin_lock_irqsave(&runtime->lock, flags); ++ if (err) ++ goto out; + } + result += count1; + count -= count1; + } ++ out: ++ snd_rawmidi_buffer_unref(runtime); + spin_unlock_irqrestore(&runtime->lock, flags); +- return result; ++ return result > 0 ? result : err; + } + + long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream, +@@ -1262,6 +1283,7 @@ static long snd_rawmidi_kernel_write1(st + return -EAGAIN; + } + } ++ snd_rawmidi_buffer_ref(runtime); + while (count > 0 && runtime->avail > 0) { + count1 = runtime->buffer_size - runtime->appl_ptr; + if (count1 > count) +@@ -1293,6 +1315,7 @@ static long snd_rawmidi_kernel_write1(st + } + __end: + count1 = runtime->avail < runtime->buffer_size; ++ snd_rawmidi_buffer_unref(runtime); + spin_unlock_irqrestore(&runtime->lock, flags); + if (count1) + snd_rawmidi_output_trigger(substream, 1); diff --git a/queue-4.4/series b/queue-4.4/series index 0cca6da181a..3f737e3c005 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -69,3 +69,5 @@ gcc-10-avoid-shadowing-standard-library-free-in-crypto.patch net-fix-a-potential-recursive-netdev_feat_change.patch net-ipv4-really-enforce-backoff-for-redirects.patch netlabel-cope-with-null-catmap.patch +alsa-hda-realtek-limit-int-mic-boost-for-thinkpad-t530.patch +alsa-rawmidi-fix-racy-buffer-resize-under-concurrent-accesses.patch -- 2.47.3