Blame SOURCES/0245-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch

b35c50
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b35c50
From: Darren Kenny <darren.kenny@oracle.com>
b35c50
Date: Thu, 7 Apr 2022 15:18:12 +0000
b35c50
Subject: [PATCH] fs/btrfs: Fix more fuzz issues related to chunks
b35c50
b35c50
The corpus we generating issues in grub_btrfs_read_logical() when
b35c50
attempting to iterate over nstripes entries in the boot mapping.
b35c50
b35c50
In most cases the reason for the failure was that the number of strips
b35c50
exceeded the possible space statically allocated in superblock bootmapping
b35c50
space. Each stripe entry in the bootmapping block consists of
b35c50
a grub_btrfs_key followed by a grub_btrfs_chunk_stripe.
b35c50
b35c50
Another issue that came up was that while calculating the chunk size,
b35c50
in an earlier piece of code in that function, depending on the data
b35c50
provided in the btrfs file system, it would end up calculating a size
b35c50
that was too small to contain even 1 grub_btrfs_chunk_item, which is
b35c50
obviously invalid too.
b35c50
b35c50
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
b35c50
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
b35c50
(cherry picked from commit e00cd76cbadcc897a9cc4087cb2fcb5dbe15e596)
b35c50
---
b35c50
 grub-core/fs/btrfs.c | 24 ++++++++++++++++++++++++
b35c50
 1 file changed, 24 insertions(+)
b35c50
b35c50
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
b35c50
index 0e9b450413..47325f6ad7 100644
b35c50
--- a/grub-core/fs/btrfs.c
b35c50
+++ b/grub-core/fs/btrfs.c
b35c50
@@ -947,6 +947,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
b35c50
 	  return grub_error (GRUB_ERR_BAD_FS,
b35c50
 			     "got an invalid zero-size chunk");
b35c50
 	}
b35c50
+
b35c50
+      /*
b35c50
+       * The space being allocated for a chunk should at least be able to
b35c50
+       * contain one chunk item.
b35c50
+       */
b35c50
+      if (chsize < sizeof (struct grub_btrfs_chunk_item))
b35c50
+       {
b35c50
+         grub_dprintf ("btrfs", "chunk-size too small\n");
b35c50
+         return grub_error (GRUB_ERR_BAD_FS,
b35c50
+                            "got an invalid chunk size");
b35c50
+       }
b35c50
       chunk = grub_malloc (chsize);
b35c50
       if (!chunk)
b35c50
 	return grub_errno;
b35c50
@@ -1194,6 +1205,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
b35c50
 	if (csize > (grub_uint64_t) size)
b35c50
 	  csize = size;
b35c50
 
b35c50
+	/*
b35c50
+	 * The space for a chunk stripe is limited to the space provide in the super-block's
b35c50
+	 * bootstrap mapping with an initial btrfs key at the start of each chunk.
b35c50
+	 */
b35c50
+	grub_size_t avail_stripes = sizeof (data->sblock.bootstrap_mapping) /
b35c50
+	  (sizeof (struct grub_btrfs_key) + sizeof (struct grub_btrfs_chunk_stripe));
b35c50
+
b35c50
 	for (j = 0; j < 2; j++)
b35c50
 	  {
b35c50
 	    grub_size_t est_chunk_alloc = 0;
b35c50
@@ -1220,6 +1238,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
b35c50
 		break;
b35c50
 	      }
b35c50
 
b35c50
+	   if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes)
b35c50
+             {
b35c50
+               err = GRUB_ERR_BAD_FS;
b35c50
+               break;
b35c50
+             }
b35c50
+
b35c50
 	    if (is_raid56)
b35c50
 	      {
b35c50
 		err = btrfs_read_from_chunk (data, chunk, stripen,