]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 May 2024 13:30:13 +0000 (15:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 May 2024 13:30:13 +0000 (15:30 +0200)
added patches:
btrfs-add-missing-mutex_unlock-in-btrfs_relocate_sys_chunks.patch
btrfs-make-sure-that-written-is-set-on-all-metadata-blocks.patch
btrfs-qgroup-do-not-check-qgroup-inherit-if-qgroup-is-disabled.patch
btrfs-set-correct-ram_bytes-when-splitting-ordered-extent.patch
maple_tree-fix-mas_empty_area_rev-null-pointer-dereference.patch
mm-slub-avoid-zeroing-outside-object-freepointer-for-single-free.patch

queue-6.8/btrfs-add-missing-mutex_unlock-in-btrfs_relocate_sys_chunks.patch [new file with mode: 0644]
queue-6.8/btrfs-make-sure-that-written-is-set-on-all-metadata-blocks.patch [new file with mode: 0644]
queue-6.8/btrfs-qgroup-do-not-check-qgroup-inherit-if-qgroup-is-disabled.patch [new file with mode: 0644]
queue-6.8/btrfs-set-correct-ram_bytes-when-splitting-ordered-extent.patch [new file with mode: 0644]
queue-6.8/maple_tree-fix-mas_empty_area_rev-null-pointer-dereference.patch [new file with mode: 0644]
queue-6.8/mm-slub-avoid-zeroing-outside-object-freepointer-for-single-free.patch [new file with mode: 0644]
queue-6.8/series

diff --git a/queue-6.8/btrfs-add-missing-mutex_unlock-in-btrfs_relocate_sys_chunks.patch b/queue-6.8/btrfs-add-missing-mutex_unlock-in-btrfs_relocate_sys_chunks.patch
new file mode 100644 (file)
index 0000000..85a9712
--- /dev/null
@@ -0,0 +1,35 @@
+From 9af503d91298c3f2945e73703f0e00995be08c30 Mon Sep 17 00:00:00 2001
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Date: Fri, 19 Apr 2024 11:22:48 +0900
+Subject: btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks()
+
+From: Dominique Martinet <dominique.martinet@atmark-techno.com>
+
+commit 9af503d91298c3f2945e73703f0e00995be08c30 upstream.
+
+The previous patch that replaced BUG_ON by error handling forgot to
+unlock the mutex in the error path.
+
+Link: https://lore.kernel.org/all/Zh%2fHpAGFqa7YAFuM@duo.ucw.cz
+Reported-by: Pavel Machek <pavel@denx.de>
+Fixes: 7411055db5ce ("btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks()")
+CC: stable@vger.kernel.org
+Reviewed-by: Pavel Machek <pavel@denx.de>
+Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/volumes.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -3456,6 +3456,7 @@ again:
+                        * alignment and size).
+                        */
+                       ret = -EUCLEAN;
++                      mutex_unlock(&fs_info->reclaim_bgs_lock);
+                       goto error;
+               }
diff --git a/queue-6.8/btrfs-make-sure-that-written-is-set-on-all-metadata-blocks.patch b/queue-6.8/btrfs-make-sure-that-written-is-set-on-all-metadata-blocks.patch
new file mode 100644 (file)
index 0000000..22c2b89
--- /dev/null
@@ -0,0 +1,148 @@
+From e03418abde871314e1a3a550f4c8afb7b89cb273 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 29 Apr 2024 09:03:35 -0400
+Subject: btrfs: make sure that WRITTEN is set on all metadata blocks
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit e03418abde871314e1a3a550f4c8afb7b89cb273 upstream.
+
+We previously would call btrfs_check_leaf() if we had the check
+integrity code enabled, which meant that we could only run the extended
+leaf checks if we had WRITTEN set on the header flags.
+
+This leaves a gap in our checking, because we could end up with
+corruption on disk where WRITTEN isn't set on the leaf, and then the
+extended leaf checks don't get run which we rely on to validate all of
+the item pointers to make sure we don't access memory outside of the
+extent buffer.
+
+However, since 732fab95abe2 ("btrfs: check-integrity: remove
+CONFIG_BTRFS_FS_CHECK_INTEGRITY option") we no longer call
+btrfs_check_leaf() from btrfs_mark_buffer_dirty(), which means we only
+ever call it on blocks that are being written out, and thus have WRITTEN
+set, or that are being read in, which should have WRITTEN set.
+
+Add checks to make sure we have WRITTEN set appropriately, and then make
+sure __btrfs_check_leaf() always does the item checking.  This will
+protect us from file systems that have been corrupted and no longer have
+WRITTEN set on some of the blocks.
+
+This was hit on a crafted image tweaking the WRITTEN bit and reported by
+KASAN as out-of-bound access in the eb accessors. The example is a dir
+item at the end of an eb.
+
+  [2.042] BTRFS warning (device loop1): bad eb member start: ptr 0x3fff start 30572544 member offset 16410 size 2
+  [2.040] general protection fault, probably for non-canonical address 0xe0009d1000000003: 0000 [#1] PREEMPT SMP KASAN NOPTI
+  [2.537] KASAN: maybe wild-memory-access in range [0x0005088000000018-0x000508800000001f]
+  [2.729] CPU: 0 PID: 2587 Comm: mount Not tainted 6.8.2 #1
+  [2.729] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+  [2.621] RIP: 0010:btrfs_get_16+0x34b/0x6d0
+  [2.621] RSP: 0018:ffff88810871fab8 EFLAGS: 00000206
+  [2.621] RAX: 0000a11000000003 RBX: ffff888104ff8720 RCX: ffff88811b2288c0
+  [2.621] RDX: dffffc0000000000 RSI: ffffffff81dd8aca RDI: ffff88810871f748
+  [2.621] RBP: 000000000000401a R08: 0000000000000001 R09: ffffed10210e3ee9
+  [2.621] R10: ffff88810871f74f R11: 205d323430333737 R12: 000000000000001a
+  [2.621] R13: 000508800000001a R14: 1ffff110210e3f5d R15: ffffffff850011e8
+  [2.621] FS:  00007f56ea275840(0000) GS:ffff88811b200000(0000) knlGS:0000000000000000
+  [2.621] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  [2.621] CR2: 00007febd13b75c0 CR3: 000000010bb50000 CR4: 00000000000006f0
+  [2.621] Call Trace:
+  [2.621]  <TASK>
+  [2.621]  ? show_regs+0x74/0x80
+  [2.621]  ? die_addr+0x46/0xc0
+  [2.621]  ? exc_general_protection+0x161/0x2a0
+  [2.621]  ? asm_exc_general_protection+0x26/0x30
+  [2.621]  ? btrfs_get_16+0x33a/0x6d0
+  [2.621]  ? btrfs_get_16+0x34b/0x6d0
+  [2.621]  ? btrfs_get_16+0x33a/0x6d0
+  [2.621]  ? __pfx_btrfs_get_16+0x10/0x10
+  [2.621]  ? __pfx_mutex_unlock+0x10/0x10
+  [2.621]  btrfs_match_dir_item_name+0x101/0x1a0
+  [2.621]  btrfs_lookup_dir_item+0x1f3/0x280
+  [2.621]  ? __pfx_btrfs_lookup_dir_item+0x10/0x10
+  [2.621]  btrfs_get_tree+0xd25/0x1910
+
+Reported-by: lei lu <llfamsec@gmail.com>
+CC: stable@vger.kernel.org # 6.7+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+[ copy more details from report ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/tree-checker.c |   30 +++++++++++++++---------------
+ fs/btrfs/tree-checker.h |    1 +
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -1793,6 +1793,11 @@ enum btrfs_tree_block_status __btrfs_che
+               return BTRFS_TREE_BLOCK_INVALID_LEVEL;
+       }
++      if (unlikely(!btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_WRITTEN))) {
++              generic_err(leaf, 0, "invalid flag for leaf, WRITTEN not set");
++              return BTRFS_TREE_BLOCK_WRITTEN_NOT_SET;
++      }
++
+       /*
+        * Extent buffers from a relocation tree have a owner field that
+        * corresponds to the subvolume tree they are based on. So just from an
+@@ -1854,6 +1859,7 @@ enum btrfs_tree_block_status __btrfs_che
+       for (slot = 0; slot < nritems; slot++) {
+               u32 item_end_expected;
+               u64 item_data_end;
++              enum btrfs_tree_block_status ret;
+               btrfs_item_key_to_cpu(leaf, &key, slot);
+@@ -1909,21 +1915,10 @@ enum btrfs_tree_block_status __btrfs_che
+                       return BTRFS_TREE_BLOCK_INVALID_OFFSETS;
+               }
+-              /*
+-               * We only want to do this if WRITTEN is set, otherwise the leaf
+-               * may be in some intermediate state and won't appear valid.
+-               */
+-              if (btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_WRITTEN)) {
+-                      enum btrfs_tree_block_status ret;
+-
+-                      /*
+-                       * Check if the item size and content meet other
+-                       * criteria
+-                       */
+-                      ret = check_leaf_item(leaf, &key, slot, &prev_key);
+-                      if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
+-                              return ret;
+-              }
++              /* Check if the item size and content meet other criteria. */
++              ret = check_leaf_item(leaf, &key, slot, &prev_key);
++              if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
++                      return ret;
+               prev_key.objectid = key.objectid;
+               prev_key.type = key.type;
+@@ -1953,6 +1948,11 @@ enum btrfs_tree_block_status __btrfs_che
+       int level = btrfs_header_level(node);
+       u64 bytenr;
++      if (unlikely(!btrfs_header_flag(node, BTRFS_HEADER_FLAG_WRITTEN))) {
++              generic_err(node, 0, "invalid flag for node, WRITTEN not set");
++              return BTRFS_TREE_BLOCK_WRITTEN_NOT_SET;
++      }
++
+       if (unlikely(level <= 0 || level >= BTRFS_MAX_LEVEL)) {
+               generic_err(node, 0,
+                       "invalid level for node, have %d expect [1, %d]",
+--- a/fs/btrfs/tree-checker.h
++++ b/fs/btrfs/tree-checker.h
+@@ -51,6 +51,7 @@ enum btrfs_tree_block_status {
+       BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
+       BTRFS_TREE_BLOCK_INVALID_ITEM,
+       BTRFS_TREE_BLOCK_INVALID_OWNER,
++      BTRFS_TREE_BLOCK_WRITTEN_NOT_SET,
+ };
+ /*
diff --git a/queue-6.8/btrfs-qgroup-do-not-check-qgroup-inherit-if-qgroup-is-disabled.patch b/queue-6.8/btrfs-qgroup-do-not-check-qgroup-inherit-if-qgroup-is-disabled.patch
new file mode 100644 (file)
index 0000000..cba99b0
--- /dev/null
@@ -0,0 +1,54 @@
+From b5357cb268c41b4e2b7383d2759fc562f5b58c33 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Sat, 20 Apr 2024 17:20:27 +0930
+Subject: btrfs: qgroup: do not check qgroup inherit if qgroup is disabled
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit b5357cb268c41b4e2b7383d2759fc562f5b58c33 upstream.
+
+[BUG]
+After kernel commit 86211eea8ae1 ("btrfs: qgroup: validate
+btrfs_qgroup_inherit parameter"), user space tool snapper will fail to
+create snapshot using its timeline feature.
+
+[CAUSE]
+It turns out that, if using timeline snapper would unconditionally pass
+btrfs_qgroup_inherit parameter (assigning the new snapshot to qgroup 1/0)
+for snapshot creation.
+
+In that case, since qgroup is disabled there would be no qgroup 1/0, and
+btrfs_qgroup_check_inherit() would return -ENOENT and fail the whole
+snapshot creation.
+
+[FIX]
+Just skip the check if qgroup is not enabled.
+This is to keep the older behavior for user space tools, as if the
+kernel behavior changed for user space, it is a regression of kernel.
+
+Thankfully snapper is also fixing the behavior by detecting if qgroup is
+running in the first place, so the effect should not be that huge.
+
+Link: https://github.com/openSUSE/snapper/issues/894
+Fixes: 86211eea8ae1 ("btrfs: qgroup: validate btrfs_qgroup_inherit parameter")
+CC: stable@vger.kernel.org # 6.8+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/qgroup.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -3052,6 +3052,8 @@ int btrfs_qgroup_check_inherit(struct bt
+                              struct btrfs_qgroup_inherit *inherit,
+                              size_t size)
+ {
++      if (!btrfs_qgroup_enabled(fs_info))
++              return 0;
+       if (inherit->flags & ~BTRFS_QGROUP_INHERIT_FLAGS_SUPP)
+               return -EOPNOTSUPP;
+       if (size < sizeof(*inherit) || size > PAGE_SIZE)
diff --git a/queue-6.8/btrfs-set-correct-ram_bytes-when-splitting-ordered-extent.patch b/queue-6.8/btrfs-set-correct-ram_bytes-when-splitting-ordered-extent.patch
new file mode 100644 (file)
index 0000000..0e21dbc
--- /dev/null
@@ -0,0 +1,65 @@
+From 63a6ce5a1a6261e4c70bad2b55c4e0de8da4762e Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 16 Apr 2024 08:07:00 +0930
+Subject: btrfs: set correct ram_bytes when splitting ordered extent
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 63a6ce5a1a6261e4c70bad2b55c4e0de8da4762e upstream.
+
+[BUG]
+When running generic/287, the following file extent items can be
+generated:
+
+        item 16 key (258 EXTENT_DATA 2682880) itemoff 15305 itemsize 53
+                generation 9 type 1 (regular)
+                extent data disk byte 1378414592 nr 462848
+                extent data offset 0 nr 462848 ram 2097152
+                extent compression 0 (none)
+
+Note that file extent item is not a compressed one, but its ram_bytes is
+way larger than its disk_num_bytes.
+
+According to btrfs on-disk scheme, ram_bytes should match disk_num_bytes
+if it's not a compressed one.
+
+[CAUSE]
+Since commit b73a6fd1b1ef ("btrfs: split partial dio bios before
+submit"), for partial dio writes, we would split the ordered extent.
+
+However the function btrfs_split_ordered_extent() doesn't update the
+ram_bytes even it has already shrunk the disk_num_bytes.
+
+Originally the function btrfs_split_ordered_extent() is only introduced
+for zoned devices in commit d22002fd37bd ("btrfs: zoned: split ordered
+extent when bio is sent"), but later commit b73a6fd1b1ef ("btrfs: split
+partial dio bios before submit") makes non-zoned btrfs affected.
+
+Thankfully for un-compressed file extent, we do not really utilize the
+ram_bytes member, thus it won't cause any real problem.
+
+[FIX]
+Also update btrfs_ordered_extent::ram_bytes inside
+btrfs_split_ordered_extent().
+
+Fixes: d22002fd37bd ("btrfs: zoned: split ordered extent when bio is sent")
+CC: stable@vger.kernel.org # 5.15+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/ordered-data.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/ordered-data.c
++++ b/fs/btrfs/ordered-data.c
+@@ -1189,6 +1189,7 @@ struct btrfs_ordered_extent *btrfs_split
+       ordered->disk_bytenr += len;
+       ordered->num_bytes -= len;
+       ordered->disk_num_bytes -= len;
++      ordered->ram_bytes -= len;
+       if (test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags)) {
+               ASSERT(ordered->bytes_left == 0);
diff --git a/queue-6.8/maple_tree-fix-mas_empty_area_rev-null-pointer-dereference.patch b/queue-6.8/maple_tree-fix-mas_empty_area_rev-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..63f516a
--- /dev/null
@@ -0,0 +1,65 @@
+From 955a923d2809803980ff574270f81510112be9cf Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Mon, 22 Apr 2024 16:33:49 -0400
+Subject: maple_tree: fix mas_empty_area_rev() null pointer dereference
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit 955a923d2809803980ff574270f81510112be9cf upstream.
+
+Currently the code calls mas_start() followed by mas_data_end() if the
+maple state is MA_START, but mas_start() may return with the maple state
+node == NULL.  This will lead to a null pointer dereference when checking
+information in the NULL node, which is done in mas_data_end().
+
+Avoid setting the offset if there is no node by waiting until after the
+maple state is checked for an empty or single entry state.
+
+A user could trigger the events to cause a kernel oops by unmapping all
+vmas to produce an empty maple tree, then mapping a vma that would cause
+the scenario described above.
+
+Link: https://lkml.kernel.org/r/20240422203349.2418465-1-Liam.Howlett@oracle.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: Marius Fleischer <fleischermarius@gmail.com>
+Closes: https://lore.kernel.org/lkml/CAJg=8jyuSxDL6XvqEXY_66M20psRK2J53oBTP+fjV5xpW2-R6w@mail.gmail.com/
+Link: https://lore.kernel.org/lkml/CAJg=8jyuSxDL6XvqEXY_66M20psRK2J53oBTP+fjV5xpW2-R6w@mail.gmail.com/
+Tested-by: Marius Fleischer <fleischermarius@gmail.com>
+Tested-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -5061,18 +5061,18 @@ int mas_empty_area_rev(struct ma_state *
+       if (size == 0 || max - min < size - 1)
+               return -EINVAL;
+-      if (mas_is_start(mas)) {
++      if (mas_is_start(mas))
+               mas_start(mas);
+-              mas->offset = mas_data_end(mas);
+-      } else if (mas->offset >= 2) {
+-              mas->offset -= 2;
+-      } else if (!mas_rewind_node(mas)) {
++      else if ((mas->offset < 2) && (!mas_rewind_node(mas)))
+               return -EBUSY;
+-      }
+-      /* Empty set. */
+-      if (mas_is_none(mas) || mas_is_ptr(mas))
++      if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))
+               return mas_sparse_area(mas, min, max, size, false);
++      else if (mas->offset >= 2)
++              mas->offset -= 2;
++      else
++              mas->offset = mas_data_end(mas);
++
+       /* The start of the window can only be within these values. */
+       mas->index = min;
diff --git a/queue-6.8/mm-slub-avoid-zeroing-outside-object-freepointer-for-single-free.patch b/queue-6.8/mm-slub-avoid-zeroing-outside-object-freepointer-for-single-free.patch
new file mode 100644 (file)
index 0000000..723bf38
--- /dev/null
@@ -0,0 +1,147 @@
+From 8f828aa48812ced28aa39cb3cfe55ef2444d03dd Mon Sep 17 00:00:00 2001
+From: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+Date: Tue, 30 Apr 2024 13:34:59 +0200
+Subject: mm/slub: avoid zeroing outside-object freepointer for single free
+
+From: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+
+commit 8f828aa48812ced28aa39cb3cfe55ef2444d03dd upstream.
+
+Commit 284f17ac13fe ("mm/slub: handle bulk and single object freeing
+separately") splits single and bulk object freeing in two functions
+slab_free() and slab_free_bulk() which leads slab_free() to call
+slab_free_hook() directly instead of slab_free_freelist_hook().
+
+If `init_on_free` is set, slab_free_hook() zeroes the object.
+Afterward, if `slub_debug=F` and `CONFIG_SLAB_FREELIST_HARDENED` are
+set, the do_slab_free() slowpath executes freelist consistency
+checks and try to decode a zeroed freepointer which leads to a
+"Freepointer corrupt" detection in check_object().
+
+During bulk free, slab_free_freelist_hook() isn't affected as it always
+sets it objects freepointer using set_freepointer() to maintain its
+reconstructed freelist after `init_on_free`.
+
+For single free, object's freepointer thus needs to be avoided when
+stored outside the object if `init_on_free` is set. The freepointer left
+as is, check_object() may later detect an invalid pointer value due to
+objects overflow.
+
+To reproduce, set `slub_debug=FU init_on_free=1 log_level=7` on the
+command line of a kernel build with `CONFIG_SLAB_FREELIST_HARDENED=y`.
+
+dmesg sample log:
+[   10.708715] =============================================================================
+[   10.710323] BUG kmalloc-rnd-05-32 (Tainted: G    B           T ): Freepointer corrupt
+[   10.712695] -----------------------------------------------------------------------------
+[   10.712695]
+[   10.712695] Slab 0xffffd8bdc400d580 objects=32 used=4 fp=0xffff9d9a80356f80 flags=0x200000000000a00(workingset|slab|node=0|zone=2)
+[   10.716698] Object 0xffff9d9a80356600 @offset=1536 fp=0x7ee4f480ce0ecd7c
+[   10.716698]
+[   10.716698] Bytes b4 ffff9d9a803565f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+[   10.720703] Object   ffff9d9a80356600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+[   10.720703] Object   ffff9d9a80356610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+[   10.724696] Padding  ffff9d9a8035666c: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
+[   10.724696] Padding  ffff9d9a8035667c: 00 00 00 00                                      ....
+[   10.724696] FIX kmalloc-rnd-05-32: Object at 0xffff9d9a80356600 not freed
+
+Fixes: 284f17ac13fe ("mm/slub: handle bulk and single object freeing separately")
+Cc: <stable@vger.kernel.org>
+Co-developed-by: Chengming Zhou <chengming.zhou@linux.dev>
+Signed-off-by: Chengming Zhou <chengming.zhou@linux.dev>
+Signed-off-by: Nicolas Bouchinet <nicolas.bouchinet@ssi.gouv.fr>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/slub.c |   52 +++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 29 insertions(+), 23 deletions(-)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -557,6 +557,26 @@ static inline void set_freepointer(struc
+       *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr);
+ }
++/*
++ * See comment in calculate_sizes().
++ */
++static inline bool freeptr_outside_object(struct kmem_cache *s)
++{
++      return s->offset >= s->inuse;
++}
++
++/*
++ * Return offset of the end of info block which is inuse + free pointer if
++ * not overlapping with object.
++ */
++static inline unsigned int get_info_end(struct kmem_cache *s)
++{
++      if (freeptr_outside_object(s))
++              return s->inuse + sizeof(void *);
++      else
++              return s->inuse;
++}
++
+ /* Loop over all objects in a slab */
+ #define for_each_object(__p, __s, __addr, __objects) \
+       for (__p = fixup_red_left(__s, __addr); \
+@@ -845,26 +865,6 @@ static void print_section(char *level, c
+       metadata_access_disable();
+ }
+-/*
+- * See comment in calculate_sizes().
+- */
+-static inline bool freeptr_outside_object(struct kmem_cache *s)
+-{
+-      return s->offset >= s->inuse;
+-}
+-
+-/*
+- * Return offset of the end of info block which is inuse + free pointer if
+- * not overlapping with object.
+- */
+-static inline unsigned int get_info_end(struct kmem_cache *s)
+-{
+-      if (freeptr_outside_object(s))
+-              return s->inuse + sizeof(void *);
+-      else
+-              return s->inuse;
+-}
+-
+ static struct track *get_track(struct kmem_cache *s, void *object,
+       enum track_item alloc)
+ {
+@@ -2107,15 +2107,20 @@ bool slab_free_hook(struct kmem_cache *s
+        *
+        * The initialization memset's clear the object and the metadata,
+        * but don't touch the SLAB redzone.
++       *
++       * The object's freepointer is also avoided if stored outside the
++       * object.
+        */
+       if (unlikely(init)) {
+               int rsize;
++              unsigned int inuse;
++              inuse = get_info_end(s);
+               if (!kasan_has_integrated_init())
+                       memset(kasan_reset_tag(x), 0, s->object_size);
+               rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad : 0;
+-              memset((char *)kasan_reset_tag(x) + s->inuse, 0,
+-                     s->size - s->inuse - rsize);
++              memset((char *)kasan_reset_tag(x) + inuse, 0,
++                     s->size - inuse - rsize);
+       }
+       /* KASAN might put x into memory quarantine, delaying its reuse. */
+       return !kasan_slab_free(s, x, init);
+@@ -3737,7 +3742,8 @@ static void *__slab_alloc_node(struct km
+ static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s,
+                                                  void *obj)
+ {
+-      if (unlikely(slab_want_init_on_free(s)) && obj)
++      if (unlikely(slab_want_init_on_free(s)) && obj &&
++          !freeptr_outside_object(s))
+               memset((void *)((char *)kasan_reset_tag(obj) + s->offset),
+                       0, sizeof(void *));
+ }
index 8767fec5f3eb2cbd1563bb0fb4b305b70de740fe..b722161020893ef78e675b173037a976464175af 100644 (file)
@@ -259,3 +259,9 @@ usb-typec-tcpm-check-for-port-partner-validity-before-consuming-it.patch
 alsa-hda-realtek-fix-mute-led-of-hp-laptop-15-da3001tu.patch
 alsa-hda-realtek-fix-conflicting-pci-ssid-17aa-386f-for-lenovo-legion-models.patch
 firewire-ohci-fulfill-timestamp-for-some-local-asynchronous-transaction.patch
+mm-slub-avoid-zeroing-outside-object-freepointer-for-single-free.patch
+btrfs-add-missing-mutex_unlock-in-btrfs_relocate_sys_chunks.patch
+btrfs-set-correct-ram_bytes-when-splitting-ordered-extent.patch
+btrfs-qgroup-do-not-check-qgroup-inherit-if-qgroup-is-disabled.patch
+btrfs-make-sure-that-written-is-set-on-all-metadata-blocks.patch
+maple_tree-fix-mas_empty_area_rev-null-pointer-dereference.patch