From 7b2cc243a8823a34e167075a32d8511e1b2e21d8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Jan 2023 17:18:17 +0100 Subject: [PATCH] 6.0-stable patches added patches: btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch --- ...-block-check-to-also-verify-checksum.patch | 117 ++++++++++++++++++ queue-6.0/series | 1 + 2 files changed, 118 insertions(+) create mode 100644 queue-6.0/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch diff --git a/queue-6.0/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch b/queue-6.0/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch new file mode 100644 index 00000000000..ea7cbda30e3 --- /dev/null +++ b/queue-6.0/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch @@ -0,0 +1,117 @@ +From 3d17adea74a56a4965f7a603d8ed8c66bb9356d9 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Tue, 18 Oct 2022 09:56:38 +0800 +Subject: btrfs: make thaw time super block check to also verify checksum + +From: Qu Wenruo + +commit 3d17adea74a56a4965f7a603d8ed8c66bb9356d9 upstream. + +Previous commit a05d3c915314 ("btrfs: check superblock to ensure the fs +was not modified at thaw time") only checks the content of the super +block, but it doesn't really check if the on-disk super block has a +matching checksum. + +This patch will add the checksum verification to thaw time superblock +verification. + +This involves the following extra changes: + +- Export btrfs_check_super_csum() + As we need to call it in super.c. + +- Change the argument list of btrfs_check_super_csum() + Instead of passing a char *, directly pass struct btrfs_super_block * + pointer. + +- Verify that our checksum type didn't change before checking the + checksum value, like it's done at mount time + +Fixes: a05d3c915314 ("btrfs: check superblock to ensure the fs was not modified at thaw time") +Reviewed-by: Johannes Thumshirn +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/disk-io.c | 10 ++++------ + fs/btrfs/disk-io.h | 2 ++ + fs/btrfs/super.c | 16 ++++++++++++++++ + 3 files changed, 22 insertions(+), 6 deletions(-) + +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -167,11 +167,9 @@ static bool btrfs_supported_super_csum(u + * Return 0 if the superblock checksum type matches the checksum value of that + * algorithm. Pass the raw disk superblock data. + */ +-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, +- char *raw_disk_sb) ++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, ++ const struct btrfs_super_block *disk_sb) + { +- struct btrfs_super_block *disk_sb = +- (struct btrfs_super_block *)raw_disk_sb; + char result[BTRFS_CSUM_SIZE]; + SHASH_DESC_ON_STACK(shash, fs_info->csum_shash); + +@@ -182,7 +180,7 @@ static int btrfs_check_super_csum(struct + * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is + * filled with zeros and is included in the checksum. + */ +- crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE, ++ crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE, + BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result); + + if (memcmp(disk_sb->csum, result, fs_info->csum_size)) +@@ -3471,7 +3469,7 @@ int __cold open_ctree(struct super_block + * We want to check superblock checksum, the type is stored inside. + * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k). + */ +- if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) { ++ if (btrfs_check_super_csum(fs_info, disk_super)) { + btrfs_err(fs_info, "superblock checksum mismatch"); + err = -EINVAL; + btrfs_release_disk_super(disk_super); +--- a/fs/btrfs/disk-io.h ++++ b/fs/btrfs/disk-io.h +@@ -42,6 +42,8 @@ struct extent_buffer *btrfs_find_create_ + void btrfs_clean_tree_block(struct extent_buffer *buf); + void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info); + int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info); ++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info, ++ const struct btrfs_super_block *disk_sb); + int __cold open_ctree(struct super_block *sb, + struct btrfs_fs_devices *fs_devices, + char *options); +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2553,6 +2553,7 @@ static int check_dev_super(struct btrfs_ + { + struct btrfs_fs_info *fs_info = dev->fs_info; + struct btrfs_super_block *sb; ++ u16 csum_type; + int ret = 0; + + /* This should be called with fs still frozen. */ +@@ -2567,6 +2568,21 @@ static int check_dev_super(struct btrfs_ + if (IS_ERR(sb)) + return PTR_ERR(sb); + ++ /* Verify the checksum. */ ++ csum_type = btrfs_super_csum_type(sb); ++ if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) { ++ btrfs_err(fs_info, "csum type changed, has %u expect %u", ++ csum_type, btrfs_super_csum_type(fs_info->super_copy)); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ ++ if (btrfs_check_super_csum(fs_info, sb)) { ++ btrfs_err(fs_info, "csum for on-disk super block no longer matches"); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ + /* Btrfs_validate_super() includes fsid check against super->fsid. */ + ret = btrfs_validate_super(fs_info, sb, 0); + if (ret < 0) diff --git a/queue-6.0/series b/queue-6.0/series index f9dda7781a9..ae60c8fd987 100644 --- a/queue-6.0/series +++ b/queue-6.0/series @@ -143,3 +143,4 @@ btrfs-handle-case-when-repair-happens-with-dev-repla.patch ksmbd-fix-infinite-loop-in-ksmbd_conn_handler_loop.patch ksmbd-send-proper-error-response-in-smb2_tree_connect.patch ksmbd-check-nt_len-to-be-at-least-cifs_encpwd_size-in-ksmbd_decode_ntlmssp_auth_blob.patch +btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch -- 2.47.3