Skip to content

Commit 33eb5b3

Browse files
danobigregkh
authored andcommitted
btrfs: tree-checker: validate number of chunk stripes and parity
commit 85d07fb upstream. If there's no parity and num_stripes < ncopies, a crafted image can trigger a division by zero in calc_stripe_length(). The image was generated through fuzzing. CC: stable@vger.kernel.org # 5.4+ Reviewed-by: Qu Wenruo <wqu@suse.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=209587 Signed-off-by: Daniel Xu <dxu@dxuuu.xyz> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 0cb097f commit 33eb5b3

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

fs/btrfs/tree-checker.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,18 +760,36 @@ int btrfs_check_chunk_valid(struct extent_buffer *leaf,
760760
u64 type;
761761
u64 features;
762762
bool mixed = false;
763+
int raid_index;
764+
int nparity;
765+
int ncopies;
763766

764767
length = btrfs_chunk_length(leaf, chunk);
765768
stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
766769
num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
767770
sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
768771
type = btrfs_chunk_type(leaf, chunk);
772+
raid_index = btrfs_bg_flags_to_raid_index(type);
773+
ncopies = btrfs_raid_array[raid_index].ncopies;
774+
nparity = btrfs_raid_array[raid_index].nparity;
769775

770776
if (!num_stripes) {
771777
chunk_err(leaf, chunk, logical,
772778
"invalid chunk num_stripes, have %u", num_stripes);
773779
return -EUCLEAN;
774780
}
781+
if (num_stripes < ncopies) {
782+
chunk_err(leaf, chunk, logical,
783+
"invalid chunk num_stripes < ncopies, have %u < %d",
784+
num_stripes, ncopies);
785+
return -EUCLEAN;
786+
}
787+
if (nparity && num_stripes == nparity) {
788+
chunk_err(leaf, chunk, logical,
789+
"invalid chunk num_stripes == nparity, have %u == %d",
790+
num_stripes, nparity);
791+
return -EUCLEAN;
792+
}
775793
if (!IS_ALIGNED(logical, fs_info->sectorsize)) {
776794
chunk_err(leaf, chunk, logical,
777795
"invalid chunk logical, have %llu should aligned to %u",

0 commit comments

Comments
 (0)