]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Fri, 1 May 2026 00:51:40 +0000 (20:51 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 1 May 2026 00:51:40 +0000 (20:51 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/mm-memory_hotplug-fix-hwpoisoned-large-folio-handlin.patch [new file with mode: 0644]
queue-6.12/series
queue-6.18/mm-call-free_folio-directly-in-folio_unmap_invalidat.patch [new file with mode: 0644]
queue-6.18/series
queue-6.6/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.1/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch b/queue-6.1/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch
new file mode 100644 (file)
index 0000000..91dc8ab
--- /dev/null
@@ -0,0 +1,77 @@
+From acf106a4b8d5a034e3e52b100c1346ebaf6b3ef1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Apr 2026 13:55:37 +0800
+Subject: f2fs: fix to detect potential corrupted nid in free_nid_list
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 8fc6056dcf79937c46c97fa4996cda65956437a9 ]
+
+As reported, on-disk footer.ino and footer.nid is the same and
+out-of-range, let's add sanity check on f2fs_alloc_nid() to detect
+any potential corruption in free_nid_list.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Robert Garcia <rob_garcia@163.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/node.c          | 17 ++++++++++++++++-
+ include/linux/f2fs_fs.h |  1 +
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 2555787c79bbe..06c94680ae4e7 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -27,12 +27,17 @@ static struct kmem_cache *free_nid_slab;
+ static struct kmem_cache *nat_entry_set_slab;
+ static struct kmem_cache *fsync_node_entry_slab;
++static inline bool is_invalid_nid(struct f2fs_sb_info *sbi, nid_t nid)
++{
++      return nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid;
++}
++
+ /*
+  * Check whether the given nid is within node id range.
+  */
+ int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
+ {
+-      if (unlikely(nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid)) {
++      if (unlikely(is_invalid_nid(sbi, nid))) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_warn(sbi, "%s: out-of-range nid=%x, run fsck to fix.",
+                         __func__, nid);
+@@ -2593,6 +2598,16 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
+               f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list));
+               i = list_first_entry(&nm_i->free_nid_list,
+                                       struct free_nid, list);
++
++              if (unlikely(is_invalid_nid(sbi, i->nid))) {
++                      spin_unlock(&nm_i->nid_list_lock);
++                      f2fs_err(sbi, "Corrupted nid %u in free_nid_list",
++                                                              i->nid);
++                      f2fs_stop_checkpoint(sbi, false,
++                                      STOP_CP_REASON_CORRUPTED_NID);
++                      return false;
++              }
++
+               *nid = i->nid;
+               __move_free_nid(sbi, i, FREE_NID, PREALLOC_NID);
+diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
+index c61d8fc1deb3e..26c7daca99598 100644
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -81,6 +81,7 @@ enum stop_cp_reason {
+       STOP_CP_REASON_CORRUPTED_SUMMARY,
+       STOP_CP_REASON_UPDATE_INODE,
+       STOP_CP_REASON_FLUSH_FAIL,
++      STOP_CP_REASON_CORRUPTED_NID,
+       STOP_CP_REASON_MAX,
+ };
+-- 
+2.53.0
+
index 07ae1dc2f5a92fb5769d4dcf4dc7a5f635af64ba..3c9c95931706ad6b75a2da4bf82ddce436db9662 100644 (file)
@@ -179,3 +179,4 @@ ocfs2-split-transactions-in-dio-completion-to-avoid-credit-exhaustion.patch
 driver-core-don-t-let-a-device-probe-until-it-s-read.patch
 wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
 um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
+f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch
diff --git a/queue-6.12/mm-memory_hotplug-fix-hwpoisoned-large-folio-handlin.patch b/queue-6.12/mm-memory_hotplug-fix-hwpoisoned-large-folio-handlin.patch
new file mode 100644 (file)
index 0000000..73887f4
--- /dev/null
@@ -0,0 +1,86 @@
+From ebd37391cfef1c18d2a2616219189cf1b31e5a02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Apr 2026 14:37:31 +0300
+Subject: mm/memory_hotplug: fix hwpoisoned large folio handling in
+ do_migrate_range()
+
+From: Jinjiang Tu <tujinjiang@huawei.com>
+
+commit 397f6d14f9c370e4910e6885294c340f39dedbf5 upstream.
+
+In do_migrate_range(), the hwpoisoned folio may be large folio, which
+can't be handled by unmap_poisoned_folio().
+
+I can reproduce this issue in qemu after adding delay in memory_failure()
+
+BUG: kernel NULL pointer dereference, address: 0000000000000000
+Workqueue: kacpi_hotplug acpi_hotplug_work_fn
+RIP: 0010:try_to_unmap_one+0x16a/0xfc0
+  <TASK>
+  rmap_walk_anon+0xda/0x1f0
+  try_to_unmap+0x78/0x80
+  ? __pfx_try_to_unmap_one+0x10/0x10
+  ? __pfx_folio_not_mapped+0x10/0x10
+  ? __pfx_folio_lock_anon_vma_read+0x10/0x10
+  unmap_poisoned_folio+0x60/0x140
+  do_migrate_range+0x4d1/0x600
+  ? slab_memory_callback+0x6a/0x190
+  ? notifier_call_chain+0x56/0xb0
+  offline_pages+0x3e6/0x460
+  memory_subsys_offline+0x130/0x1f0
+  device_offline+0xba/0x110
+  acpi_bus_offline+0xb7/0x130
+  acpi_scan_hot_remove+0x77/0x290
+  acpi_device_hotplug+0x1e0/0x240
+  acpi_hotplug_work_fn+0x1a/0x30
+  process_one_work+0x186/0x340
+
+Besides, do_migrate_range() may be called between memory_failure set
+hwpoison flag and isolate the folio from lru, so remove WARN_ON(). In other
+places, unmap_poisoned_folio() is called when the folio is isolated, obey
+it in do_migrate_range() too.
+
+[david@redhat.com: don't abort offlining, fixed typo, add comment]
+Link: https://lkml.kernel.org/r/3c214dff-9649-4015-840f-10de0e03ebe4@redhat.com
+Fixes: b15c87263a69 ("hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined")
+Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Acked-by: Zi Yan <ziy@nvidia.com>
+Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Luis Chamberalin <mcgrof@kernel.org>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Pankaj Raghav <kernel@pankajraghav.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/memory_hotplug.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+index 0a42e9a8caba2..16d788547b9b6 100644
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1802,8 +1802,14 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
+                       goto put_folio;
+               if (folio_contain_hwpoisoned_page(folio)) {
+-                      if (WARN_ON(folio_test_lru(folio)))
+-                              folio_isolate_lru(folio);
++                      /*
++                       * unmap_poisoned_folio() cannot handle large folios
++                       * in all cases yet.
++                       */
++                      if (folio_test_large(folio) && !folio_test_hugetlb(folio))
++                              goto put_folio;
++                      if (folio_test_lru(folio) && !folio_isolate_lru(folio))
++                              goto put_folio;
+                       if (folio_mapped(folio)) {
+                               folio_lock(folio);
+                               unmap_poisoned_folio(folio, pfn, false);
+-- 
+2.53.0
+
index c23f863dfb7af93a543dec4e0354cbe95194926a..142e73088919dfb09df82769077d82c82caa7e74 100644 (file)
@@ -32,3 +32,4 @@ vfio-cdx-fix-null-pointer-dereference-in-interrupt-trigger-path.patch
 um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
 spi-imx-fix-use-after-free-on-unbind.patch
 spi-ch341-fix-memory-leaks-on-probe-failures.patch
+mm-memory_hotplug-fix-hwpoisoned-large-folio-handlin.patch
diff --git a/queue-6.18/mm-call-free_folio-directly-in-folio_unmap_invalidat.patch b/queue-6.18/mm-call-free_folio-directly-in-folio_unmap_invalidat.patch
new file mode 100644 (file)
index 0000000..36de382
--- /dev/null
@@ -0,0 +1,89 @@
+From 5dd31b7e3d2e26e15c2bb1184a483828c00ad2ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Apr 2026 18:22:22 +0100
+Subject: mm: call ->free_folio() directly in folio_unmap_invalidate()
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+commit 615d9bb2ccad42f9e21d837431e401db2e471195 upstream.
+
+We can only call filemap_free_folio() if we have a reference to (or hold a
+lock on) the mapping.  Otherwise, we've already removed the folio from the
+mapping so it no longer pins the mapping and the mapping can be removed,
+causing a use-after-free when accessing mapping->a_ops.
+
+Follow the same pattern as __remove_mapping() and load the free_folio
+function pointer before dropping the lock on the mapping.  That lets us
+make filemap_free_folio() static as this was the only caller outside
+filemap.c.
+
+Link: https://lore.kernel.org/20260413184314.3419945-1-willy@infradead.org
+Fixes: fb7d3bc41493 ("mm/filemap: drop streaming/uncached pages when writeback completes")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reported-by: Google Big Sleep <big-sleep-vuln-reports+bigsleep-501448199@google.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Jan Kara <jack@suse.cz>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/filemap.c  | 3 ++-
+ mm/internal.h | 1 -
+ mm/truncate.c | 6 +++++-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 91dcfe14a67b7..e3339cf37a1f0 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -227,7 +227,8 @@ void __filemap_remove_folio(struct folio *folio, void *shadow)
+       page_cache_delete(mapping, folio, shadow);
+ }
+-void filemap_free_folio(struct address_space *mapping, struct folio *folio)
++static void filemap_free_folio(const struct address_space *mapping,
++              struct folio *folio)
+ {
+       void (*free_folio)(struct folio *);
+diff --git a/mm/internal.h b/mm/internal.h
+index c80c6f566c2d9..4cf6a12ff491d 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -471,7 +471,6 @@ unsigned find_lock_entries(struct address_space *mapping, pgoff_t *start,
+               pgoff_t end, struct folio_batch *fbatch, pgoff_t *indices);
+ unsigned find_get_entries(struct address_space *mapping, pgoff_t *start,
+               pgoff_t end, struct folio_batch *fbatch, pgoff_t *indices);
+-void filemap_free_folio(struct address_space *mapping, struct folio *folio);
+ int truncate_inode_folio(struct address_space *mapping, struct folio *folio);
+ bool truncate_inode_partial_folio(struct folio *folio, loff_t start,
+               loff_t end);
+diff --git a/mm/truncate.c b/mm/truncate.c
+index 3c5a50ae32741..4bf64fd610c94 100644
+--- a/mm/truncate.c
++++ b/mm/truncate.c
+@@ -622,6 +622,7 @@ static int folio_launder(struct address_space *mapping, struct folio *folio)
+ int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
+                          gfp_t gfp)
+ {
++      void (*free_folio)(struct folio *);
+       int ret;
+       VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
+@@ -648,9 +649,12 @@ int folio_unmap_invalidate(struct address_space *mapping, struct folio *folio,
+       xa_unlock_irq(&mapping->i_pages);
+       if (mapping_shrinkable(mapping))
+               inode_add_lru(mapping->host);
++      free_folio = mapping->a_ops->free_folio;
+       spin_unlock(&mapping->host->i_lock);
+-      filemap_free_folio(mapping, folio);
++      if (free_folio)
++              free_folio(folio);
++      folio_put_refs(folio, folio_nr_pages(folio));
+       return 1;
+ failed:
+       xa_unlock_irq(&mapping->i_pages);
+-- 
+2.53.0
+
index 2239dd44bb0e6712eb729ca1e81dddee0023080a..d8a5c01c15395eb4d50505800655f24e73ecd608 100644 (file)
@@ -35,3 +35,4 @@ um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
 thermal-core-fix-thermal-zone-governor-cleanup-issues.patch
 spi-imx-fix-use-after-free-on-unbind.patch
 spi-ch341-fix-memory-leaks-on-probe-failures.patch
+mm-call-free_folio-directly-in-folio_unmap_invalidat.patch
diff --git a/queue-6.6/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch b/queue-6.6/f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch
new file mode 100644 (file)
index 0000000..ad24fad
--- /dev/null
@@ -0,0 +1,77 @@
+From 7e6c290bd29fb2739746b9b6e30ffd6cfeffeff1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Apr 2026 13:45:10 +0800
+Subject: f2fs: fix to detect potential corrupted nid in free_nid_list
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 8fc6056dcf79937c46c97fa4996cda65956437a9 ]
+
+As reported, on-disk footer.ino and footer.nid is the same and
+out-of-range, let's add sanity check on f2fs_alloc_nid() to detect
+any potential corruption in free_nid_list.
+
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Robert Garcia <rob_garcia@163.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/node.c          | 17 ++++++++++++++++-
+ include/linux/f2fs_fs.h |  1 +
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 133141f10d94d..586a90643ddd2 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -27,12 +27,17 @@ static struct kmem_cache *free_nid_slab;
+ static struct kmem_cache *nat_entry_set_slab;
+ static struct kmem_cache *fsync_node_entry_slab;
++static inline bool is_invalid_nid(struct f2fs_sb_info *sbi, nid_t nid)
++{
++      return nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid;
++}
++
+ /*
+  * Check whether the given nid is within node id range.
+  */
+ int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid)
+ {
+-      if (unlikely(nid < F2FS_ROOT_INO(sbi) || nid >= NM_I(sbi)->max_nid)) {
++      if (unlikely(is_invalid_nid(sbi, nid))) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_warn(sbi, "%s: out-of-range nid=%x, run fsck to fix.",
+                         __func__, nid);
+@@ -2603,6 +2608,16 @@ bool f2fs_alloc_nid(struct f2fs_sb_info *sbi, nid_t *nid)
+               f2fs_bug_on(sbi, list_empty(&nm_i->free_nid_list));
+               i = list_first_entry(&nm_i->free_nid_list,
+                                       struct free_nid, list);
++
++              if (unlikely(is_invalid_nid(sbi, i->nid))) {
++                      spin_unlock(&nm_i->nid_list_lock);
++                      f2fs_err(sbi, "Corrupted nid %u in free_nid_list",
++                                                              i->nid);
++                      f2fs_stop_checkpoint(sbi, false,
++                                      STOP_CP_REASON_CORRUPTED_NID);
++                      return false;
++              }
++
+               *nid = i->nid;
+               __move_free_nid(sbi, i, FREE_NID, PREALLOC_NID);
+diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
+index b9affa64b7fa2..fed8bec024db7 100644
+--- a/include/linux/f2fs_fs.h
++++ b/include/linux/f2fs_fs.h
+@@ -77,6 +77,7 @@ enum stop_cp_reason {
+       STOP_CP_REASON_UPDATE_INODE,
+       STOP_CP_REASON_FLUSH_FAIL,
+       STOP_CP_REASON_NO_SEGMENT,
++      STOP_CP_REASON_CORRUPTED_NID,
+       STOP_CP_REASON_MAX,
+ };
+-- 
+2.53.0
+
index e9fc59202031b5cf2341b094dc7ede0f8e3fc925..302cfb86e375792d8c4e853d2d6f9eab510355d1 100644 (file)
@@ -25,3 +25,4 @@ zram-do-not-forget-to-endio-for-partial-discard-requests.patch
 wifi-rtw88-check-for-pci-upstream-bridge-existence.patch
 um-drivers-call-kernel_strrchr-explicitly-in-cow_user.c.patch
 spi-imx-fix-use-after-free-on-unbind.patch
+f2fs-fix-to-detect-potential-corrupted-nid-in-free_n.patch