Filipe Manana (3): btrfs: remove superfluous metadata check at btrfs_lookup_extent_info() btrfs: reduce nesting for extent processing at btrfs_lookup_extent_info() btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
fs/btrfs/extent-tree.c | 45 +++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 16 deletions(-)
From: Filipe Manana fdmanana@suse.com
mainline inclusion from mainline-v6.11-rc1 commit c65967ac4d1668dfcb903215c8af128fa15f05d6 bugzilla: https://gitee.com/src-openeuler/kernel/issues/IARX0N CVE: CVE-2024-46751
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
If we didn't found an extent item with the initial btrfs_search_slot() call, it's pointless to test if the "metadata" variable is "true", because right after we check if the key type is BTRFS_METADATA_ITEM_KEY and that is the case only when "metadata" is set to "true". So remove the redundant check.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/btrfs/extent-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 578b217bc4ea..88b00fb2a30d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -155,7 +155,7 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, if (ret < 0) goto out_free;
- if (ret > 0 && metadata && key.type == BTRFS_METADATA_ITEM_KEY) { + if (ret > 0 && key.type == BTRFS_METADATA_ITEM_KEY) { if (path->slots[0]) { path->slots[0]--; btrfs_item_key_to_cpu(path->nodes[0], &key,
From: Filipe Manana fdmanana@suse.com
mainline inclusion from mainline-v6.11-rc1 commit 5c83b3beaee06aa88d4015408ac2d8bb35380b06 bugzilla: https://gitee.com/src-openeuler/kernel/issues/IARX0N CVE: CVE-2024-46751
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Instead of using an if-else statement when processing the extent item at btrfs_lookup_extent_info(), use a single if statement for the error case since it does a goto at the end and leave the success (expected) case following the if statement, reducing indentation and making the logic a bit easier to follow. Also make the if statement's condition as unlikely since it's not expected to ever happen, as it signals some corruption, making it clear and hint the compiler to generate more efficient code.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Conflicts: fs/btrfs/extent-tree.c [Context differences, no owner now.] Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/btrfs/extent-tree.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 88b00fb2a30d..5f659565e4b6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -117,10 +117,7 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_head *head; struct btrfs_delayed_ref_root *delayed_refs; struct btrfs_path *path; - struct btrfs_extent_item *ei; - struct extent_buffer *leaf; struct btrfs_key key; - u32 item_size; u64 num_refs; u64 extent_flags; int ret; @@ -168,14 +165,11 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, }
if (ret == 0) { - leaf = path->nodes[0]; - item_size = btrfs_item_size_nr(leaf, path->slots[0]); - if (item_size >= sizeof(*ei)) { - ei = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_extent_item); - num_refs = btrfs_extent_refs(leaf, ei); - extent_flags = btrfs_extent_flags(leaf, ei); - } else { + struct extent_buffer *leaf = path->nodes[0]; + struct btrfs_extent_item *ei; + const u32 item_size = btrfs_item_size_nr(leaf, path->slots[0]); + + if (unlikely(item_size < sizeof(*ei))) { ret = -EINVAL; btrfs_print_v0_err(fs_info); if (trans) @@ -186,6 +180,9 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, goto out_free; }
+ ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); + num_refs = btrfs_extent_refs(leaf, ei); + extent_flags = btrfs_extent_flags(leaf, ei); BUG_ON(num_refs == 0); } else { num_refs = 0;
From: Filipe Manana fdmanana@suse.com
mainline inclusion from mainline-v6.11-rc1 commit 28cb13f29faf6290597b24b728dc3100c019356f bugzilla: https://gitee.com/src-openeuler/kernel/issues/IARX0N CVE: CVE-2024-46751
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Instead of doing a BUG_ON() handle the error by returning -EUCLEAN, aborting the transaction and logging an error message.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Conflicts: fs/btrfs/extent-tree.c [context differences. No owner now.] Signed-off-by: Yifan Qiao qiaoyifan4@huawei.com --- fs/btrfs/extent-tree.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5f659565e4b6..9521cb45433f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -182,8 +182,15 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); num_refs = btrfs_extent_refs(leaf, ei); + if (unlikely(num_refs == 0)) { + ret = -EUCLEAN; + btrfs_err(fs_info, + "unexpected zero reference count for extent item (%llu %u %llu)", + key.objectid, key.type, key.offset); + btrfs_abort_transaction(trans, ret); + goto out_free; + } extent_flags = btrfs_extent_flags(leaf, ei); - BUG_ON(num_refs == 0); } else { num_refs = 0; extent_flags = 0; @@ -213,10 +220,19 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, goto search_again; } spin_lock(&head->lock); - if (head->extent_op && head->extent_op->update_flags) + if (head->extent_op && head->extent_op->update_flags) { extent_flags |= head->extent_op->flags_to_set; - else - BUG_ON(num_refs == 0); + } else if (unlikely(num_refs == 0)) { + spin_unlock(&head->lock); + mutex_unlock(&head->mutex); + spin_unlock(&delayed_refs->lock); + ret = -EUCLEAN; + btrfs_err(fs_info, + "unexpected zero reference count for extent %llu (%s)", + bytenr, metadata ? "metadata" : "data"); + btrfs_abort_transaction(trans, ret); + goto out_free; + }
num_refs += head->ref_mod; spin_unlock(&head->lock);
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/11709 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/11709 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/S...