]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Nov 2021 18:30:25 +0000 (19:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Nov 2021 18:30:25 +0000 (19:30 +0100)
added patches:
alsa-hda-hdac_ext_stream-fix-potential-locking-issues.patch
alsa-hda-hdac_stream-fix-potential-locking-issue-in-snd_hdac_stream_assign.patch

queue-5.4/alsa-hda-hdac_ext_stream-fix-potential-locking-issues.patch [new file with mode: 0644]
queue-5.4/alsa-hda-hdac_stream-fix-potential-locking-issue-in-snd_hdac_stream_assign.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/alsa-hda-hdac_ext_stream-fix-potential-locking-issues.patch b/queue-5.4/alsa-hda-hdac_ext_stream-fix-potential-locking-issues.patch
new file mode 100644 (file)
index 0000000..175fb4e
--- /dev/null
@@ -0,0 +1,164 @@
+From 868ddfcef31ff93ea8961b2e81ea7fe12f6f144b Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Date: Fri, 24 Sep 2021 14:24:16 -0500
+Subject: ALSA: hda: hdac_ext_stream: fix potential locking issues
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+commit 868ddfcef31ff93ea8961b2e81ea7fe12f6f144b upstream.
+
+The code for hdac_ext_stream seems inherited from hdac_stream, and
+similar locking issues are present: the use of the bus->reg_lock
+spinlock is inconsistent, with only writes to specific fields being
+protected.
+
+Apply similar fix as in hdac_stream by protecting all accesses to
+'link_locked' and 'decoupled' fields, with a new helper
+snd_hdac_ext_stream_decouple_locked() added to simplify code
+changes.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210924192417.169243-4-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/sound/hdaudio_ext.h     |    2 +
+ sound/hda/ext/hdac_ext_stream.c |   46 ++++++++++++++++++++++++----------------
+ 2 files changed, 30 insertions(+), 18 deletions(-)
+
+--- a/include/sound/hdaudio_ext.h
++++ b/include/sound/hdaudio_ext.h
+@@ -88,6 +88,8 @@ struct hdac_ext_stream *snd_hdac_ext_str
+                                          struct snd_pcm_substream *substream,
+                                          int type);
+ void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
++void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
++                                struct hdac_ext_stream *azx_dev, bool decouple);
+ void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
+                               struct hdac_ext_stream *azx_dev, bool decouple);
+ void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
+--- a/sound/hda/ext/hdac_ext_stream.c
++++ b/sound/hda/ext/hdac_ext_stream.c
+@@ -106,20 +106,14 @@ void snd_hdac_stream_free_all(struct hda
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_stream_free_all);
+-/**
+- * snd_hdac_ext_stream_decouple - decouple the hdac stream
+- * @bus: HD-audio core bus
+- * @stream: HD-audio ext core stream object to initialize
+- * @decouple: flag to decouple
+- */
+-void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
+-                              struct hdac_ext_stream *stream, bool decouple)
++void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
++                                       struct hdac_ext_stream *stream,
++                                       bool decouple)
+ {
+       struct hdac_stream *hstream = &stream->hstream;
+       u32 val;
+       int mask = AZX_PPCTL_PROCEN(hstream->index);
+-      spin_lock_irq(&bus->reg_lock);
+       val = readw(bus->ppcap + AZX_REG_PP_PPCTL) & mask;
+       if (decouple && !val)
+@@ -128,6 +122,20 @@ void snd_hdac_ext_stream_decouple(struct
+               snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, 0);
+       stream->decoupled = decouple;
++}
++EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple_locked);
++
++/**
++ * snd_hdac_ext_stream_decouple - decouple the hdac stream
++ * @bus: HD-audio core bus
++ * @stream: HD-audio ext core stream object to initialize
++ * @decouple: flag to decouple
++ */
++void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
++                                struct hdac_ext_stream *stream, bool decouple)
++{
++      spin_lock_irq(&bus->reg_lock);
++      snd_hdac_ext_stream_decouple_locked(bus, stream, decouple);
+       spin_unlock_irq(&bus->reg_lock);
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple);
+@@ -252,6 +260,7 @@ hdac_ext_link_stream_assign(struct hdac_
+               return NULL;
+       }
++      spin_lock_irq(&bus->reg_lock);
+       list_for_each_entry(stream, &bus->stream_list, list) {
+               struct hdac_ext_stream *hstream = container_of(stream,
+                                               struct hdac_ext_stream,
+@@ -266,17 +275,16 @@ hdac_ext_link_stream_assign(struct hdac_
+               }
+               if (!hstream->link_locked) {
+-                      snd_hdac_ext_stream_decouple(bus, hstream, true);
++                      snd_hdac_ext_stream_decouple_locked(bus, hstream, true);
+                       res = hstream;
+                       break;
+               }
+       }
+       if (res) {
+-              spin_lock_irq(&bus->reg_lock);
+               res->link_locked = 1;
+               res->link_substream = substream;
+-              spin_unlock_irq(&bus->reg_lock);
+       }
++      spin_unlock_irq(&bus->reg_lock);
+       return res;
+ }
+@@ -292,6 +300,7 @@ hdac_ext_host_stream_assign(struct hdac_
+               return NULL;
+       }
++      spin_lock_irq(&bus->reg_lock);
+       list_for_each_entry(stream, &bus->stream_list, list) {
+               struct hdac_ext_stream *hstream = container_of(stream,
+                                               struct hdac_ext_stream,
+@@ -301,18 +310,17 @@ hdac_ext_host_stream_assign(struct hdac_
+               if (!stream->opened) {
+                       if (!hstream->decoupled)
+-                              snd_hdac_ext_stream_decouple(bus, hstream, true);
++                              snd_hdac_ext_stream_decouple_locked(bus, hstream, true);
+                       res = hstream;
+                       break;
+               }
+       }
+       if (res) {
+-              spin_lock_irq(&bus->reg_lock);
+               res->hstream.opened = 1;
+               res->hstream.running = 0;
+               res->hstream.substream = substream;
+-              spin_unlock_irq(&bus->reg_lock);
+       }
++      spin_unlock_irq(&bus->reg_lock);
+       return res;
+ }
+@@ -378,15 +386,17 @@ void snd_hdac_ext_stream_release(struct
+               break;
+       case HDAC_EXT_STREAM_TYPE_HOST:
++              spin_lock_irq(&bus->reg_lock);
+               if (stream->decoupled && !stream->link_locked)
+-                      snd_hdac_ext_stream_decouple(bus, stream, false);
++                      snd_hdac_ext_stream_decouple_locked(bus, stream, false);
++              spin_unlock_irq(&bus->reg_lock);
+               snd_hdac_stream_release(&stream->hstream);
+               break;
+       case HDAC_EXT_STREAM_TYPE_LINK:
+-              if (stream->decoupled && !stream->hstream.opened)
+-                      snd_hdac_ext_stream_decouple(bus, stream, false);
+               spin_lock_irq(&bus->reg_lock);
++              if (stream->decoupled && !stream->hstream.opened)
++                      snd_hdac_ext_stream_decouple_locked(bus, stream, false);
+               stream->link_locked = 0;
+               stream->link_substream = NULL;
+               spin_unlock_irq(&bus->reg_lock);
diff --git a/queue-5.4/alsa-hda-hdac_stream-fix-potential-locking-issue-in-snd_hdac_stream_assign.patch b/queue-5.4/alsa-hda-hdac_stream-fix-potential-locking-issue-in-snd_hdac_stream_assign.patch
new file mode 100644 (file)
index 0000000..75cd0ad
--- /dev/null
@@ -0,0 +1,50 @@
+From 1465d06a6d8580e73ae65f8590392df58c5ed2fd Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Date: Fri, 24 Sep 2021 14:24:14 -0500
+Subject: ALSA: hda: hdac_stream: fix potential locking issue in snd_hdac_stream_assign()
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+commit 1465d06a6d8580e73ae65f8590392df58c5ed2fd upstream.
+
+The fields 'opened', 'running', 'assigned_key' are all protected by a
+spinlock, but the spinlock is not taken when looking for a
+stream. This can result in a possible race between assign() and
+release().
+
+Fix by taking the spinlock before walking through the bus stream list.
+
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20210924192417.169243-2-pierre-louis.bossart@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Scott Bruce <smbruce@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/hdac_stream.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/hda/hdac_stream.c
++++ b/sound/hda/hdac_stream.c
+@@ -289,6 +289,7 @@ struct hdac_stream *snd_hdac_stream_assi
+       int key = (substream->pcm->device << 16) | (substream->number << 2) |
+               (substream->stream + 1);
++      spin_lock_irq(&bus->reg_lock);
+       list_for_each_entry(azx_dev, &bus->stream_list, list) {
+               if (azx_dev->direction != substream->stream)
+                       continue;
+@@ -302,13 +303,12 @@ struct hdac_stream *snd_hdac_stream_assi
+                       res = azx_dev;
+       }
+       if (res) {
+-              spin_lock_irq(&bus->reg_lock);
+               res->opened = 1;
+               res->running = 0;
+               res->assigned_key = key;
+               res->substream = substream;
+-              spin_unlock_irq(&bus->reg_lock);
+       }
++      spin_unlock_irq(&bus->reg_lock);
+       return res;
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_stream_assign);
index 53bc5997a91a0e061b8630e871f2ab806192b746..f79825ef7483deaf34edeea5d4583d659078a98f 100644 (file)
@@ -96,3 +96,5 @@ usb-max-3421-use-driver-data-instead-of-maintaining-a-list-of-bound-devices.patc
 ice-delete-always-true-check-of-pf-pointer.patch
 tlb-mmu_gather-add-tlb_flush_-_range-apis.patch
 hugetlbfs-flush-tlbs-correctly-after-huge_pmd_unshare.patch
+alsa-hda-hdac_ext_stream-fix-potential-locking-issues.patch
+alsa-hda-hdac_stream-fix-potential-locking-issue-in-snd_hdac_stream_assign.patch