]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 09:58:57 +0000 (11:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Aug 2021 09:58:57 +0000 (11:58 +0200)
added patches:
drivers-core-fix-oops-when-driver-probe-fails.patch
ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch
media-rtl28xxu-fix-zero-length-control-request.patch
pipe-increase-minimum-default-pipe-size-to-2-pages.patch
staging-rtl8712-error-handling-refactoring.patch
staging-rtl8712-get-rid-of-flush_scheduled_work.patch
staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch

queue-5.13/drivers-core-fix-oops-when-driver-probe-fails.patch [new file with mode: 0644]
queue-5.13/ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch [new file with mode: 0644]
queue-5.13/media-rtl28xxu-fix-zero-length-control-request.patch [new file with mode: 0644]
queue-5.13/pipe-increase-minimum-default-pipe-size-to-2-pages.patch [new file with mode: 0644]
queue-5.13/series
queue-5.13/staging-rtl8712-error-handling-refactoring.patch [new file with mode: 0644]
queue-5.13/staging-rtl8712-get-rid-of-flush_scheduled_work.patch [new file with mode: 0644]
queue-5.13/staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch [new file with mode: 0644]

diff --git a/queue-5.13/drivers-core-fix-oops-when-driver-probe-fails.patch b/queue-5.13/drivers-core-fix-oops-when-driver-probe-fails.patch
new file mode 100644 (file)
index 0000000..8083a46
--- /dev/null
@@ -0,0 +1,66 @@
+From 4d1014c1816c0395eca5d1d480f196a4c63119d0 Mon Sep 17 00:00:00 2001
+From: Filip Schauer <filip@mg6.at>
+Date: Tue, 27 Jul 2021 13:23:11 +0200
+Subject: drivers core: Fix oops when driver probe fails
+
+From: Filip Schauer <filip@mg6.at>
+
+commit 4d1014c1816c0395eca5d1d480f196a4c63119d0 upstream.
+
+dma_range_map is freed to early, which might cause an oops when
+a driver probe fails.
+ Call trace:
+  is_free_buddy_page+0xe4/0x1d4
+  __free_pages+0x2c/0x88
+  dma_free_contiguous+0x64/0x80
+  dma_direct_free+0x38/0xb4
+  dma_free_attrs+0x88/0xa0
+  dmam_release+0x28/0x34
+  release_nodes+0x78/0x8c
+  devres_release_all+0xa8/0x110
+  really_probe+0x118/0x2d0
+  __driver_probe_device+0xc8/0xe0
+  driver_probe_device+0x54/0xec
+  __driver_attach+0xe0/0xf0
+  bus_for_each_dev+0x7c/0xc8
+  driver_attach+0x30/0x3c
+  bus_add_driver+0x17c/0x1c4
+  driver_register+0xc0/0xf8
+  __platform_driver_register+0x34/0x40
+  ...
+
+This issue is introduced by commit d0243bbd5dd3 ("drivers core:
+Free dma_range_map when driver probe failed"). It frees
+dma_range_map before the call to devres_release_all, which is too
+early. The solution is to free dma_range_map only after
+devres_release_all.
+
+Fixes: d0243bbd5dd3 ("drivers core: Free dma_range_map when driver probe failed")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Filip Schauer <filip@mg6.at>
+Link: https://lore.kernel.org/r/20210727112311.GA7645@DESKTOP-E8BN1B0.localdomain
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/dd.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -634,8 +634,6 @@ dev_groups_failed:
+       else if (drv->remove)
+               drv->remove(dev);
+ probe_failed:
+-      kfree(dev->dma_range_map);
+-      dev->dma_range_map = NULL;
+       if (dev->bus)
+               blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+                                            BUS_NOTIFY_DRIVER_NOT_BOUND, dev);
+@@ -643,6 +641,8 @@ pinctrl_bind_failed:
+       device_links_no_driver(dev);
+       devres_release_all(dev);
+       arch_teardown_dma_ops(dev);
++      kfree(dev->dma_range_map);
++      dev->dma_range_map = NULL;
+       driver_sysfs_remove(dev);
+       dev->driver = NULL;
+       dev_set_drvdata(dev, NULL);
diff --git a/queue-5.13/ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch b/queue-5.13/ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch
new file mode 100644 (file)
index 0000000..31186e6
--- /dev/null
@@ -0,0 +1,38 @@
+From 877ba3f729fd3d8ef0e29bc2a55e57cfa54b2e43 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 4 Aug 2021 14:23:55 -0400
+Subject: ext4: fix potential htree corruption when growing large_dir directories
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 877ba3f729fd3d8ef0e29bc2a55e57cfa54b2e43 upstream.
+
+Commit b5776e7524af ("ext4: fix potential htree index checksum
+corruption) removed a required restart when multiple levels of index
+nodes need to be split.  Fix this to avoid directory htree corruptions
+when using the large_dir feature.
+
+Cc: stable@kernel.org # v5.11
+Cc: Благодаренко Артём <artem.blagodarenko@gmail.com>
+Fixes: b5776e7524af ("ext4: fix potential htree index checksum corruption)
+Reported-by: Denis <denis@voxelsoft.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/namei.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2517,7 +2517,7 @@ again:
+                               goto journal_error;
+                       err = ext4_handle_dirty_dx_node(handle, dir,
+                                                       frame->bh);
+-                      if (err)
++                      if (restart || err)
+                               goto journal_error;
+               } else {
+                       struct dx_root *dxroot;
diff --git a/queue-5.13/media-rtl28xxu-fix-zero-length-control-request.patch b/queue-5.13/media-rtl28xxu-fix-zero-length-control-request.patch
new file mode 100644 (file)
index 0000000..24e2a64
--- /dev/null
@@ -0,0 +1,58 @@
+From 76f22c93b209c811bd489950f17f8839adb31901 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Wed, 23 Jun 2021 10:45:21 +0200
+Subject: media: rtl28xxu: fix zero-length control request
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 76f22c93b209c811bd489950f17f8839adb31901 upstream.
+
+The direction of the pipe argument must match the request-type direction
+bit or control requests may fail depending on the host-controller-driver
+implementation.
+
+Control transfers without a data stage are treated as OUT requests by
+the USB stack and should be using usb_sndctrlpipe(). Failing to do so
+will now trigger a warning.
+
+The driver uses a zero-length i2c-read request for type detection so
+update the control-request code to use usb_sndctrlpipe() in this case.
+
+Note that actually trying to read the i2c register in question does not
+work as the register might not exist (e.g. depending on the demodulator)
+as reported by Eero Lehtinen <debiangamer2@gmail.com>.
+
+Reported-by: syzbot+faf11bbadc5a372564da@syzkaller.appspotmail.com
+Reported-by: Eero Lehtinen <debiangamer2@gmail.com>
+Tested-by: Eero Lehtinen <debiangamer2@gmail.com>
+Fixes: d0f232e823af ("[media] rtl28xxu: add heuristic to detect chip type")
+Cc: stable@vger.kernel.org      # 4.0
+Cc: Antti Palosaari <crope@iki.fi>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/usb/dvb-usb-v2/rtl28xxu.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
++++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+@@ -37,7 +37,16 @@ static int rtl28xxu_ctrl_msg(struct dvb_
+       } else {
+               /* read */
+               requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+-              pipe = usb_rcvctrlpipe(d->udev, 0);
++
++              /*
++               * Zero-length transfers must use usb_sndctrlpipe() and
++               * rtl28xxu_identify_state() uses a zero-length i2c read
++               * command to determine the chip type.
++               */
++              if (req->size)
++                      pipe = usb_rcvctrlpipe(d->udev, 0);
++              else
++                      pipe = usb_sndctrlpipe(d->udev, 0);
+       }
+       ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
diff --git a/queue-5.13/pipe-increase-minimum-default-pipe-size-to-2-pages.patch b/queue-5.13/pipe-increase-minimum-default-pipe-size-to-2-pages.patch
new file mode 100644 (file)
index 0000000..080e6a4
--- /dev/null
@@ -0,0 +1,75 @@
+From 46c4c9d1beb7f5b4cec4dd90e7728720583ee348 Mon Sep 17 00:00:00 2001
+From: "Alex Xu (Hello71)" <alex_y_xu@yahoo.ca>
+Date: Thu, 5 Aug 2021 10:40:47 -0400
+Subject: pipe: increase minimum default pipe size to 2 pages
+
+From: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
+
+commit 46c4c9d1beb7f5b4cec4dd90e7728720583ee348 upstream.
+
+This program always prints 4096 and hangs before the patch, and always
+prints 8192 and exits successfully after:
+
+  int main()
+  {
+      int pipefd[2];
+      for (int i = 0; i < 1025; i++)
+          if (pipe(pipefd) == -1)
+              return 1;
+      size_t bufsz = fcntl(pipefd[1], F_GETPIPE_SZ);
+      printf("%zd\n", bufsz);
+      char *buf = calloc(bufsz, 1);
+      write(pipefd[1], buf, bufsz);
+      read(pipefd[0], buf, bufsz-1);
+      write(pipefd[1], buf, 1);
+  }
+
+Note that you may need to increase your RLIMIT_NOFILE before running the
+program.
+
+Fixes: 759c01142a ("pipe: limit the per-user amount of pages allocated in pipes")
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/lkml/1628086770.5rn8p04n6j.none@localhost/
+Link: https://lore.kernel.org/lkml/1628127094.lxxn016tj7.none@localhost/
+Signed-off-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/pipe.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -32,6 +32,21 @@
+ #include "internal.h"
+ /*
++ * New pipe buffers will be restricted to this size while the user is exceeding
++ * their pipe buffer quota. The general pipe use case needs at least two
++ * buffers: one for data yet to be read, and one for new data. If this is less
++ * than two, then a write to a non-empty pipe may block even if the pipe is not
++ * full. This can occur with GNU make jobserver or similar uses of pipes as
++ * semaphores: multiple processes may be waiting to write tokens back to the
++ * pipe before reading tokens: https://lore.kernel.org/lkml/1628086770.5rn8p04n6j.none@localhost/.
++ *
++ * Users can reduce their pipe buffers with F_SETPIPE_SZ below this at their
++ * own risk, namely: pipe writes to non-full pipes may block until the pipe is
++ * emptied.
++ */
++#define PIPE_MIN_DEF_BUFFERS 2
++
++/*
+  * The max size that a non-root user is allowed to grow the pipe. Can
+  * be set by root in /proc/sys/fs/pipe-max-size
+  */
+@@ -781,8 +796,8 @@ struct pipe_inode_info *alloc_pipe_info(
+       user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
+       if (too_many_pipe_buffers_soft(user_bufs) && pipe_is_unprivileged_user()) {
+-              user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
+-              pipe_bufs = 1;
++              user_bufs = account_pipe_buffers(user, pipe_bufs, PIPE_MIN_DEF_BUFFERS);
++              pipe_bufs = PIPE_MIN_DEF_BUFFERS;
+       }
+       if (too_many_pipe_buffers_hard(user_bufs) && pipe_is_unprivileged_user())
index f4129115081bf43c73d00de6919480b6c62c190e..bb3ad0ffff3c2fab33c215db8dc88c1fac9b530f 100644 (file)
@@ -113,3 +113,10 @@ optee-fix-memory-leak-when-failing-to-register-shm-pages.patch
 optee-refuse-to-load-the-driver-under-the-kdump-kernel.patch
 optee-fix-tee-out-of-memory-failure-seen-during-kexec-reboot.patch
 tpm_ftpm_tee-free-and-unregister-tee-shared-memory-during-kexec.patch
+staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch
+staging-rtl8712-get-rid-of-flush_scheduled_work.patch
+staging-rtl8712-error-handling-refactoring.patch
+drivers-core-fix-oops-when-driver-probe-fails.patch
+media-rtl28xxu-fix-zero-length-control-request.patch
+pipe-increase-minimum-default-pipe-size-to-2-pages.patch
+ext4-fix-potential-htree-corruption-when-growing-large_dir-directories.patch
diff --git a/queue-5.13/staging-rtl8712-error-handling-refactoring.patch b/queue-5.13/staging-rtl8712-error-handling-refactoring.patch
new file mode 100644 (file)
index 0000000..08c137c
--- /dev/null
@@ -0,0 +1,139 @@
+From e9e6aa51b2735d83a67d9fa0119cf11abef80d99 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Wed, 21 Jul 2021 22:34:47 +0300
+Subject: staging: rtl8712: error handling refactoring
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit e9e6aa51b2735d83a67d9fa0119cf11abef80d99 upstream.
+
+There was strange error handling logic in case of fw load failure. For
+some reason fw loader callback was doing clean up stuff when fw is not
+available. I don't see any reason behind doing this. Since this driver
+doesn't have EEPROM firmware let's just disconnect it in case of fw load
+failure. Doing clean up stuff in 2 different place which can run
+concurently is not good idea and syzbot found 2 bugs related to this
+strange approach.
+
+So, in this pacth I deleted all clean up code from fw callback and made
+a call to device_release_driver() under device_lock(parent) in case of fw
+load failure. This approach is more generic and it defend driver from UAF
+bugs, since all clean up code is moved to one place.
+
+Fixes: e02a3b945816 ("staging: rtl8712: fix memory leak in rtl871x_load_fw_cb")
+Fixes: 8c213fa59199 ("staging: r8712u: Use asynchronous firmware loading")
+Cc: stable <stable@vger.kernel.org>
+Reported-and-tested-by: syzbot+5872a520e0ce0a7c7230@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+cc699626e48a6ebaf295@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Link: https://lore.kernel.org/r/d49ecc56e97c4df181d7bd4d240b031f315eacc3.1626895918.git.paskripkin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8712/hal_init.c |   30 +++++++++++++++--------
+ drivers/staging/rtl8712/usb_intf.c |   48 ++++++++++++++++---------------------
+ 2 files changed, 41 insertions(+), 37 deletions(-)
+
+--- a/drivers/staging/rtl8712/hal_init.c
++++ b/drivers/staging/rtl8712/hal_init.c
+@@ -29,21 +29,31 @@
+ #define FWBUFF_ALIGN_SZ 512
+ #define MAX_DUMP_FWSZ (48 * 1024)
++static void rtl871x_load_fw_fail(struct _adapter *adapter)
++{
++      struct usb_device *udev = adapter->dvobjpriv.pusbdev;
++      struct device *dev = &udev->dev;
++      struct device *parent = dev->parent;
++
++      complete(&adapter->rtl8712_fw_ready);
++
++      dev_err(&udev->dev, "r8712u: Firmware request failed\n");
++
++      if (parent)
++              device_lock(parent);
++
++      device_release_driver(dev);
++
++      if (parent)
++              device_unlock(parent);
++}
++
+ static void rtl871x_load_fw_cb(const struct firmware *firmware, void *context)
+ {
+       struct _adapter *adapter = context;
+       if (!firmware) {
+-              struct usb_device *udev = adapter->dvobjpriv.pusbdev;
+-              struct usb_interface *usb_intf = adapter->pusb_intf;
+-
+-              dev_err(&udev->dev, "r8712u: Firmware request failed\n");
+-              usb_put_dev(udev);
+-              usb_set_intfdata(usb_intf, NULL);
+-              r8712_free_drv_sw(adapter);
+-              adapter->dvobj_deinit(adapter);
+-              complete(&adapter->rtl8712_fw_ready);
+-              free_netdev(adapter->pnetdev);
++              rtl871x_load_fw_fail(adapter);
+               return;
+       }
+       adapter->fw = firmware;
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -594,36 +594,30 @@ static void r871xu_dev_remove(struct usb
+ {
+       struct net_device *pnetdev = usb_get_intfdata(pusb_intf);
+       struct usb_device *udev = interface_to_usbdev(pusb_intf);
++      struct _adapter *padapter = netdev_priv(pnetdev);
+-      if (pnetdev) {
+-              struct _adapter *padapter = netdev_priv(pnetdev);
++      /* never exit with a firmware callback pending */
++      wait_for_completion(&padapter->rtl8712_fw_ready);
++      usb_set_intfdata(pusb_intf, NULL);
++      release_firmware(padapter->fw);
++      if (drvpriv.drv_registered)
++              padapter->surprise_removed = true;
++      if (pnetdev->reg_state != NETREG_UNINITIALIZED)
++              unregister_netdev(pnetdev); /* will call netdev_close() */
++      r8712_flush_rwctrl_works(padapter);
++      r8712_flush_led_works(padapter);
++      udelay(1);
++      /* Stop driver mlme relation timer */
++      r8712_stop_drv_timers(padapter);
++      r871x_dev_unload(padapter);
++      r8712_free_drv_sw(padapter);
++      free_netdev(pnetdev);
+-              /* never exit with a firmware callback pending */
+-              wait_for_completion(&padapter->rtl8712_fw_ready);
+-              pnetdev = usb_get_intfdata(pusb_intf);
+-              usb_set_intfdata(pusb_intf, NULL);
+-              if (!pnetdev)
+-                      goto firmware_load_fail;
+-              release_firmware(padapter->fw);
+-              if (drvpriv.drv_registered)
+-                      padapter->surprise_removed = true;
+-              if (pnetdev->reg_state != NETREG_UNINITIALIZED)
+-                      unregister_netdev(pnetdev); /* will call netdev_close() */
+-              r8712_flush_rwctrl_works(padapter);
+-              r8712_flush_led_works(padapter);
+-              udelay(1);
+-              /* Stop driver mlme relation timer */
+-              r8712_stop_drv_timers(padapter);
+-              r871x_dev_unload(padapter);
+-              r8712_free_drv_sw(padapter);
+-              free_netdev(pnetdev);
++      /* decrease the reference count of the usb device structure
++       * when disconnect
++       */
++      usb_put_dev(udev);
+-              /* decrease the reference count of the usb device structure
+-               * when disconnect
+-               */
+-              usb_put_dev(udev);
+-      }
+-firmware_load_fail:
+       /* If we didn't unplug usb dongle and remove/insert module, driver
+        * fails on sitesurvey for the first time when device is up.
+        * Reset usb port for sitesurvey fail issue.
diff --git a/queue-5.13/staging-rtl8712-get-rid-of-flush_scheduled_work.patch b/queue-5.13/staging-rtl8712-get-rid-of-flush_scheduled_work.patch
new file mode 100644 (file)
index 0000000..4dd6831
--- /dev/null
@@ -0,0 +1,89 @@
+From 9be550ee43919b070bcd77f9228bdbbbc073245b Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Wed, 21 Jul 2021 22:34:36 +0300
+Subject: staging: rtl8712: get rid of flush_scheduled_work
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit 9be550ee43919b070bcd77f9228bdbbbc073245b upstream.
+
+This patch is preparation for following patch for error handling
+refactoring.
+
+flush_scheduled_work() takes (wq_completion)events lock and
+it can lead to deadlock when r871xu_dev_remove() is called from workqueue.
+To avoid deadlock sutiation we can change flush_scheduled_work() call to
+flush_work() call for all possibly scheduled works in this driver,
+since next patch adds device_release_driver() in case of fw load failure.
+
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/6e028b4c457eeb7156c76c6ea3cdb3cb0207c7e1.1626895918.git.paskripkin@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8712/rtl8712_led.c     |    8 ++++++++
+ drivers/staging/rtl8712/rtl871x_led.h     |    1 +
+ drivers/staging/rtl8712/rtl871x_pwrctrl.c |    8 ++++++++
+ drivers/staging/rtl8712/rtl871x_pwrctrl.h |    1 +
+ drivers/staging/rtl8712/usb_intf.c        |    3 ++-
+ 5 files changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/rtl8712/rtl8712_led.c
++++ b/drivers/staging/rtl8712/rtl8712_led.c
+@@ -1820,3 +1820,11 @@ void LedControl871x(struct _adapter *pad
+               break;
+       }
+ }
++
++void r8712_flush_led_works(struct _adapter *padapter)
++{
++      struct led_priv *pledpriv = &padapter->ledpriv;
++
++      flush_work(&pledpriv->SwLed0.BlinkWorkItem);
++      flush_work(&pledpriv->SwLed1.BlinkWorkItem);
++}
+--- a/drivers/staging/rtl8712/rtl871x_led.h
++++ b/drivers/staging/rtl8712/rtl871x_led.h
+@@ -112,6 +112,7 @@ struct led_priv {
+ void r8712_InitSwLeds(struct _adapter *padapter);
+ void r8712_DeInitSwLeds(struct _adapter *padapter);
+ void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction);
++void r8712_flush_led_works(struct _adapter *padapter);
+ #endif
+--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
++++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+@@ -224,3 +224,11 @@ void r8712_unregister_cmd_alive(struct _
+       }
+       mutex_unlock(&pwrctrl->mutex_lock);
+ }
++
++void r8712_flush_rwctrl_works(struct _adapter *padapter)
++{
++      struct pwrctrl_priv *pwrctrl = &padapter->pwrctrlpriv;
++
++      flush_work(&pwrctrl->SetPSModeWorkItem);
++      flush_work(&pwrctrl->rpwm_workitem);
++}
+--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
++++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+@@ -108,5 +108,6 @@ void r8712_cpwm_int_hdl(struct _adapter
+ void r8712_set_ps_mode(struct _adapter *padapter, uint ps_mode,
+                       uint smart_ps);
+ void r8712_set_rpwm(struct _adapter *padapter, u8 val8);
++void r8712_flush_rwctrl_works(struct _adapter *padapter);
+ #endif  /* __RTL871X_PWRCTRL_H_ */
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -609,7 +609,8 @@ static void r871xu_dev_remove(struct usb
+                       padapter->surprise_removed = true;
+               if (pnetdev->reg_state != NETREG_UNINITIALIZED)
+                       unregister_netdev(pnetdev); /* will call netdev_close() */
+-              flush_scheduled_work();
++              r8712_flush_rwctrl_works(padapter);
++              r8712_flush_led_works(padapter);
+               udelay(1);
+               /* Stop driver mlme relation timer */
+               r8712_stop_drv_timers(padapter);
diff --git a/queue-5.13/staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch b/queue-5.13/staging-rtl8723bs-fix-a-resource-leak-in-sd_int_dpc.patch
new file mode 100644 (file)
index 0000000..761436a
--- /dev/null
@@ -0,0 +1,33 @@
+From 990e4ad3ddcb72216caeddd6e62c5f45a21e8121 Mon Sep 17 00:00:00 2001
+From: Xiangyang Zhang <xyz.sun.ok@gmail.com>
+Date: Mon, 28 Jun 2021 23:22:39 +0800
+Subject: staging: rtl8723bs: Fix a resource leak in sd_int_dpc
+
+From: Xiangyang Zhang <xyz.sun.ok@gmail.com>
+
+commit 990e4ad3ddcb72216caeddd6e62c5f45a21e8121 upstream.
+
+The "c2h_evt" variable is not freed when function call
+"c2h_evt_read_88xx" failed
+
+Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Xiangyang Zhang <xyz.sun.ok@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210628152239.5475-1-xyz.sun.ok@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/rtl8723bs/hal/sdio_ops.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c
++++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c
+@@ -921,6 +921,8 @@ void sd_int_dpc(struct adapter *adapter)
+                               } else {
+                                       rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
+                               }
++                      } else {
++                              kfree(c2h_evt);
+                       }
+               } else {
+                       /* Error handling for malloc fail */