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