nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

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

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