bcachefs: Check for subvolues with bogus snapshot/inode fields
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 20 May 2024 05:11:20 +0000 (01:11 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 20 May 2024 09:37:26 +0000 (05:37 -0400)
This fixes an assertion pop in btree_iter.c that checks for forgetting
to pass a snapshot ID when iterating over snapshots btrees.

Reported-by: syzbot+0dfe05235e38653e2aee@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/sb-errors_types.h
fs/bcachefs/subvolume.c

index 87324747351aae9397ec7f2d36da373306036411..666599d3fb9d7d1a684a1efa94f77eab2d9dc0bb 100644 (file)
        x(dup_backpointer_to_bad_csum_extent,                   265)    \
        x(btree_bitmap_not_marked,                              266)    \
        x(sb_clean_entry_overrun,                               267)    \
-       x(btree_ptr_v2_written_0,                               268)
+       x(btree_ptr_v2_written_0,                               268)    \
+       x(subvol_snapshot_bad,                                  269)    \
+       x(subvol_inode_bad,                                     270)
 
 enum bch_sb_error_id {
 #define x(t, n) BCH_FSCK_ERR_##t = n,
index 132213761ef6436c04ee96020d2fe297a6eb130c..dfc9cf305756f8c8e837a691d977d746183414fa 100644 (file)
@@ -210,12 +210,21 @@ int bch2_check_subvol_children(struct bch_fs *c)
 int bch2_subvolume_invalid(struct bch_fs *c, struct bkey_s_c k,
                           enum bch_validate_flags flags, struct printbuf *err)
 {
+       struct bkey_s_c_subvolume subvol = bkey_s_c_to_subvolume(k);
        int ret = 0;
 
        bkey_fsck_err_on(bkey_lt(k.k->p, SUBVOL_POS_MIN) ||
                         bkey_gt(k.k->p, SUBVOL_POS_MAX), c, err,
                         subvol_pos_bad,
                         "invalid pos");
+
+       bkey_fsck_err_on(!subvol.v->snapshot, c, err,
+                        subvol_snapshot_bad,
+                        "invalid snapshot");
+
+       bkey_fsck_err_on(!subvol.v->inode, c, err,
+                        subvol_inode_bad,
+                        "invalid inode");
 fsck_err:
        return ret;
 }