1From bd0cf8148ccf721f6e39ffbd70f8abad0c8897f0 Mon Sep 17 00:00:00 2001
2From: Daniel Axtens <dja@axtens.net>
3Date: Mon, 18 Jan 2021 14:57:17 +1100
4Subject: [PATCH] fs/jfs: Limit the extents that getblk() can consider
5
6getblk() implicitly trusts that treehead->count is an accurate count of
7the number of extents. However, that value is read from disk and is not
8trustworthy, leading to OOB reads and crashes. I am not sure to what
9extent the data read from OOB can influence subsequent program execution.
10
11Require callers to pass in the maximum number of extents for which
12they have storage.
13
14Signed-off-by: Daniel Axtens <dja@axtens.net>
15Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
16Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
17---
18 grub-core/fs/jfs.c | 8 +++++---
19 1 file changed, 5 insertions(+), 3 deletions(-)
20
21diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
22index e5bbda6..804c42d 100644
23--- a/grub-core/fs/jfs.c
24+++ b/grub-core/fs/jfs.c
25@@ -261,13 +261,15 @@ static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint
26 static grub_int64_t
27 getblk (struct grub_jfs_treehead *treehead,
28 	struct grub_jfs_tree_extent *extents,
29+	int max_extents,
30 	struct grub_jfs_data *data,
31 	grub_uint64_t blk)
32 {
33   int found = -1;
34   int i;
35
36-  for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
37+  for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 &&
38+	      i < max_extents; i++)
39     {
40       if (treehead->flags & GRUB_JFS_TREE_LEAF)
41 	{
42@@ -302,7 +304,7 @@ getblk (struct grub_jfs_treehead *treehead,
43 			   << (grub_le_to_cpu16 (data->sblock.log2_blksz)
44 			       - GRUB_DISK_SECTOR_BITS), 0,
45 			   sizeof (*tree), (char *) tree))
46-	ret = getblk (&tree->treehead, &tree->extents[0], data, blk);
47+	ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk);
48       grub_free (tree);
49       return ret;
50     }
51@@ -316,7 +318,7 @@ static grub_int64_t
52 grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
53 		grub_uint64_t blk)
54 {
55-  return getblk (&inode->file.tree, &inode->file.extents[0], data, blk);
56+  return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk);
57 }
58
59
60--
612.14.2
62
63