]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2024 13:53:45 +0000 (15:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 23 Jul 2024 13:53:45 +0000 (15:53 +0200)
added patches:
alsa-hda-cs35l41-fix-swapped-l-r-audio-channels-for-lenovo-thinbook-13x-gen4.patch
bluetooth-l2cap-fix-deadlock.patch
cachefiles-fix-slab-use-after-free-in-cachefiles_withdraw_cookie.patch
cachefiles-fix-slab-use-after-free-in-fscache_withdraw_volume.patch
netfs-fscache-export-fscache_put_volume-and-add-fscache_try_get_volume.patch
of-irq-disable-interrupt-map-parsing-for-pasemi-nemo.patch
wifi-cfg80211-wext-set-ssids-null-for-passive-scans.patch
wifi-iwlwifi-mvm-don-t-wake-up-rx_sync_waitq-upon-rfkill.patch
wifi-mac80211-disable-softirqs-for-queued-frame-handling.patch

queue-6.9/alsa-hda-cs35l41-fix-swapped-l-r-audio-channels-for-lenovo-thinbook-13x-gen4.patch [new file with mode: 0644]
queue-6.9/bluetooth-l2cap-fix-deadlock.patch [new file with mode: 0644]
queue-6.9/cachefiles-fix-slab-use-after-free-in-cachefiles_withdraw_cookie.patch [new file with mode: 0644]
queue-6.9/cachefiles-fix-slab-use-after-free-in-fscache_withdraw_volume.patch [new file with mode: 0644]
queue-6.9/netfs-fscache-export-fscache_put_volume-and-add-fscache_try_get_volume.patch [new file with mode: 0644]
queue-6.9/of-irq-disable-interrupt-map-parsing-for-pasemi-nemo.patch [new file with mode: 0644]
queue-6.9/series
queue-6.9/wifi-cfg80211-wext-set-ssids-null-for-passive-scans.patch [new file with mode: 0644]
queue-6.9/wifi-iwlwifi-mvm-don-t-wake-up-rx_sync_waitq-upon-rfkill.patch [new file with mode: 0644]
queue-6.9/wifi-mac80211-disable-softirqs-for-queued-frame-handling.patch [new file with mode: 0644]

diff --git a/queue-6.9/alsa-hda-cs35l41-fix-swapped-l-r-audio-channels-for-lenovo-thinbook-13x-gen4.patch b/queue-6.9/alsa-hda-cs35l41-fix-swapped-l-r-audio-channels-for-lenovo-thinbook-13x-gen4.patch
new file mode 100644 (file)
index 0000000..f0aaa8c
--- /dev/null
@@ -0,0 +1,34 @@
+From 0f74758c08fc711b45cdf5564c5b12903fe88c82 Mon Sep 17 00:00:00 2001
+From: Dmitry Savin <envelsavinds@gmail.com>
+Date: Thu, 4 Jul 2024 22:14:01 +0100
+Subject: ALSA: hda: cs35l41: Fix swapped l/r audio channels for Lenovo ThinBook 13x Gen4
+
+From: Dmitry Savin <envelsavinds@gmail.com>
+
+commit 0f74758c08fc711b45cdf5564c5b12903fe88c82 upstream.
+
+Fixes audio channel assignment in configuration table for ThinkBook 13x Gen4.
+
+Fixes: b32f92d1af37 ("ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 4")
+Signed-off-by: Dmitry Savin <envelsavinds@gmail.com>
+Reviewed-by: Stefan Binding <sbinding@opensource.cirrus.com>
+Link: https://patch.msgid.link/20240704211402.87776-1-envelsavinds@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/cs35l41_hda_property.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/hda/cs35l41_hda_property.c
++++ b/sound/pci/hda/cs35l41_hda_property.c
+@@ -118,8 +118,8 @@ static const struct cs35l41_config cs35l
+       { "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       { "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+       { "17AA38B7", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
+-      { "17AA38C7", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 2, -1, 1000, 4500, 24 },
+-      { "17AA38C8", 4, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT }, 0, 2, -1, 1000, 4500, 24 },
++      { "17AA38C7", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 },
++      { "17AA38C8", 4, INTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, CS35L41_RIGHT, CS35L41_LEFT }, 0, 2, -1, 1000, 4500, 24 },
+       { "17AA38F9", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
+       { "17AA38FA", 2, EXTERNAL, { CS35L41_RIGHT, CS35L41_LEFT, 0, 0 }, 0, 2, -1, 0, 0, 0 },
+       {}
diff --git a/queue-6.9/bluetooth-l2cap-fix-deadlock.patch b/queue-6.9/bluetooth-l2cap-fix-deadlock.patch
new file mode 100644 (file)
index 0000000..f144207
--- /dev/null
@@ -0,0 +1,258 @@
+From f1a8f402f13f94263cf349216c257b2985100927 Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Mon, 24 Jun 2024 09:42:09 -0400
+Subject: Bluetooth: L2CAP: Fix deadlock
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+commit f1a8f402f13f94263cf349216c257b2985100927 upstream.
+
+This fixes the following deadlock introduced by 39a92a55be13
+("bluetooth/l2cap: sync sock recv cb and release")
+
+============================================
+WARNING: possible recursive locking detected
+6.10.0-rc3-g4029dba6b6f1 #6823 Not tainted
+--------------------------------------------
+kworker/u5:0/35 is trying to acquire lock:
+ffff888002ec2510 (&chan->lock#2/1){+.+.}-{3:3}, at:
+l2cap_sock_recv_cb+0x44/0x1e0
+
+but task is already holding lock:
+ffff888002ec2510 (&chan->lock#2/1){+.+.}-{3:3}, at:
+l2cap_get_chan_by_scid+0xaf/0xd0
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+       CPU0
+       ----
+  lock(&chan->lock#2/1);
+  lock(&chan->lock#2/1);
+
+ *** DEADLOCK ***
+
+ May be due to missing lock nesting notation
+
+3 locks held by kworker/u5:0/35:
+ #0: ffff888002b8a940 ((wq_completion)hci0#2){+.+.}-{0:0}, at:
+process_one_work+0x750/0x930
+ #1: ffff888002c67dd0 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0},
+at: process_one_work+0x44e/0x930
+ #2: ffff888002ec2510 (&chan->lock#2/1){+.+.}-{3:3}, at:
+l2cap_get_chan_by_scid+0xaf/0xd0
+
+To fix the original problem this introduces l2cap_chan_lock at
+l2cap_conless_channel to ensure that l2cap_sock_recv_cb is called with
+chan->lock held.
+
+Fixes: 89e856e124f9 ("bluetooth/l2cap: sync sock recv cb and release")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/hci_sync.h |    2 +
+ net/bluetooth/hci_core.c         |   72 +++++++++------------------------------
+ net/bluetooth/hci_sync.c         |   13 +++++++
+ net/bluetooth/l2cap_core.c       |    3 +
+ net/bluetooth/l2cap_sock.c       |   13 -------
+ 5 files changed, 37 insertions(+), 66 deletions(-)
+
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -38,6 +38,8 @@ int __hci_cmd_sync_status(struct hci_dev
+ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
+                            const void *param, u8 event, u32 timeout,
+                            struct sock *sk);
++int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
++                      const void *param, u32 timeout);
+ void hci_cmd_sync_init(struct hci_dev *hdev);
+ void hci_cmd_sync_clear(struct hci_dev *hdev);
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -63,50 +63,6 @@ DEFINE_MUTEX(hci_cb_list_lock);
+ /* HCI ID Numbering */
+ static DEFINE_IDA(hci_index_ida);
+-static int hci_scan_req(struct hci_request *req, unsigned long opt)
+-{
+-      __u8 scan = opt;
+-
+-      BT_DBG("%s %x", req->hdev->name, scan);
+-
+-      /* Inquiry and Page scans */
+-      hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
+-      return 0;
+-}
+-
+-static int hci_auth_req(struct hci_request *req, unsigned long opt)
+-{
+-      __u8 auth = opt;
+-
+-      BT_DBG("%s %x", req->hdev->name, auth);
+-
+-      /* Authentication */
+-      hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
+-      return 0;
+-}
+-
+-static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
+-{
+-      __u8 encrypt = opt;
+-
+-      BT_DBG("%s %x", req->hdev->name, encrypt);
+-
+-      /* Encryption */
+-      hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
+-      return 0;
+-}
+-
+-static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
+-{
+-      __le16 policy = cpu_to_le16(opt);
+-
+-      BT_DBG("%s %x", req->hdev->name, policy);
+-
+-      /* Default link policy */
+-      hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
+-      return 0;
+-}
+-
+ /* Get HCI device by index.
+  * Device is held on return. */
+ struct hci_dev *hci_dev_get(int index)
+@@ -728,6 +684,7 @@ int hci_dev_cmd(unsigned int cmd, void _
+ {
+       struct hci_dev *hdev;
+       struct hci_dev_req dr;
++      __le16 policy;
+       int err = 0;
+       if (copy_from_user(&dr, arg, sizeof(dr)))
+@@ -754,8 +711,8 @@ int hci_dev_cmd(unsigned int cmd, void _
+       switch (cmd) {
+       case HCISETAUTH:
+-              err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
+-                                 HCI_INIT_TIMEOUT, NULL);
++              err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
++                                          1, &dr.dev_opt, HCI_CMD_TIMEOUT);
+               break;
+       case HCISETENCRYPT:
+@@ -766,19 +723,23 @@ int hci_dev_cmd(unsigned int cmd, void _
+               if (!test_bit(HCI_AUTH, &hdev->flags)) {
+                       /* Auth must be enabled first */
+-                      err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
+-                                         HCI_INIT_TIMEOUT, NULL);
++                      err = __hci_cmd_sync_status(hdev,
++                                                  HCI_OP_WRITE_AUTH_ENABLE,
++                                                  1, &dr.dev_opt,
++                                                  HCI_CMD_TIMEOUT);
+                       if (err)
+                               break;
+               }
+-              err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
+-                                 HCI_INIT_TIMEOUT, NULL);
++              err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE,
++                                          1, &dr.dev_opt,
++                                          HCI_CMD_TIMEOUT);
+               break;
+       case HCISETSCAN:
+-              err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
+-                                 HCI_INIT_TIMEOUT, NULL);
++              err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
++                                          1, &dr.dev_opt,
++                                          HCI_CMD_TIMEOUT);
+               /* Ensure that the connectable and discoverable states
+                * get correctly modified as this was a non-mgmt change.
+@@ -788,8 +749,11 @@ int hci_dev_cmd(unsigned int cmd, void _
+               break;
+       case HCISETLINKPOL:
+-              err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
+-                                 HCI_INIT_TIMEOUT, NULL);
++              policy = cpu_to_le16(dr.dev_opt);
++
++              err = __hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
++                                          2, &policy,
++                                          HCI_CMD_TIMEOUT);
+               break;
+       case HCISETLINKMODE:
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -280,6 +280,19 @@ int __hci_cmd_sync_status(struct hci_dev
+ }
+ EXPORT_SYMBOL(__hci_cmd_sync_status);
++int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
++                      const void *param, u32 timeout)
++{
++      int err;
++
++      hci_req_sync_lock(hdev);
++      err = __hci_cmd_sync_status(hdev, opcode, plen, param, timeout);
++      hci_req_sync_unlock(hdev);
++
++      return err;
++}
++EXPORT_SYMBOL(hci_cmd_sync_status);
++
+ static void hci_cmd_sync_work(struct work_struct *work)
+ {
+       struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6762,6 +6762,8 @@ static void l2cap_conless_channel(struct
+       BT_DBG("chan %p, len %d", chan, skb->len);
++      l2cap_chan_lock(chan);
++
+       if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
+               goto drop;
+@@ -6778,6 +6780,7 @@ static void l2cap_conless_channel(struct
+       }
+ drop:
++      l2cap_chan_unlock(chan);
+       l2cap_chan_put(chan);
+ free_skb:
+       kfree_skb(skb);
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -1489,18 +1489,9 @@ static int l2cap_sock_recv_cb(struct l2c
+       struct l2cap_pinfo *pi;
+       int err;
+-      /* To avoid race with sock_release, a chan lock needs to be added here
+-       * to synchronize the sock.
+-       */
+-      l2cap_chan_hold(chan);
+-      l2cap_chan_lock(chan);
+       sk = chan->data;
+-
+-      if (!sk) {
+-              l2cap_chan_unlock(chan);
+-              l2cap_chan_put(chan);
++      if (!sk)
+               return -ENXIO;
+-      }
+       pi = l2cap_pi(sk);
+       lock_sock(sk);
+@@ -1552,8 +1543,6 @@ static int l2cap_sock_recv_cb(struct l2c
+ done:
+       release_sock(sk);
+-      l2cap_chan_unlock(chan);
+-      l2cap_chan_put(chan);
+       return err;
+ }
diff --git a/queue-6.9/cachefiles-fix-slab-use-after-free-in-cachefiles_withdraw_cookie.patch b/queue-6.9/cachefiles-fix-slab-use-after-free-in-cachefiles_withdraw_cookie.patch
new file mode 100644 (file)
index 0000000..6602244
--- /dev/null
@@ -0,0 +1,166 @@
+From stable+bounces-60607-greg=kroah.com@vger.kernel.org Fri Jul 19 15:31:16 2024
+From: libaokun@huaweicloud.com
+Date: Fri, 19 Jul 2024 21:28:12 +0800
+Subject: cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, sashal@kernel.org, patches@lists.linux.dev, hsiangkao@linux.alibaba.com, yangerkun@huawei.com, libaokun1@huawei.com, Hou Tao <houtao1@huawei.com>, Christian Brauner <brauner@kernel.org>
+Message-ID: <20240719132812.1542957-3-libaokun@huaweicloud.com>
+
+From: libaokun@huaweicloud.com
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 5d8f805789072ea7fd39504694b7bd17e5f751c4 ]
+
+We got the following issue in our fault injection stress test:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in cachefiles_withdraw_cookie+0x4d9/0x600
+Read of size 8 at addr ffff888118efc000 by task kworker/u78:0/109
+
+CPU: 13 PID: 109 Comm: kworker/u78:0 Not tainted 6.8.0-dirty #566
+Call Trace:
+ <TASK>
+ kasan_report+0x93/0xc0
+ cachefiles_withdraw_cookie+0x4d9/0x600
+ fscache_cookie_state_machine+0x5c8/0x1230
+ fscache_cookie_worker+0x91/0x1c0
+ process_one_work+0x7fa/0x1800
+ [...]
+
+Allocated by task 117:
+ kmalloc_trace+0x1b3/0x3c0
+ cachefiles_acquire_volume+0xf3/0x9c0
+ fscache_create_volume_work+0x97/0x150
+ process_one_work+0x7fa/0x1800
+ [...]
+
+Freed by task 120301:
+ kfree+0xf1/0x2c0
+ cachefiles_withdraw_cache+0x3fa/0x920
+ cachefiles_put_unbind_pincount+0x1f6/0x250
+ cachefiles_daemon_release+0x13b/0x290
+ __fput+0x204/0xa00
+ task_work_run+0x139/0x230
+ do_exit+0x87a/0x29b0
+ [...]
+==================================================================
+
+Following is the process that triggers the issue:
+
+           p1                |             p2
+------------------------------------------------------------
+                              fscache_begin_lookup
+                               fscache_begin_volume_access
+                                fscache_cache_is_live(fscache_cache)
+cachefiles_daemon_release
+ cachefiles_put_unbind_pincount
+  cachefiles_daemon_unbind
+   cachefiles_withdraw_cache
+    fscache_withdraw_cache
+     fscache_set_cache_state(cache, FSCACHE_CACHE_IS_WITHDRAWN);
+    cachefiles_withdraw_objects(cache)
+    fscache_wait_for_objects(fscache)
+      atomic_read(&fscache_cache->object_count) == 0
+                              fscache_perform_lookup
+                               cachefiles_lookup_cookie
+                                cachefiles_alloc_object
+                                 refcount_set(&object->ref, 1);
+                                 object->volume = volume
+                                 fscache_count_object(vcookie->cache);
+                                  atomic_inc(&fscache_cache->object_count)
+    cachefiles_withdraw_volumes
+     cachefiles_withdraw_volume
+      fscache_withdraw_volume
+      __cachefiles_free_volume
+       kfree(cachefiles_volume)
+                              fscache_cookie_state_machine
+                               cachefiles_withdraw_cookie
+                                cache = object->volume->cache;
+                                // cachefiles_volume UAF !!!
+
+After setting FSCACHE_CACHE_IS_WITHDRAWN, wait for all the cookie lookups
+to complete first, and then wait for fscache_cache->object_count == 0 to
+avoid the cookie exiting after the volume has been freed and triggering
+the above issue. Therefore call fscache_withdraw_volume() before calling
+cachefiles_withdraw_objects().
+
+This way, after setting FSCACHE_CACHE_IS_WITHDRAWN, only the following two
+cases will occur:
+1) fscache_begin_lookup fails in fscache_begin_volume_access().
+2) fscache_withdraw_volume() will ensure that fscache_count_object() has
+   been executed before calling fscache_wait_for_objects().
+
+Fixes: fe2140e2f57f ("cachefiles: Implement volume support")
+Suggested-by: Hou Tao <houtao1@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Link: https://lore.kernel.org/r/20240628062930.2467993-4-libaokun@huaweicloud.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cachefiles/cache.c  |   35 ++++++++++++++++++++++++++++++++++-
+ fs/cachefiles/volume.c |    1 -
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/fs/cachefiles/cache.c
++++ b/fs/cachefiles/cache.c
+@@ -313,7 +313,39 @@ static void cachefiles_withdraw_objects(
+ }
+ /*
+- * Withdraw volumes.
++ * Withdraw fscache volumes.
++ */
++static void cachefiles_withdraw_fscache_volumes(struct cachefiles_cache *cache)
++{
++      struct list_head *cur;
++      struct cachefiles_volume *volume;
++      struct fscache_volume *vcookie;
++
++      _enter("");
++retry:
++      spin_lock(&cache->object_list_lock);
++      list_for_each(cur, &cache->volumes) {
++              volume = list_entry(cur, struct cachefiles_volume, cache_link);
++
++              if (atomic_read(&volume->vcookie->n_accesses) == 0)
++                      continue;
++
++              vcookie = fscache_try_get_volume(volume->vcookie,
++                                               fscache_volume_get_withdraw);
++              if (vcookie) {
++                      spin_unlock(&cache->object_list_lock);
++                      fscache_withdraw_volume(vcookie);
++                      fscache_put_volume(vcookie, fscache_volume_put_withdraw);
++                      goto retry;
++              }
++      }
++      spin_unlock(&cache->object_list_lock);
++
++      _leave("");
++}
++
++/*
++ * Withdraw cachefiles volumes.
+  */
+ static void cachefiles_withdraw_volumes(struct cachefiles_cache *cache)
+ {
+@@ -381,6 +413,7 @@ void cachefiles_withdraw_cache(struct ca
+       pr_info("File cache on %s unregistering\n", fscache->name);
+       fscache_withdraw_cache(fscache);
++      cachefiles_withdraw_fscache_volumes(cache);
+       /* we now have to destroy all the active objects pertaining to this
+        * cache - which we do by passing them off to thread pool to be
+--- a/fs/cachefiles/volume.c
++++ b/fs/cachefiles/volume.c
+@@ -133,7 +133,6 @@ void cachefiles_free_volume(struct fscac
+ void cachefiles_withdraw_volume(struct cachefiles_volume *volume)
+ {
+-      fscache_withdraw_volume(volume->vcookie);
+       cachefiles_set_volume_xattr(volume);
+       __cachefiles_free_volume(volume);
+ }
diff --git a/queue-6.9/cachefiles-fix-slab-use-after-free-in-fscache_withdraw_volume.patch b/queue-6.9/cachefiles-fix-slab-use-after-free-in-fscache_withdraw_volume.patch
new file mode 100644 (file)
index 0000000..cfee850
--- /dev/null
@@ -0,0 +1,173 @@
+From stable+bounces-60608-greg=kroah.com@vger.kernel.org Fri Jul 19 15:31:17 2024
+From: libaokun@huaweicloud.com
+Date: Fri, 19 Jul 2024 21:28:11 +0800
+Subject: cachefiles: fix slab-use-after-free in fscache_withdraw_volume()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, sashal@kernel.org, patches@lists.linux.dev, hsiangkao@linux.alibaba.com, yangerkun@huawei.com, libaokun1@huawei.com, Christian Brauner <brauner@kernel.org>
+Message-ID: <20240719132812.1542957-2-libaokun@huaweicloud.com>
+
+From: libaokun@huaweicloud.com
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 522018a0de6b6fcce60c04f86dfc5f0e4b6a1b36 ]
+
+We got the following issue in our fault injection stress test:
+
+==================================================================
+BUG: KASAN: slab-use-after-free in fscache_withdraw_volume+0x2e1/0x370
+Read of size 4 at addr ffff88810680be08 by task ondemand-04-dae/5798
+
+CPU: 0 PID: 5798 Comm: ondemand-04-dae Not tainted 6.8.0-dirty #565
+Call Trace:
+ kasan_check_range+0xf6/0x1b0
+ fscache_withdraw_volume+0x2e1/0x370
+ cachefiles_withdraw_volume+0x31/0x50
+ cachefiles_withdraw_cache+0x3ad/0x900
+ cachefiles_put_unbind_pincount+0x1f6/0x250
+ cachefiles_daemon_release+0x13b/0x290
+ __fput+0x204/0xa00
+ task_work_run+0x139/0x230
+
+Allocated by task 5820:
+ __kmalloc+0x1df/0x4b0
+ fscache_alloc_volume+0x70/0x600
+ __fscache_acquire_volume+0x1c/0x610
+ erofs_fscache_register_volume+0x96/0x1a0
+ erofs_fscache_register_fs+0x49a/0x690
+ erofs_fc_fill_super+0x6c0/0xcc0
+ vfs_get_super+0xa9/0x140
+ vfs_get_tree+0x8e/0x300
+ do_new_mount+0x28c/0x580
+ [...]
+
+Freed by task 5820:
+ kfree+0xf1/0x2c0
+ fscache_put_volume.part.0+0x5cb/0x9e0
+ erofs_fscache_unregister_fs+0x157/0x1b0
+ erofs_kill_sb+0xd9/0x1c0
+ deactivate_locked_super+0xa3/0x100
+ vfs_get_super+0x105/0x140
+ vfs_get_tree+0x8e/0x300
+ do_new_mount+0x28c/0x580
+ [...]
+==================================================================
+
+Following is the process that triggers the issue:
+
+        mount failed         |         daemon exit
+------------------------------------------------------------
+ deactivate_locked_super        cachefiles_daemon_release
+  erofs_kill_sb
+   erofs_fscache_unregister_fs
+    fscache_relinquish_volume
+     __fscache_relinquish_volume
+      fscache_put_volume(fscache_volume, fscache_volume_put_relinquish)
+       zero = __refcount_dec_and_test(&fscache_volume->ref, &ref);
+                                 cachefiles_put_unbind_pincount
+                                  cachefiles_daemon_unbind
+                                   cachefiles_withdraw_cache
+                                    cachefiles_withdraw_volumes
+                                     list_del_init(&volume->cache_link)
+       fscache_free_volume(fscache_volume)
+        cache->ops->free_volume
+         cachefiles_free_volume
+          list_del_init(&cachefiles_volume->cache_link);
+        kfree(fscache_volume)
+                                     cachefiles_withdraw_volume
+                                      fscache_withdraw_volume
+                                       fscache_volume->n_accesses
+                                       // fscache_volume UAF !!!
+
+The fscache_volume in cache->volumes must not have been freed yet, but its
+reference count may be 0. So use the new fscache_try_get_volume() helper
+function try to get its reference count.
+
+If the reference count of fscache_volume is 0, fscache_put_volume() is
+freeing it, so wait for it to be removed from cache->volumes.
+
+If its reference count is not 0, call cachefiles_withdraw_volume() with
+reference count protection to avoid the above issue.
+
+Fixes: fe2140e2f57f ("cachefiles: Implement volume support")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Link: https://lore.kernel.org/r/20240628062930.2467993-3-libaokun@huaweicloud.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cachefiles/cache.c          |   10 ++++++++++
+ include/trace/events/fscache.h |    4 ++++
+ 2 files changed, 14 insertions(+)
+
+--- a/fs/cachefiles/cache.c
++++ b/fs/cachefiles/cache.c
+@@ -8,6 +8,7 @@
+ #include <linux/slab.h>
+ #include <linux/statfs.h>
+ #include <linux/namei.h>
++#include <trace/events/fscache.h>
+ #include "internal.h"
+ /*
+@@ -319,12 +320,20 @@ static void cachefiles_withdraw_volumes(
+       _enter("");
+       for (;;) {
++              struct fscache_volume *vcookie = NULL;
+               struct cachefiles_volume *volume = NULL;
+               spin_lock(&cache->object_list_lock);
+               if (!list_empty(&cache->volumes)) {
+                       volume = list_first_entry(&cache->volumes,
+                                                 struct cachefiles_volume, cache_link);
++                      vcookie = fscache_try_get_volume(volume->vcookie,
++                                                       fscache_volume_get_withdraw);
++                      if (!vcookie) {
++                              spin_unlock(&cache->object_list_lock);
++                              cpu_relax();
++                              continue;
++                      }
+                       list_del_init(&volume->cache_link);
+               }
+               spin_unlock(&cache->object_list_lock);
+@@ -332,6 +341,7 @@ static void cachefiles_withdraw_volumes(
+                       break;
+               cachefiles_withdraw_volume(volume);
++              fscache_put_volume(vcookie, fscache_volume_put_withdraw);
+       }
+       _leave("");
+--- a/include/trace/events/fscache.h
++++ b/include/trace/events/fscache.h
+@@ -35,12 +35,14 @@ enum fscache_volume_trace {
+       fscache_volume_get_cookie,
+       fscache_volume_get_create_work,
+       fscache_volume_get_hash_collision,
++      fscache_volume_get_withdraw,
+       fscache_volume_free,
+       fscache_volume_new_acquire,
+       fscache_volume_put_cookie,
+       fscache_volume_put_create_work,
+       fscache_volume_put_hash_collision,
+       fscache_volume_put_relinquish,
++      fscache_volume_put_withdraw,
+       fscache_volume_see_create_work,
+       fscache_volume_see_hash_wake,
+       fscache_volume_wait_create_work,
+@@ -120,12 +122,14 @@ enum fscache_access_trace {
+       EM(fscache_volume_get_cookie,           "GET cook ")            \
+       EM(fscache_volume_get_create_work,      "GET creat")            \
+       EM(fscache_volume_get_hash_collision,   "GET hcoll")            \
++      EM(fscache_volume_get_withdraw,         "GET withd")            \
+       EM(fscache_volume_free,                 "FREE     ")            \
+       EM(fscache_volume_new_acquire,          "NEW acq  ")            \
+       EM(fscache_volume_put_cookie,           "PUT cook ")            \
+       EM(fscache_volume_put_create_work,      "PUT creat")            \
+       EM(fscache_volume_put_hash_collision,   "PUT hcoll")            \
+       EM(fscache_volume_put_relinquish,       "PUT relnq")            \
++      EM(fscache_volume_put_withdraw,         "PUT withd")            \
+       EM(fscache_volume_see_create_work,      "SEE creat")            \
+       EM(fscache_volume_see_hash_wake,        "SEE hwake")            \
+       E_(fscache_volume_wait_create_work,     "WAIT crea")
diff --git a/queue-6.9/netfs-fscache-export-fscache_put_volume-and-add-fscache_try_get_volume.patch b/queue-6.9/netfs-fscache-export-fscache_put_volume-and-add-fscache_try_get_volume.patch
new file mode 100644 (file)
index 0000000..19fd830
--- /dev/null
@@ -0,0 +1,94 @@
+From stable+bounces-60606-greg=kroah.com@vger.kernel.org Fri Jul 19 15:31:16 2024
+From: libaokun@huaweicloud.com
+Date: Fri, 19 Jul 2024 21:28:10 +0800
+Subject: netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume()
+To: stable@vger.kernel.org
+Cc: gregkh@linuxfoundation.org, sashal@kernel.org, patches@lists.linux.dev, hsiangkao@linux.alibaba.com, yangerkun@huawei.com, libaokun1@huawei.com, Christian Brauner <brauner@kernel.org>
+Message-ID: <20240719132812.1542957-1-libaokun@huaweicloud.com>
+
+From: libaokun@huaweicloud.com
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 85b08b31a22b481ec6528130daf94eee4452e23f ]
+
+Export fscache_put_volume() and add fscache_try_get_volume()
+helper function to allow cachefiles to get/put fscache_volume
+via linux/fscache-cache.h.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Link: https://lore.kernel.org/r/20240628062930.2467993-2-libaokun@huaweicloud.com
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Stable-dep-of: 522018a0de6b ("cachefiles: fix slab-use-after-free in fscache_withdraw_volume()")
+Stable-dep-of: 5d8f80578907 ("cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie()")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/netfs/fscache_volume.c     |   14 ++++++++++++++
+ fs/netfs/internal.h           |    2 --
+ include/linux/fscache-cache.h |    6 ++++++
+ 3 files changed, 20 insertions(+), 2 deletions(-)
+
+--- a/fs/netfs/fscache_volume.c
++++ b/fs/netfs/fscache_volume.c
+@@ -27,6 +27,19 @@ struct fscache_volume *fscache_get_volum
+       return volume;
+ }
++struct fscache_volume *fscache_try_get_volume(struct fscache_volume *volume,
++                                            enum fscache_volume_trace where)
++{
++      int ref;
++
++      if (!__refcount_inc_not_zero(&volume->ref, &ref))
++              return NULL;
++
++      trace_fscache_volume(volume->debug_id, ref + 1, where);
++      return volume;
++}
++EXPORT_SYMBOL(fscache_try_get_volume);
++
+ static void fscache_see_volume(struct fscache_volume *volume,
+                              enum fscache_volume_trace where)
+ {
+@@ -420,6 +433,7 @@ void fscache_put_volume(struct fscache_v
+                       fscache_free_volume(volume);
+       }
+ }
++EXPORT_SYMBOL(fscache_put_volume);
+ /*
+  * Relinquish a volume representation cookie.
+--- a/fs/netfs/internal.h
++++ b/fs/netfs/internal.h
+@@ -326,8 +326,6 @@ extern const struct seq_operations fscac
+ struct fscache_volume *fscache_get_volume(struct fscache_volume *volume,
+                                         enum fscache_volume_trace where);
+-void fscache_put_volume(struct fscache_volume *volume,
+-                      enum fscache_volume_trace where);
+ bool fscache_begin_volume_access(struct fscache_volume *volume,
+                                struct fscache_cookie *cookie,
+                                enum fscache_access_trace why);
+--- a/include/linux/fscache-cache.h
++++ b/include/linux/fscache-cache.h
+@@ -19,6 +19,7 @@
+ enum fscache_cache_trace;
+ enum fscache_cookie_trace;
+ enum fscache_access_trace;
++enum fscache_volume_trace;
+ enum fscache_cache_state {
+       FSCACHE_CACHE_IS_NOT_PRESENT,   /* No cache is present for this name */
+@@ -97,6 +98,11 @@ extern void fscache_withdraw_cookie(stru
+ extern void fscache_io_error(struct fscache_cache *cache);
++extern struct fscache_volume *
++fscache_try_get_volume(struct fscache_volume *volume,
++                     enum fscache_volume_trace where);
++extern void fscache_put_volume(struct fscache_volume *volume,
++                             enum fscache_volume_trace where);
+ extern void fscache_end_volume_access(struct fscache_volume *volume,
+                                     struct fscache_cookie *cookie,
+                                     enum fscache_access_trace why);
diff --git a/queue-6.9/of-irq-disable-interrupt-map-parsing-for-pasemi-nemo.patch b/queue-6.9/of-irq-disable-interrupt-map-parsing-for-pasemi-nemo.patch
new file mode 100644 (file)
index 0000000..8e18efd
--- /dev/null
@@ -0,0 +1,68 @@
+From 2cf6b7d15a28640117bf9f75dc050892cf78a6e8 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Tue, 2 Jul 2024 22:42:46 +0100
+Subject: of/irq: Disable "interrupt-map" parsing for PASEMI Nemo
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 2cf6b7d15a28640117bf9f75dc050892cf78a6e8 upstream.
+
+Once again, we've broken PASEMI Nemo boards with its incomplete
+"interrupt-map" translations. Commit 935df1bd40d4 ("of/irq: Factor out
+parsing of interrupt-map parent phandle+args from of_irq_parse_raw()")
+changed the behavior resulting in the existing work-around not taking
+effect. Rework the work-around to just skip parsing "interrupt-map" up
+front by using the of_irq_imap_abusers list.
+
+Fixes: 935df1bd40d4 ("of/irq: Factor out parsing of interrupt-map parent phandle+args from of_irq_parse_raw()")
+Reported-by: Christian Zigotzky <chzigotzky@xenosoft.de>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/86ed8ba2sp.wl-maz@kernel.org
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/of/irq.c |   18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -81,7 +81,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+ /*
+  * These interrupt controllers abuse interrupt-map for unspeakable
+  * reasons and rely on the core code to *ignore* it (the drivers do
+- * their own parsing of the property).
++ * their own parsing of the property). The PAsemi entry covers a
++ * non-sensical interrupt-map that is better left ignored.
+  *
+  * If you think of adding to the list for something *new*, think
+  * again. There is a high chance that you will be sent back to the
+@@ -95,6 +96,7 @@ static const char * const of_irq_imap_ab
+       "fsl,ls1043a-extirq",
+       "fsl,ls1088a-extirq",
+       "renesas,rza1-irqc",
++      "pasemi,rootbus",
+       NULL,
+ };
+@@ -293,20 +295,8 @@ int of_irq_parse_raw(const __be32 *addr,
+                       imaplen -= imap - oldimap;
+                       pr_debug(" -> imaplen=%d\n", imaplen);
+               }
+-              if (!match) {
+-                      if (intc) {
+-                              /*
+-                               * The PASEMI Nemo is a known offender, so
+-                               * let's only warn for anyone else.
+-                               */
+-                              WARN(!IS_ENABLED(CONFIG_PPC_PASEMI),
+-                                   "%pOF interrupt-map failed, using interrupt-controller\n",
+-                                   ipar);
+-                              return 0;
+-                      }
+-
++              if (!match)
+                       goto fail;
+-              }
+               /*
+                * Successfully parsed an interrupt-map translation; copy new
index 0b5561f5c5fc75197658747f2f2365af55a737e3..b3eeb37d7242d0baad38ad2b6d3d1a55b1059467 100644 (file)
@@ -152,3 +152,12 @@ selftests-bpf-extend-tcx-tests-to-cover-late-tcx_ent.patch
 spi-mux-set-ctlr-bits_per_word_mask.patch
 alsa-hda-use-imply-for-suggesting-config_serial_mult.patch
 mm-page_ref-remove-folio_try_get_rcu.patch
+bluetooth-l2cap-fix-deadlock.patch
+alsa-hda-cs35l41-fix-swapped-l-r-audio-channels-for-lenovo-thinbook-13x-gen4.patch
+of-irq-disable-interrupt-map-parsing-for-pasemi-nemo.patch
+wifi-cfg80211-wext-set-ssids-null-for-passive-scans.patch
+wifi-mac80211-disable-softirqs-for-queued-frame-handling.patch
+wifi-iwlwifi-mvm-don-t-wake-up-rx_sync_waitq-upon-rfkill.patch
+netfs-fscache-export-fscache_put_volume-and-add-fscache_try_get_volume.patch
+cachefiles-fix-slab-use-after-free-in-fscache_withdraw_volume.patch
+cachefiles-fix-slab-use-after-free-in-cachefiles_withdraw_cookie.patch
diff --git a/queue-6.9/wifi-cfg80211-wext-set-ssids-null-for-passive-scans.patch b/queue-6.9/wifi-cfg80211-wext-set-ssids-null-for-passive-scans.patch
new file mode 100644 (file)
index 0000000..347435f
--- /dev/null
@@ -0,0 +1,41 @@
+From 0941772342d59e48733131ac3a202fa1a4d832e9 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 11 Jun 2024 18:58:16 +0200
+Subject: wifi: cfg80211: wext: set ssids=NULL for passive scans
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 0941772342d59e48733131ac3a202fa1a4d832e9 upstream.
+
+In nl80211, we always set the ssids of a scan request to
+NULL when n_ssids==0 (passive scan). Drivers have relied
+on this behaviour in the past, so we fixed it in 6 GHz
+scan requests as well, and added a warning so we'd have
+assurance the API would always be called that way.
+
+syzbot found that wext doesn't ensure that, so we reach
+the check and trigger the warning. Fix the wext code to
+set the ssids pointer to NULL when there are none.
+
+Reported-by: syzbot+cd6135193ba6bb9ad158@syzkaller.appspotmail.com
+Fixes: f7a8b10bfd61 ("wifi: cfg80211: fix 6 GHz scan request building")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/scan.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -3492,8 +3492,10 @@ int cfg80211_wext_siwscan(struct net_dev
+                       memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
+                       creq->ssids[0].ssid_len = wreq->essid_len;
+               }
+-              if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
++              if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) {
++                      creq->ssids = NULL;
+                       creq->n_ssids = 0;
++              }
+       }
+       for (i = 0; i < NUM_NL80211_BANDS; i++)
diff --git a/queue-6.9/wifi-iwlwifi-mvm-don-t-wake-up-rx_sync_waitq-upon-rfkill.patch b/queue-6.9/wifi-iwlwifi-mvm-don-t-wake-up-rx_sync_waitq-upon-rfkill.patch
new file mode 100644 (file)
index 0000000..8b5257d
--- /dev/null
@@ -0,0 +1,57 @@
+From e715c9302b1c6fae990b9898a80fac855549d1f0 Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Wed, 3 Jul 2024 06:43:16 +0300
+Subject: wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit e715c9302b1c6fae990b9898a80fac855549d1f0 upstream.
+
+Since we now want to sync the queues even when we're in RFKILL, we
+shouldn't wake up the wait queue since we still expect to get all the
+notifications from the firmware.
+
+Fixes: 4d08c0b3357c ("wifi: iwlwifi: mvm: handle BA session teardown in RF-kill")
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20240703064027.be7a9dbeacde.I5586cb3ca8d6e44f79d819a48a0c22351ff720c9@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |    6 ++----
+ drivers/net/wireless/intel/iwlwifi/mvm/ops.c      |    6 ++----
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -6189,11 +6189,9 @@ void iwl_mvm_sync_rx_queues_internal(str
+       if (sync) {
+               lockdep_assert_held(&mvm->mutex);
+               ret = wait_event_timeout(mvm->rx_sync_waitq,
+-                                       READ_ONCE(mvm->queue_sync_state) == 0 ||
+-                                       iwl_mvm_is_radio_hw_killed(mvm),
++                                       READ_ONCE(mvm->queue_sync_state) == 0,
+                                        SYNC_RX_QUEUE_TIMEOUT);
+-              WARN_ONCE(!ret && !iwl_mvm_is_radio_hw_killed(mvm),
+-                        "queue sync: failed to sync, state is 0x%lx, cookie %d\n",
++              WARN_ONCE(!ret, "queue sync: failed to sync, state is 0x%lx, cookie %d\n",
+                         mvm->queue_sync_state,
+                         mvm->queue_sync_cookie);
+       }
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -1854,12 +1854,10 @@ static bool iwl_mvm_set_hw_rfkill_state(
+       bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
+       bool unified = iwl_mvm_has_unified_ucode(mvm);
+-      if (state) {
++      if (state)
+               set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
+-              wake_up(&mvm->rx_sync_waitq);
+-      } else {
++      else
+               clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
+-      }
+       iwl_mvm_set_rfkill_state(mvm);
diff --git a/queue-6.9/wifi-mac80211-disable-softirqs-for-queued-frame-handling.patch b/queue-6.9/wifi-mac80211-disable-softirqs-for-queued-frame-handling.patch
new file mode 100644 (file)
index 0000000..6e4d1ee
--- /dev/null
@@ -0,0 +1,46 @@
+From 321028bc45f01edb9e57b0ae5c11c5c3600d00ca Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 26 Jun 2024 09:15:59 +0200
+Subject: wifi: mac80211: disable softirqs for queued frame handling
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 321028bc45f01edb9e57b0ae5c11c5c3600d00ca upstream.
+
+As noticed by syzbot, calling ieee80211_handle_queued_frames()
+(and actually handling frames there) requires softirqs to be
+disabled, since we call into the RX code. Fix that in the case
+of cleaning up frames left over during shutdown.
+
+Fixes: 177c6ae9725d ("wifi: mac80211: handle tasklet frames before stopping")
+Reported-by: syzbot+1d516edf1e74469ba5d3@syzkaller.appspotmail.com
+Link: https://patch.msgid.link/20240626091559.cd6f08105a6e.I74778610a5ff2cf8680964698131099d2960352a@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/main.c |    1 +
+ net/mac80211/util.c |    2 ++
+ 2 files changed, 3 insertions(+)
+
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -423,6 +423,7 @@ u64 ieee80211_reset_erp_info(struct ieee
+              BSS_CHANGED_ERP_SLOT;
+ }
++/* context: requires softirqs disabled */
+ void ieee80211_handle_queued_frames(struct ieee80211_local *local)
+ {
+       struct sk_buff *skb;
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1567,7 +1567,9 @@ u32 ieee80211_sta_get_rates(struct ieee8
+ void ieee80211_stop_device(struct ieee80211_local *local)
+ {
++      local_bh_disable();
+       ieee80211_handle_queued_frames(local);
++      local_bh_enable();
+       ieee80211_led_radio(local, false);
+       ieee80211_mod_tpt_led_trig(local, 0, IEEE80211_TPT_LEDTRIG_FL_RADIO);