| From bd0cf8148ccf721f6e39ffbd70f8abad0c8897f0 Mon Sep 17 00:00:00 2001 |
| From: Daniel Axtens <dja@axtens.net> |
| Date: Mon, 18 Jan 2021 14:57:17 +1100 |
| Subject: [PATCH] fs/jfs: Limit the extents that getblk() can consider |
| |
| getblk() implicitly trusts that treehead->count is an accurate count of |
| the number of extents. However, that value is read from disk and is not |
| trustworthy, leading to OOB reads and crashes. I am not sure to what |
| extent the data read from OOB can influence subsequent program execution. |
| |
| Require callers to pass in the maximum number of extents for which |
| they have storage. |
| |
| Signed-off-by: Daniel Axtens <dja@axtens.net> |
| Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> |
| Signed-off-by: Stefan SΓΈrensen <stefan.sorensen@spectralink.com> |
| --- |
| grub-core/fs/jfs.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c |
| index e5bbda6..804c42d 100644 |
| --- a/grub-core/fs/jfs.c |
| +++ b/grub-core/fs/jfs.c |
| @@ -261,13 +261,15 @@ static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint |
| static grub_int64_t |
| getblk (struct grub_jfs_treehead *treehead, |
| struct grub_jfs_tree_extent *extents, |
| + int max_extents, |
| struct grub_jfs_data *data, |
| grub_uint64_t blk) |
| { |
| int found = -1; |
| int i; |
| |
| - for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) |
| + for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 && |
| + i < max_extents; i++) |
| { |
| if (treehead->flags & GRUB_JFS_TREE_LEAF) |
| { |
| @@ -302,7 +304,7 @@ getblk (struct grub_jfs_treehead *treehead, |
| << (grub_le_to_cpu16 (data->sblock.log2_blksz) |
| - GRUB_DISK_SECTOR_BITS), 0, |
| sizeof (*tree), (char *) tree)) |
| - ret = getblk (&tree->treehead, &tree->extents[0], data, blk); |
| + ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk); |
| grub_free (tree); |
| return ret; |
| } |
| @@ -316,7 +318,7 @@ static grub_int64_t |
| grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, |
| grub_uint64_t blk) |
| { |
| - return getblk (&inode->file.tree, &inode->file.extents[0], data, blk); |
| + return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk); |
| } |
| |
| |
| -- |
| 2.14.2 |
| |