diff mbox series

btrfs: initialize btrfs_fs_info::csum_size earlier in open_ctree()

Message ID 20210211083828.6835-1-l@damenly.su (mailing list archive)
State New, archived
Headers show
Series btrfs: initialize btrfs_fs_info::csum_size earlier in open_ctree() | expand

Commit Message

Su Yue Feb. 11, 2021, 8:38 a.m. UTC
User reported that btrfs-progs misc-tests/028-superblock-recover fails:
    [TEST/misc]   028-superblock-recover
unexpected success: mounted fs with corrupted superblock
test failed for case 028-superblock-recover

The test case expects that a broken image with bad superblock will be
rejected to be mounted. However, the test image just passed csum check
of superblock and was successfully mounted.

Commit 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size
everywhere") replaces all calls to btrfs_super_csum_size by
fs_info::csum_size. The calls include the place where fs_info->csum_size
is not initialized. So btrfs_check_super_csum() passes because memcmp()
with len 0 always returns 0.

Fix it by caching csum size in btrfs_fs_info::csum_size once we know the
csum type in superblock is valid in open_ctree().

Link: https://github.com/kdave/btrfs-progs/issues/250
Fixes: 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size everywhere")
Signed-off-by: Su Yue <l@damenly.su>
---
 fs/btrfs/disk-io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

David Sterba Feb. 12, 2021, 1:38 p.m. UTC | #1
On Thu, Feb 11, 2021 at 04:38:28PM +0800, Su Yue wrote:
> User reported that btrfs-progs misc-tests/028-superblock-recover fails:
>     [TEST/misc]   028-superblock-recover
> unexpected success: mounted fs with corrupted superblock
> test failed for case 028-superblock-recover
> 
> The test case expects that a broken image with bad superblock will be
> rejected to be mounted. However, the test image just passed csum check
> of superblock and was successfully mounted.
> 
> Commit 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size
> everywhere") replaces all calls to btrfs_super_csum_size by
> fs_info::csum_size. The calls include the place where fs_info->csum_size
> is not initialized. So btrfs_check_super_csum() passes because memcmp()
> with len 0 always returns 0.
> 
> Fix it by caching csum size in btrfs_fs_info::csum_size once we know the
> csum type in superblock is valid in open_ctree().
> 
> Link: https://github.com/kdave/btrfs-progs/issues/250
> Fixes: 55fc29bed8dd ("btrfs: use cached value of fs_info::csum_size everywhere")

That's a new commit in 5.11 and the bug looks serious, I'll need to send
one more pull request. Thanks for the fix.
diff mbox series

Patch

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6b35b7e88136..07a2b4f69b10 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3044,6 +3044,8 @@  int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 		goto fail_alloc;
 	}
 
+	fs_info->csum_size = btrfs_super_csum_size(disk_super);
+
 	ret = btrfs_init_csum_hash(fs_info, csum_type);
 	if (ret) {
 		err = ret;
@@ -3161,7 +3163,6 @@  int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 	fs_info->nodesize = nodesize;
 	fs_info->sectorsize = sectorsize;
 	fs_info->sectorsize_bits = ilog2(sectorsize);
-	fs_info->csum_size = btrfs_super_csum_size(disk_super);
 	fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;
 	fs_info->stripesize = stripesize;