b1bcb2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b1bcb2
From: Daniel Axtens <dja@axtens.net>
b1bcb2
Date: Mon, 18 Jan 2021 14:34:58 +1100
b1bcb2
Subject: [PATCH] fs/sfs: Fix over-read of root object name
b1bcb2
b1bcb2
There's a read of the name of the root object that assumes that the name
b1bcb2
is nul-terminated within the root block. This isn't guaranteed - it seems
b1bcb2
SFS would require you to read multiple blocks to get a full name in general,
b1bcb2
but maybe that doesn't apply to the root object.
b1bcb2
b1bcb2
Either way, figure out how much space is left in the root block and don't
b1bcb2
over-read it. This fixes some OOB reads.
b1bcb2
b1bcb2
Signed-off-by: Daniel Axtens <dja@axtens.net>
b1bcb2
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
b1bcb2
---
b1bcb2
 grub-core/fs/sfs.c | 9 ++++++++-
b1bcb2
 1 file changed, 8 insertions(+), 1 deletion(-)
b1bcb2
b1bcb2
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
b1bcb2
index 4f68808a891..bba600429bb 100644
b1bcb2
--- a/grub-core/fs/sfs.c
b1bcb2
+++ b/grub-core/fs/sfs.c
b1bcb2
@@ -368,6 +368,7 @@ grub_sfs_mount (grub_disk_t disk)
b1bcb2
   struct grub_sfs_objc *rootobjc;
b1bcb2
   char *rootobjc_data = 0;
b1bcb2
   grub_uint32_t blk;
b1bcb2
+  unsigned int max_len;
b1bcb2
 
b1bcb2
   data = grub_malloc (sizeof (*data));
b1bcb2
   if (!data)
b1bcb2
@@ -416,7 +417,13 @@ grub_sfs_mount (grub_disk_t disk)
b1bcb2
   data->diropen.data = data;
b1bcb2
   data->diropen.cache = 0;
b1bcb2
   data->disk = disk;
b1bcb2
-  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
b1bcb2
+
b1bcb2
+  /* We only read 1 block of data, so truncate the name if needed. */
b1bcb2
+  max_len = ((GRUB_DISK_SECTOR_SIZE << data->log_blocksize)
b1bcb2
+	     - 24    /* offsetof (struct grub_sfs_objc, objects) */
b1bcb2
+	     - 25);  /* offsetof (struct grub_sfs_obj, filename) */
b1bcb2
+  data->label = grub_zalloc (max_len + 1);
b1bcb2
+  grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len);
b1bcb2
 
b1bcb2
   grub_free (rootobjc_data);
b1bcb2
   return data;