]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches master
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Dec 2025 16:03:06 +0000 (17:03 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Dec 2025 16:03:06 +0000 (17:03 +0100)
added patches:
block-freeze-queue-when-updating-zone-resources.patch
fuse-fix-io-uring-list-corruption-for-terminated-non-committed-requests.patch
fuse-fix-readahead-reclaim-deadlock.patch
fuse-missing-copy_finish-in-fuse-over-io-uring-argument-copies.patch
iommu-mediatek-fix-use-after-free-on-probe-deferral.patch

queue-6.18/block-freeze-queue-when-updating-zone-resources.patch [new file with mode: 0644]
queue-6.18/fuse-fix-io-uring-list-corruption-for-terminated-non-committed-requests.patch [new file with mode: 0644]
queue-6.18/fuse-fix-readahead-reclaim-deadlock.patch [new file with mode: 0644]
queue-6.18/fuse-missing-copy_finish-in-fuse-over-io-uring-argument-copies.patch [new file with mode: 0644]
queue-6.18/iommu-mediatek-fix-use-after-free-on-probe-deferral.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/block-freeze-queue-when-updating-zone-resources.patch b/queue-6.18/block-freeze-queue-when-updating-zone-resources.patch
new file mode 100644 (file)
index 0000000..9446d88
--- /dev/null
@@ -0,0 +1,124 @@
+From bba4322e3f303b2d656e748be758320b567f046f Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 5 Nov 2025 06:22:36 +0900
+Subject: block: freeze queue when updating zone resources
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit bba4322e3f303b2d656e748be758320b567f046f upstream.
+
+Modify disk_update_zone_resources() to freeze the device queue before
+updating the number of zones, zone capacity and other zone related
+resources. The locking order resulting from the call to
+queue_limits_commit_update_frozen() is preserved, that is, the queue
+limits lock is first taken by calling queue_limits_start_update() before
+freezing the queue, and the queue is unfrozen after executing
+queue_limits_commit_update(), which replaces the call to
+queue_limits_commit_update_frozen().
+
+This change ensures that there are no in-flights I/Os when the zone
+resources are updated due to a zone revalidation. In case of error when
+the limits are applied, directly call disk_free_zone_resources() from
+disk_update_zone_resources() while the disk queue is still frozen to
+avoid needing to freeze & unfreeze the queue again in
+blk_revalidate_disk_zones(), thus simplifying that function code a
+little.
+
+Fixes: 0b83c86b444a ("block: Prevent potential deadlock in blk_revalidate_disk_zones()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/blk-zoned.c |   42 ++++++++++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 18 deletions(-)
+
+--- a/block/blk-zoned.c
++++ b/block/blk-zoned.c
+@@ -1516,8 +1516,13 @@ static int disk_update_zone_resources(st
+ {
+       struct request_queue *q = disk->queue;
+       unsigned int nr_seq_zones, nr_conv_zones;
+-      unsigned int pool_size;
++      unsigned int pool_size, memflags;
+       struct queue_limits lim;
++      int ret = 0;
++
++      lim = queue_limits_start_update(q);
++
++      memflags = blk_mq_freeze_queue(q);
+       disk->nr_zones = args->nr_zones;
+       disk->zone_capacity = args->zone_capacity;
+@@ -1527,11 +1532,10 @@ static int disk_update_zone_resources(st
+       if (nr_conv_zones >= disk->nr_zones) {
+               pr_warn("%s: Invalid number of conventional zones %u / %u\n",
+                       disk->disk_name, nr_conv_zones, disk->nr_zones);
+-              return -ENODEV;
++              ret = -ENODEV;
++              goto unfreeze;
+       }
+-      lim = queue_limits_start_update(q);
+-
+       /*
+        * Some devices can advertize zone resource limits that are larger than
+        * the number of sequential zones of the zoned block device, e.g. a
+@@ -1568,7 +1572,15 @@ static int disk_update_zone_resources(st
+       }
+ commit:
+-      return queue_limits_commit_update_frozen(q, &lim);
++      ret = queue_limits_commit_update(q, &lim);
++
++unfreeze:
++      if (ret)
++              disk_free_zone_resources(disk);
++
++      blk_mq_unfreeze_queue(q, memflags);
++
++      return ret;
+ }
+ static int blk_revalidate_conv_zone(struct blk_zone *zone, unsigned int idx,
+@@ -1733,7 +1745,7 @@ int blk_revalidate_disk_zones(struct gen
+       sector_t zone_sectors = q->limits.chunk_sectors;
+       sector_t capacity = get_capacity(disk);
+       struct blk_revalidate_zone_args args = { };
+-      unsigned int noio_flag;
++      unsigned int memflags, noio_flag;
+       int ret = -ENOMEM;
+       if (WARN_ON_ONCE(!blk_queue_is_zoned(q)))
+@@ -1783,20 +1795,14 @@ int blk_revalidate_disk_zones(struct gen
+               ret = -ENODEV;
+       }
+-      /*
+-       * Set the new disk zone parameters only once the queue is frozen and
+-       * all I/Os are completed.
+-       */
+       if (ret > 0)
+-              ret = disk_update_zone_resources(disk, &args);
+-      else
+-              pr_warn("%s: failed to revalidate zones\n", disk->disk_name);
+-      if (ret) {
+-              unsigned int memflags = blk_mq_freeze_queue(q);
++              return disk_update_zone_resources(disk, &args);
+-              disk_free_zone_resources(disk);
+-              blk_mq_unfreeze_queue(q, memflags);
+-      }
++      pr_warn("%s: failed to revalidate zones\n", disk->disk_name);
++
++      memflags = blk_mq_freeze_queue(q);
++      disk_free_zone_resources(disk);
++      blk_mq_unfreeze_queue(q, memflags);
+       return ret;
+ }
diff --git a/queue-6.18/fuse-fix-io-uring-list-corruption-for-terminated-non-committed-requests.patch b/queue-6.18/fuse-fix-io-uring-list-corruption-for-terminated-non-committed-requests.patch
new file mode 100644 (file)
index 0000000..b86cc0a
--- /dev/null
@@ -0,0 +1,41 @@
+From 95c39eef7c2b666026c69ab5b30471da94ea2874 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Tue, 25 Nov 2025 10:13:47 -0800
+Subject: fuse: fix io-uring list corruption for terminated non-committed requests
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit 95c39eef7c2b666026c69ab5b30471da94ea2874 upstream.
+
+When a request is terminated before it has been committed, the request
+is not removed from the queue's list. This leaves a dangling list entry
+that leads to list corruption and use-after-free issues.
+
+Remove the request from the queue's list for terminated non-committed
+requests.
+
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Fixes: c090c8abae4b ("fuse: Add io-uring sqe commit and fetch support")
+Cc: stable@vger.kernel.org
+Reviewed-by: Bernd Schubert <bschubert@ddn.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/dev_uring.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
+index 0066c9c0a5d5..7760fe4e1f9e 100644
+--- a/fs/fuse/dev_uring.c
++++ b/fs/fuse/dev_uring.c
+@@ -86,6 +86,7 @@ static void fuse_uring_req_end(struct fuse_ring_ent *ent, struct fuse_req *req,
+       lockdep_assert_not_held(&queue->lock);
+       spin_lock(&queue->lock);
+       ent->fuse_req = NULL;
++      list_del_init(&req->list);
+       if (test_bit(FR_BACKGROUND, &req->flags)) {
+               queue->active_background--;
+               spin_lock(&fc->bg_lock);
+-- 
+2.52.0
+
diff --git a/queue-6.18/fuse-fix-readahead-reclaim-deadlock.patch b/queue-6.18/fuse-fix-readahead-reclaim-deadlock.patch
new file mode 100644 (file)
index 0000000..ea8fca2
--- /dev/null
@@ -0,0 +1,116 @@
+From bd5603eaae0aabf527bfb3ce1bb07e979ce5bd50 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Fri, 10 Oct 2025 15:07:38 -0700
+Subject: fuse: fix readahead reclaim deadlock
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit bd5603eaae0aabf527bfb3ce1bb07e979ce5bd50 upstream.
+
+Commit e26ee4efbc79 ("fuse: allocate ff->release_args only if release is
+needed") skips allocating ff->release_args if the server does not
+implement open. However in doing so, fuse_prepare_release() now skips
+grabbing the reference on the inode, which makes it possible for an
+inode to be evicted from the dcache while there are inflight readahead
+requests. This causes a deadlock if the server triggers reclaim while
+servicing the readahead request and reclaim attempts to evict the inode
+of the file being read ahead. Since the folio is locked during
+readahead, when reclaim evicts the fuse inode and fuse_evict_inode()
+attempts to remove all folios associated with the inode from the page
+cache (truncate_inode_pages_range()), reclaim will block forever waiting
+for the lock since readahead cannot relinquish the lock because it is
+itself blocked in reclaim:
+
+>>> stack_trace(1504735)
+ folio_wait_bit_common (mm/filemap.c:1308:4)
+ folio_lock (./include/linux/pagemap.h:1052:3)
+ truncate_inode_pages_range (mm/truncate.c:336:10)
+ fuse_evict_inode (fs/fuse/inode.c:161:2)
+ evict (fs/inode.c:704:3)
+ dentry_unlink_inode (fs/dcache.c:412:3)
+ __dentry_kill (fs/dcache.c:615:3)
+ shrink_kill (fs/dcache.c:1060:12)
+ shrink_dentry_list (fs/dcache.c:1087:3)
+ prune_dcache_sb (fs/dcache.c:1168:2)
+ super_cache_scan (fs/super.c:221:10)
+ do_shrink_slab (mm/shrinker.c:435:9)
+ shrink_slab (mm/shrinker.c:626:10)
+ shrink_node (mm/vmscan.c:5951:2)
+ shrink_zones (mm/vmscan.c:6195:3)
+ do_try_to_free_pages (mm/vmscan.c:6257:3)
+ do_swap_page (mm/memory.c:4136:11)
+ handle_pte_fault (mm/memory.c:5562:10)
+ handle_mm_fault (mm/memory.c:5870:9)
+ do_user_addr_fault (arch/x86/mm/fault.c:1338:10)
+ handle_page_fault (arch/x86/mm/fault.c:1481:3)
+ exc_page_fault (arch/x86/mm/fault.c:1539:2)
+ asm_exc_page_fault+0x22/0x27
+
+Fix this deadlock by allocating ff->release_args and grabbing the
+reference on the inode when preparing the file for release even if the
+server does not implement open. The inode reference will be dropped when
+the last reference on the fuse file is dropped (see fuse_file_put() ->
+fuse_release_end()).
+
+Fixes: e26ee4efbc79 ("fuse: allocate ff->release_args only if release is needed")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Reported-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/file.c |   26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -110,7 +110,9 @@ static void fuse_file_put(struct fuse_fi
+                       fuse_file_io_release(ff, ra->inode);
+               if (!args) {
+-                      /* Do nothing when server does not implement 'open' */
++                      /* Do nothing when server does not implement 'opendir' */
++              } else if (args->opcode == FUSE_RELEASE && ff->fm->fc->no_open) {
++                      fuse_release_end(ff->fm, args, 0);
+               } else if (sync) {
+                       fuse_simple_request(ff->fm, args);
+                       fuse_release_end(ff->fm, args, 0);
+@@ -131,8 +133,17 @@ struct fuse_file *fuse_file_open(struct
+       struct fuse_file *ff;
+       int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+       bool open = isdir ? !fc->no_opendir : !fc->no_open;
++      bool release = !isdir || open;
+-      ff = fuse_file_alloc(fm, open);
++      /*
++       * ff->args->release_args still needs to be allocated (so we can hold an
++       * inode reference while there are pending inflight file operations when
++       * ->release() is called, see fuse_prepare_release()) even if
++       * fc->no_open is set else it becomes possible for reclaim to deadlock
++       * if while servicing the readahead request the server triggers reclaim
++       * and reclaim evicts the inode of the file being read ahead.
++       */
++      ff = fuse_file_alloc(fm, release);
+       if (!ff)
+               return ERR_PTR(-ENOMEM);
+@@ -152,13 +163,14 @@ struct fuse_file *fuse_file_open(struct
+                       fuse_file_free(ff);
+                       return ERR_PTR(err);
+               } else {
+-                      /* No release needed */
+-                      kfree(ff->args);
+-                      ff->args = NULL;
+-                      if (isdir)
++                      if (isdir) {
++                              /* No release needed */
++                              kfree(ff->args);
++                              ff->args = NULL;
+                               fc->no_opendir = 1;
+-                      else
++                      } else {
+                               fc->no_open = 1;
++                      }
+               }
+       }
diff --git a/queue-6.18/fuse-missing-copy_finish-in-fuse-over-io-uring-argument-copies.patch b/queue-6.18/fuse-missing-copy_finish-in-fuse-over-io-uring-argument-copies.patch
new file mode 100644 (file)
index 0000000..b4b2a54
--- /dev/null
@@ -0,0 +1,69 @@
+From 6e0d7f7f4a43ac8868e98c87ecf48805aa8c24dd Mon Sep 17 00:00:00 2001
+From: Cheng Ding <cding@ddn.com>
+Date: Tue, 21 Oct 2025 22:46:42 +0200
+Subject: fuse: missing copy_finish in fuse-over-io-uring argument copies
+
+From: Cheng Ding <cding@ddn.com>
+
+commit 6e0d7f7f4a43ac8868e98c87ecf48805aa8c24dd upstream.
+
+Fix a possible reference count leak of payload pages during
+fuse argument copies.
+
+[Joanne: simplified error cleanup]
+
+Fixes: c090c8abae4b ("fuse: Add io-uring sqe commit and fetch support")
+Cc: stable@vger.kernel.org # v6.14
+Signed-off-by: Cheng Ding <cding@ddn.com>
+Signed-off-by: Bernd Schubert <bschubert@ddn.com>
+Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/dev.c        |    2 +-
+ fs/fuse/dev_uring.c  |    5 ++++-
+ fs/fuse/fuse_dev_i.h |    1 +
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -846,7 +846,7 @@ void fuse_copy_init(struct fuse_copy_sta
+ }
+ /* Unmap and put previous page of userspace buffer */
+-static void fuse_copy_finish(struct fuse_copy_state *cs)
++void fuse_copy_finish(struct fuse_copy_state *cs)
+ {
+       if (cs->currbuf) {
+               struct pipe_buffer *buf = cs->currbuf;
+--- a/fs/fuse/dev_uring.c
++++ b/fs/fuse/dev_uring.c
+@@ -599,7 +599,9 @@ static int fuse_uring_copy_from_ring(str
+       cs.is_uring = true;
+       cs.req = req;
+-      return fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
++      err = fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
++      fuse_copy_finish(&cs);
++      return err;
+ }
+  /*
+@@ -650,6 +652,7 @@ static int fuse_uring_args_to_ring(struc
+       /* copy the payload */
+       err = fuse_copy_args(&cs, num_args, args->in_pages,
+                            (struct fuse_arg *)in_args, 0);
++      fuse_copy_finish(&cs);
+       if (err) {
+               pr_info_ratelimited("%s fuse_copy_args failed\n", __func__);
+               return err;
+--- a/fs/fuse/fuse_dev_i.h
++++ b/fs/fuse/fuse_dev_i.h
+@@ -62,6 +62,7 @@ void fuse_dev_end_requests(struct list_h
+ void fuse_copy_init(struct fuse_copy_state *cs, bool write,
+                          struct iov_iter *iter);
++void fuse_copy_finish(struct fuse_copy_state *cs);
+ int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs,
+                  unsigned int argpages, struct fuse_arg *args,
+                  int zeroing);
diff --git a/queue-6.18/iommu-mediatek-fix-use-after-free-on-probe-deferral.patch b/queue-6.18/iommu-mediatek-fix-use-after-free-on-probe-deferral.patch
new file mode 100644 (file)
index 0000000..26b9ac9
--- /dev/null
@@ -0,0 +1,91 @@
+From de83d4617f9fe059623e97acf7e1e10d209625b5 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 20 Oct 2025 06:53:10 +0200
+Subject: iommu/mediatek: fix use-after-free on probe deferral
+
+From: Johan Hovold <johan@kernel.org>
+
+commit de83d4617f9fe059623e97acf7e1e10d209625b5 upstream.
+
+The driver is dropping the references taken to the larb devices during
+probe after successful lookup as well as on errors. This can
+potentially lead to a use-after-free in case a larb device has not yet
+been bound to its driver so that the iommu driver probe defers.
+
+Fix this by keeping the references as expected while the iommu driver is
+bound.
+
+Fixes: 26593928564c ("iommu/mediatek: Add error path for loop of mm_dts_parse")
+Cc: stable@vger.kernel.org
+Cc: Yong Wu <yong.wu@mediatek.com>
+Acked-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Yong Wu <yong.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/mtk_iommu.c |   25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1211,16 +1211,19 @@ static int mtk_iommu_mm_dts_parse(struct
+               }
+               component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
+-              platform_device_put(plarbdev);
+       }
+-      if (!frst_avail_smicomm_node)
+-              return -EINVAL;
++      if (!frst_avail_smicomm_node) {
++              ret = -EINVAL;
++              goto err_larbdev_put;
++      }
+       pcommdev = of_find_device_by_node(frst_avail_smicomm_node);
+       of_node_put(frst_avail_smicomm_node);
+-      if (!pcommdev)
+-              return -ENODEV;
++      if (!pcommdev) {
++              ret = -ENODEV;
++              goto err_larbdev_put;
++      }
+       data->smicomm_dev = &pcommdev->dev;
+       link = device_link_add(data->smicomm_dev, dev,
+@@ -1228,7 +1231,8 @@ static int mtk_iommu_mm_dts_parse(struct
+       platform_device_put(pcommdev);
+       if (!link) {
+               dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto err_larbdev_put;
+       }
+       return 0;
+@@ -1400,8 +1404,12 @@ out_sysfs_remove:
+       iommu_device_sysfs_remove(&data->iommu);
+ out_list_del:
+       list_del(&data->list);
+-      if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
++      if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               device_link_remove(data->smicomm_dev, dev);
++
++              for (i = 0; i < MTK_LARB_NR_MAX; i++)
++                      put_device(data->larb_imu[i].dev);
++      }
+ out_runtime_disable:
+       pm_runtime_disable(dev);
+       return ret;
+@@ -1421,6 +1429,9 @@ static void mtk_iommu_remove(struct plat
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               device_link_remove(data->smicomm_dev, &pdev->dev);
+               component_master_del(&pdev->dev, &mtk_iommu_com_ops);
++
++              for (i = 0; i < MTK_LARB_NR_MAX; i++)
++                      put_device(data->larb_imu[i].dev);
+       }
+       pm_runtime_disable(&pdev->dev);
+       for (i = 0; i < data->plat_data->banks_num; i++) {
index f77d28bb885c7f32be70aac820225bb1db8b9aaa..8645ffcfac6950348f566e8a1529211d00f45fce 100644 (file)
@@ -423,3 +423,8 @@ hwmon-w83l786ng-convert-macros-to-functions-to-avoid-toctou.patch
 arm-dts-microchip-sama5d2-fix-spi-flexcom-fifo-size-to-32.patch
 arm-dts-microchip-sama7d65-fix-uart-fifo-size-to-32.patch
 arm-dts-microchip-sama7g5-fix-uart-fifo-size-to-32.patch
+block-freeze-queue-when-updating-zone-resources.patch
+iommu-mediatek-fix-use-after-free-on-probe-deferral.patch
+fuse-fix-io-uring-list-corruption-for-terminated-non-committed-requests.patch
+fuse-fix-readahead-reclaim-deadlock.patch
+fuse-missing-copy_finish-in-fuse-over-io-uring-argument-copies.patch