]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 15:08:21 +0000 (17:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 15:08:21 +0000 (17:08 +0200)
added patches:
memstick-fix-deadlock-by-moving-removing-flag-earlier.patch
squashfs-fix-memory-leak-in-squashfs_fill_super.patch

queue-5.4/memstick-fix-deadlock-by-moving-removing-flag-earlier.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/squashfs-fix-memory-leak-in-squashfs_fill_super.patch [new file with mode: 0644]

diff --git a/queue-5.4/memstick-fix-deadlock-by-moving-removing-flag-earlier.patch b/queue-5.4/memstick-fix-deadlock-by-moving-removing-flag-earlier.patch
new file mode 100644 (file)
index 0000000..34574db
--- /dev/null
@@ -0,0 +1,80 @@
+From 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa Mon Sep 17 00:00:00 2001
+From: Jiayi Li <lijiayi@kylinos.cn>
+Date: Mon, 4 Aug 2025 09:36:04 +0800
+Subject: memstick: Fix deadlock by moving removing flag earlier
+
+From: Jiayi Li <lijiayi@kylinos.cn>
+
+commit 99d7ab8db9d8230b243f5ed20ba0229e54cc0dfa upstream.
+
+The existing memstick core patch: commit 62c59a8786e6 ("memstick: Skip
+allocating card when removing host") sets host->removing in
+memstick_remove_host(),but still exists a critical time window where
+memstick_check can run after host->eject is set but before removing is set.
+
+In the rtsx_usb_ms driver, the problematic sequence is:
+
+rtsx_usb_ms_drv_remove:          memstick_check:
+  host->eject = true
+  cancel_work_sync(handle_req)     if(!host->removing)
+  ...                              memstick_alloc_card()
+                                     memstick_set_rw_addr()
+                                       memstick_new_req()
+                                         rtsx_usb_ms_request()
+                                           if(!host->eject)
+                                           skip schedule_work
+                                       wait_for_completion()
+  memstick_remove_host:                [blocks indefinitely]
+    host->removing = true
+    flush_workqueue()
+    [block]
+
+1. rtsx_usb_ms_drv_remove sets host->eject = true
+2. cancel_work_sync(&host->handle_req) runs
+3. memstick_check work may be executed here <-- danger window
+4. memstick_remove_host sets removing = 1
+
+During this window (step 3), memstick_check calls memstick_alloc_card,
+which may indefinitely waiting for mrq_complete completion that will
+never occur because rtsx_usb_ms_request sees eject=true and skips
+scheduling work, memstick_set_rw_addr waits forever for completion.
+
+This causes a deadlock when memstick_remove_host tries to flush_workqueue,
+waiting for memstick_check to complete, while memstick_check is blocked
+waiting for mrq_complete completion.
+
+Fix this by setting removing=true at the start of rtsx_usb_ms_drv_remove,
+before any work cancellation. This ensures memstick_check will see the
+removing flag immediately and exit early, avoiding the deadlock.
+
+Fixes: 62c59a8786e6 ("memstick: Skip allocating card when removing host")
+Signed-off-by: Jiayi Li <lijiayi@kylinos.cn>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250804013604.1311218-1-lijiayi@kylinos.cn
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/memstick/core/memstick.c    |    1 -
+ drivers/memstick/host/rtsx_usb_ms.c |    1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/memstick/core/memstick.c
++++ b/drivers/memstick/core/memstick.c
+@@ -550,7 +550,6 @@ EXPORT_SYMBOL(memstick_add_host);
+  */
+ void memstick_remove_host(struct memstick_host *host)
+ {
+-      host->removing = 1;
+       flush_workqueue(workqueue);
+       mutex_lock(&host->lock);
+       if (host->card)
+--- a/drivers/memstick/host/rtsx_usb_ms.c
++++ b/drivers/memstick/host/rtsx_usb_ms.c
+@@ -812,6 +812,7 @@ static int rtsx_usb_ms_drv_remove(struct
+       int err;
+       host->eject = true;
++      msh->removing = true;
+       cancel_work_sync(&host->handle_req);
+       cancel_delayed_work_sync(&host->poll_card);
index 8e4f01ab6141b1e0230e68de4dca5cae80fa7e40..50fb146e932f6aeeab8c2adf7f46865ff36e6d0d 100644 (file)
@@ -305,3 +305,5 @@ media-imx-fix-a-potential-memory-leak-in-imx_media_csc_scaler_device_init.patch
 media-usbtv-lock-resolution-while-streaming.patch
 media-ov2659-fix-memory-leaks-in-ov2659_probe.patch
 media-venus-add-a-check-for-packet-size-after-reading-from-shared-memory.patch
+memstick-fix-deadlock-by-moving-removing-flag-earlier.patch
+squashfs-fix-memory-leak-in-squashfs_fill_super.patch
diff --git a/queue-5.4/squashfs-fix-memory-leak-in-squashfs_fill_super.patch b/queue-5.4/squashfs-fix-memory-leak-in-squashfs_fill_super.patch
new file mode 100644 (file)
index 0000000..80880ad
--- /dev/null
@@ -0,0 +1,60 @@
+From b64700d41bdc4e9f82f1346c15a3678ebb91a89c Mon Sep 17 00:00:00 2001
+From: Phillip Lougher <phillip@squashfs.org.uk>
+Date: Mon, 11 Aug 2025 23:37:40 +0100
+Subject: squashfs: fix memory leak in squashfs_fill_super
+
+From: Phillip Lougher <phillip@squashfs.org.uk>
+
+commit b64700d41bdc4e9f82f1346c15a3678ebb91a89c upstream.
+
+If sb_min_blocksize returns 0, squashfs_fill_super exits without freeing
+allocated memory (sb->s_fs_info).
+
+Fix this by moving the call to sb_min_blocksize to before memory is
+allocated.
+
+Link: https://lkml.kernel.org/r/20250811223740.110392-1-phillip@squashfs.org.uk
+Fixes: 734aa85390ea ("Squashfs: check return result of sb_min_blocksize")
+Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
+Reported-by: Scott GUO <scottzhguo@tencent.com>
+Closes: https://lore.kernel.org/all/20250811061921.3807353-1-scott_gzh@163.com
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/squashfs/super.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/fs/squashfs/super.c
++++ b/fs/squashfs/super.c
+@@ -74,10 +74,15 @@ static int squashfs_fill_super(struct su
+       unsigned short flags;
+       unsigned int fragments;
+       u64 lookup_table_start, xattr_id_table_start, next_table;
+-      int err;
++      int err, devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
+       TRACE("Entered squashfs_fill_superblock\n");
++      if (!devblksize) {
++              errorf(fc, "squashfs: unable to set blocksize\n");
++              return -EINVAL;
++      }
++
+       sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
+       if (sb->s_fs_info == NULL) {
+               ERROR("Failed to allocate squashfs_sb_info\n");
+@@ -85,12 +90,7 @@ static int squashfs_fill_super(struct su
+       }
+       msblk = sb->s_fs_info;
+-      msblk->devblksize = sb_min_blocksize(sb, SQUASHFS_DEVBLK_SIZE);
+-      if (!msblk->devblksize) {
+-              errorf(fc, "squashfs: unable to set blocksize\n");
+-              return -EINVAL;
+-      }
+-
++      msblk->devblksize = devblksize;
+       msblk->devblksize_log2 = ffz(~msblk->devblksize);
+       mutex_init(&msblk->meta_index_mutex);