Re: [syzbot] [btrfs?] general protection fault in write_all_supers

From: Qu Wenruo
Date: Wed Sep 18 2024 - 06:36:00 EST




在 2024/9/14 16:11, Lizhi Xu 写道:
if we have IGNOREDATACSUMS then don't need to backup csum root

#syz test

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a6f5441e62d1..415ad3b07032 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1679,7 +1679,6 @@ static void backup_super_roots(struct btrfs_fs_info *info)

if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
- struct btrfs_root *csum_root = btrfs_csum_root(info, 0);

btrfs_set_backup_extent_root(root_backup,
extent_root->node->start);
@@ -1688,11 +1687,15 @@ static void backup_super_roots(struct btrfs_fs_info *info)
btrfs_set_backup_extent_root_level(root_backup,
btrfs_header_level(extent_root->node));

- btrfs_set_backup_csum_root(root_backup, csum_root->node->start);
- btrfs_set_backup_csum_root_gen(root_backup,
- btrfs_header_generation(csum_root->node));
- btrfs_set_backup_csum_root_level(root_backup,
- btrfs_header_level(csum_root->node));
+ if (!btrfs_test_opt(info, IGNOREDATACSUMS)) {

This doesn't looks sane to me.

IGNOREDATACSUMS is only set with rescue=idatacsums mount option, which
relies the fs to be fully RO (not any writeback, including any log
replay), and it's not allowed to be remounted RW.

If we're hitting a missing csum root, and IGNOREDATACSUMS is applied
here, I'm wondering why we're even writing a super block.

This looks like a deeper problem, not just a NULL pointer dereference,
but some logic problem.

Thanks,
Qu

+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+ btrfs_set_backup_csum_root(root_backup, csum_root->node->start);
+ btrfs_set_backup_csum_root_gen(root_backup,
+ btrfs_header_generation(csum_root->node));
+ btrfs_set_backup_csum_root_level(root_backup,
+ btrfs_header_level(csum_root->node));
+ }
}

/*