diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch b/debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch new file mode 100644 index 0000000..30c2dad --- /dev/null +++ b/debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch @@ -0,0 +1,75 @@ +From 589500ad3777d1335c8e5cb139f7c0c6089112a8 Mon Sep 17 00:00:00 2001 +From: Darren Kenny <darren.kenny@oracle.com> +Date: Thu, 7 Apr 2022 15:18:12 +0000 +Subject: fs/btrfs: Fix more fuzz issues related to chunks + +The corpus was generating issues in grub_btrfs_read_logical() when +attempting to iterate over stripe entries in the superblock's +bootmapping. + +In most cases the reason for the failure was that the number of stripes +in chunk->nstripes exceeded the possible space statically allocated in +superblock bootmapping space. Each stripe entry in the bootmapping block +consists of a grub_btrfs_key followed by a grub_btrfs_chunk_stripe. + +Another issue that came up was that while calculating the chunk size, +in an earlier piece of code in that function, depending on the data +provided in the btrfs file system, it would end up calculating a size +that was too small to contain even 1 grub_btrfs_chunk_item, which is +obviously invalid too. + +Signed-off-by: Darren Kenny <darren.kenny@oracle.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> +--- + grub-core/fs/btrfs.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index b3d71cd9e..54a46b8f8 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -918,6 +918,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + return grub_error (GRUB_ERR_BAD_FS, + "got an invalid zero-size chunk"); + } ++ ++ /* ++ * The space being allocated for a chunk should at least be able to ++ * contain one chunk item. ++ */ ++ if (chsize < sizeof (struct grub_btrfs_chunk_item)) ++ { ++ grub_dprintf ("btrfs", "chunk-size too small\n"); ++ return grub_error (GRUB_ERR_BAD_FS, ++ "got an invalid chunk size"); ++ } + chunk = grub_malloc (chsize); + if (!chunk) + return grub_errno; +@@ -1165,6 +1176,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + if (csize > (grub_uint64_t) size) + csize = size; + ++ /* ++ * The space for a chunk stripe is limited to the space provide in the super-block's ++ * bootstrap mapping with an initial btrfs key at the start of each chunk. ++ */ ++ grub_size_t avail_stripes = sizeof (data->sblock.bootstrap_mapping) / ++ (sizeof (struct grub_btrfs_key) + sizeof (struct grub_btrfs_chunk_stripe)); ++ + for (j = 0; j < 2; j++) + { + grub_size_t est_chunk_alloc = 0; +@@ -1191,6 +1209,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, + break; + } + ++ if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes) ++ { ++ err = GRUB_ERR_BAD_FS; ++ break; ++ } ++ + if (is_raid56) + { + err = btrfs_read_from_chunk (data, chunk, stripen, |