]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jan 2023 16:18:17 +0000 (17:18 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jan 2023 16:18:17 +0000 (17:18 +0100)
added patches:
btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch

queue-6.0/btrfs-make-thaw-time-super-block-check-to-also-verify-checksum.patch [new file with mode: 0644]
queue-6.0/series

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 (file)
index 0000000..ea7cbda
--- /dev/null
@@ -0,0 +1,117 @@
+From 3d17adea74a56a4965f7a603d8ed8c66bb9356d9 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 18 Oct 2022 09:56:38 +0800
+Subject: btrfs: make thaw time super block check to also verify checksum
+
+From: Qu Wenruo <wqu@suse.com>
+
+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 <johannes.thumshirn@wdc.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
index f9dda7781a9353542b2ce674f91bff593b9dcbb2..ae60c8fd987a803833fb167a690cf282c4786fa7 100644 (file)
@@ -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