--- /dev/null
+From 331cd9461412e103d07595a10289de90004ac890 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Tue, 23 Aug 2022 12:45:42 +0100
+Subject: btrfs: fix race between quota enable and quota rescan ioctl
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 331cd9461412e103d07595a10289de90004ac890 upstream.
+
+When enabling quotas, at btrfs_quota_enable(), after committing the
+transaction, we change fs_info->quota_root to point to the quota root we
+created and set BTRFS_FS_QUOTA_ENABLED at fs_info->flags. Then we try
+to start the qgroup rescan worker, first by initializing it with a call
+to qgroup_rescan_init() - however if that fails we end up freeing the
+quota root but we leave fs_info->quota_root still pointing to it, this
+can later result in a use-after-free somewhere else.
+
+We have previously set the flags BTRFS_FS_QUOTA_ENABLED and
+BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with -EINPROGRESS at
+btrfs_quota_enable(), which is possible if someone already called the
+quota rescan ioctl, and therefore started the rescan worker.
+
+So fix this by ignoring an -EINPROGRESS and asserting we can't get any
+other error.
+
+Reported-by: Ye Bin <yebin10@huawei.com>
+Link: https://lore.kernel.org/linux-btrfs/20220823015931.421355-1-yebin10@huawei.com/
+CC: stable@vger.kernel.org # 4.19+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/qgroup.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1035,6 +1035,21 @@ out_add_root:
+ fs_info->qgroup_rescan_running = true;
+ btrfs_queue_work(fs_info->qgroup_rescan_workers,
+ &fs_info->qgroup_rescan_work);
++ } else {
++ /*
++ * We have set both BTRFS_FS_QUOTA_ENABLED and
++ * BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with
++ * -EINPROGRESS. That can happen because someone started the
++ * rescan worker by calling quota rescan ioctl before we
++ * attempted to initialize the rescan worker. Failure due to
++ * quotas disabled in the meanwhile is not possible, because
++ * we are holding a write lock on fs_info->subvol_sem, which
++ * is also acquired when disabling quotas.
++ * Ignore such error, and any other error would need to undo
++ * everything we did in the transaction we just committed.
++ */
++ ASSERT(ret == -EINPROGRESS);
++ ret = 0;
+ }
+
+ out_free_path:
--- /dev/null
+From 5610bcfe8693c02e2e4c8b31427f1bdbdecc839c Mon Sep 17 00:00:00 2001
+From: Hyunwoo Kim <imv4bel@gmail.com>
+Date: Sun, 25 Sep 2022 06:32:43 -0700
+Subject: fbdev: smscufx: Fix use-after-free in ufx_ops_open()
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+commit 5610bcfe8693c02e2e4c8b31427f1bdbdecc839c upstream.
+
+A race condition may occur if the user physically removes the
+USB device while calling open() for this device node.
+
+This is a race condition between the ufx_ops_open() function and
+the ufx_usb_disconnect() function, which may eventually result in UAF.
+
+So, add a mutex to the ufx_ops_open() and ufx_usb_disconnect() functions
+to avoid race contidion of krefs.
+
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/smscufx.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -140,6 +140,8 @@ static int ufx_submit_urb(struct ufx_dat
+ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size);
+ static void ufx_free_urb_list(struct ufx_data *dev);
+
++static DEFINE_MUTEX(disconnect_mutex);
++
+ /* reads a control register */
+ static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data)
+ {
+@@ -1073,9 +1075,13 @@ static int ufx_ops_open(struct fb_info *
+ if (user == 0 && !console)
+ return -EBUSY;
+
++ mutex_lock(&disconnect_mutex);
++
+ /* If the USB device is gone, we don't accept new opens */
+- if (dev->virtualized)
++ if (dev->virtualized) {
++ mutex_unlock(&disconnect_mutex);
+ return -ENODEV;
++ }
+
+ dev->fb_count++;
+
+@@ -1099,6 +1105,8 @@ static int ufx_ops_open(struct fb_info *
+ pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d",
+ info->node, user, info, dev->fb_count);
+
++ mutex_unlock(&disconnect_mutex);
++
+ return 0;
+ }
+
+@@ -1746,6 +1754,8 @@ static void ufx_usb_disconnect(struct us
+ {
+ struct ufx_data *dev;
+
++ mutex_lock(&disconnect_mutex);
++
+ dev = usb_get_intfdata(interface);
+
+ pr_debug("USB disconnect starting\n");
+@@ -1766,6 +1776,8 @@ static void ufx_usb_disconnect(struct us
+ kref_put(&dev->kref, ufx_free);
+
+ /* consider ufx_data freed */
++
++ mutex_unlock(&disconnect_mutex);
+ }
+
+ static struct usb_driver ufx_driver = {