Skip to content

Commit

Permalink
bcachefs: Check for extent crc uncompressed/compressed size mismatch
Browse files Browse the repository at this point in the history
When not compressed, these must be equal - this fixes an assertion pop
in bch2_rechecksum_bio().

Reported-by: syzbot+50d3544c9b8db9c99fd2@syzkaller.appspotmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
  • Loading branch information
Kent Overstreet committed Nov 29, 2024
1 parent c1e3758 commit 2d5a193
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
22 changes: 13 additions & 9 deletions fs/bcachefs/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,16 +1323,26 @@ int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k,
case BCH_EXTENT_ENTRY_crc128:
crc = bch2_extent_crc_unpack(k.k, entry_to_crc(entry));

bkey_fsck_err_on(crc.offset + crc.live_size > crc.uncompressed_size,
c, ptr_crc_uncompressed_size_too_small,
"checksum offset + key size > uncompressed size");
bkey_fsck_err_on(!bch2_checksum_type_valid(c, crc.csum_type),
c, ptr_crc_csum_type_unknown,
"invalid checksum type");
bkey_fsck_err_on(crc.compression_type >= BCH_COMPRESSION_TYPE_NR,
c, ptr_crc_compression_type_unknown,
"invalid compression type");

bkey_fsck_err_on(crc.offset + crc.live_size > crc.uncompressed_size,
c, ptr_crc_uncompressed_size_too_small,
"checksum offset + key size > uncompressed size");
bkey_fsck_err_on(crc_is_encoded(crc) &&
(crc.uncompressed_size > c->opts.encoded_extent_max >> 9) &&
(from.flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)),
c, ptr_crc_uncompressed_size_too_big,
"too large encoded extent");
bkey_fsck_err_on(!crc_is_compressed(crc) &&
crc.compressed_size != crc.uncompressed_size,
c, ptr_crc_uncompressed_size_mismatch,
"not compressed but compressed != uncompressed size");

if (bch2_csum_type_is_encryption(crc.csum_type)) {
if (nonce == UINT_MAX)
nonce = crc.offset + crc.nonce;
Expand All @@ -1346,12 +1356,6 @@ int bch2_bkey_ptrs_validate(struct bch_fs *c, struct bkey_s_c k,
"redundant crc entry");
crc_since_last_ptr = true;

bkey_fsck_err_on(crc_is_encoded(crc) &&
(crc.uncompressed_size > c->opts.encoded_extent_max >> 9) &&
(from.flags & (BCH_VALIDATE_write|BCH_VALIDATE_commit)),
c, ptr_crc_uncompressed_size_too_big,
"too large encoded extent");

size_ondisk = crc.compressed_size;
break;
case BCH_EXTENT_ENTRY_stripe_ptr:
Expand Down
5 changes: 3 additions & 2 deletions fs/bcachefs/sb-errors_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,11 @@ enum bch_fsck_flags {
x(ptr_bucket_data_type_mismatch, 155, 0) \
x(ptr_cached_and_erasure_coded, 156, 0) \
x(ptr_crc_uncompressed_size_too_small, 157, 0) \
x(ptr_crc_uncompressed_size_too_big, 161, 0) \
x(ptr_crc_uncompressed_size_mismatch, 300, 0) \
x(ptr_crc_csum_type_unknown, 158, 0) \
x(ptr_crc_compression_type_unknown, 159, 0) \
x(ptr_crc_redundant, 160, 0) \
x(ptr_crc_uncompressed_size_too_big, 161, 0) \
x(ptr_crc_nonce_mismatch, 162, 0) \
x(ptr_stripe_redundant, 163, 0) \
x(reservation_key_nr_replicas_invalid, 164, 0) \
Expand Down Expand Up @@ -310,7 +311,7 @@ enum bch_fsck_flags {
x(logged_op_but_clean, 283, FSCK_AUTOFIX) \
x(compression_opt_not_marked_in_sb, 295, FSCK_AUTOFIX) \
x(compression_type_not_marked_in_sb, 296, FSCK_AUTOFIX) \
x(MAX, 300, 0)
x(MAX, 301, 0)

enum bch_sb_error_id {
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,
Expand Down

0 comments on commit 2d5a193

Please sign in to comment.