From: Greg Kroah-Hartman Date: Mon, 23 Dec 2024 10:42:05 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v6.1.122~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f48e95fcaa36e07db777d7902e32666254bdf778;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: btrfs-tree-checker-reject-inline-extent-items-with-0-ref-count.patch --- diff --git a/queue-5.4/btrfs-tree-checker-reject-inline-extent-items-with-0-ref-count.patch b/queue-5.4/btrfs-tree-checker-reject-inline-extent-items-with-0-ref-count.patch new file mode 100644 index 00000000000..41622a4bce4 --- /dev/null +++ b/queue-5.4/btrfs-tree-checker-reject-inline-extent-items-with-0-ref-count.patch @@ -0,0 +1,104 @@ +From dfb92681a19e1d5172420baa242806414b3eff6f Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Wed, 4 Dec 2024 13:30:46 +1030 +Subject: btrfs: tree-checker: reject inline extent items with 0 ref count + +From: Qu Wenruo + +commit dfb92681a19e1d5172420baa242806414b3eff6f upstream. + +[BUG] +There is a bug report in the mailing list where btrfs_run_delayed_refs() +failed to drop the ref count for logical 25870311358464 num_bytes +2113536. + +The involved leaf dump looks like this: + + item 166 key (25870311358464 168 2113536) itemoff 10091 itemsize 50 + extent refs 1 gen 84178 flags 1 + ref#0: shared data backref parent 32399126528000 count 0 <<< + ref#1: shared data backref parent 31808973717504 count 1 + +Notice the count number is 0. + +[CAUSE] +There is no concrete evidence yet, but considering 0 -> 1 is also a +single bit flipped, it's possible that hardware memory bitflip is +involved, causing the on-disk extent tree to be corrupted. + +[FIX] +To prevent us reading such corrupted extent item, or writing such +damaged extent item back to disk, enhance the handling of +BTRFS_EXTENT_DATA_REF_KEY and BTRFS_SHARED_DATA_REF_KEY keys for both +inlined and key items, to detect such 0 ref count and reject them. + +CC: stable@vger.kernel.org # 5.4+ +Link: https://lore.kernel.org/linux-btrfs/7c69dd49-c346-4806-86e7-e6f863a66f48@app.fastmail.com/ +Reported-by: Frankie Fisher +Reviewed-by: Filipe Manana +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/tree-checker.c | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -1197,6 +1197,11 @@ static int check_extent_item(struct exte + dref_offset, fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid data ref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + inline_refs += btrfs_extent_data_ref_count(leaf, dref); + break; + /* Contains parent bytenr and ref count */ +@@ -1208,6 +1213,11 @@ static int check_extent_item(struct exte + inline_offset, fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid shared data ref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + inline_refs += btrfs_shared_data_ref_count(leaf, sref); + break; + default: +@@ -1259,8 +1269,18 @@ static int check_simple_keyed_refs(struc + { + u32 expect_item_size = 0; + +- if (key->type == BTRFS_SHARED_DATA_REF_KEY) ++ if (key->type == BTRFS_SHARED_DATA_REF_KEY) { ++ struct btrfs_shared_data_ref *sref; ++ ++ sref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref); ++ if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid shared data backref count, should have non-zero value"); ++ return -EUCLEAN; ++ } ++ + expect_item_size = sizeof(struct btrfs_shared_data_ref); ++ } + + if (btrfs_item_size_nr(leaf, slot) != expect_item_size) { + generic_err(leaf, slot, +@@ -1320,6 +1340,11 @@ static int check_extent_data_ref(struct + offset, leaf->fs_info->sectorsize); + return -EUCLEAN; + } ++ if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) { ++ extent_err(leaf, slot, ++ "invalid extent data backref count, should have non-zero value"); ++ return -EUCLEAN; ++ } + } + return 0; + } diff --git a/queue-5.4/series b/queue-5.4/series index db73dd4364e..cc0b2e68620 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -23,3 +23,4 @@ usb-serial-option-add-mediatek-t7xx-compositions.patch usb-serial-option-add-telit-fe910c04-rmnet-compositions.patch sh-clk-fix-clk_enable-to-return-0-on-null-clk.patch zram-refuse-to-use-zero-sized-block-device-as-backing-device.patch +btrfs-tree-checker-reject-inline-extent-items-with-0-ref-count.patch