summaryrefslogtreecommitdiffstats
path: root/debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch')
-rw-r--r--debian/patches/0092-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch75
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,