1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- From b01accc4d132a252f02bf57c31f5fff8ce98a339 Mon Sep 17 00:00:00 2001
- From: Lidong Chen <lidong.chen@oracle.com>
- Date: Fri, 22 Nov 2024 06:27:59 +0000
- Subject: [PATCH] fs/jfs: Fix OOB read in jfs_getent()
- The JFS fuzzing revealed an OOB read in grub_jfs_getent(). The crash
- was caused by an invalid leaf nodes count, diro->dirpage->header.count,
- which was larger than the maximum number of leaf nodes allowed in an
- inode. This fix is to ensure that the leaf nodes count is validated in
- grub_jfs_opendir() before calling grub_jfs_getent().
- On the occasion replace existing raw numbers with newly defined constant.
- Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
- Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
- Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
- Upstream: 66175696f3a385b14bdf1ebcda7755834bd2d5fb
- Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
- ---
- grub-core/fs/jfs.c | 17 +++++++++++++++--
- 1 file changed, 15 insertions(+), 2 deletions(-)
- diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
- index 6f7c43904..32dec7fb7 100644
- --- a/grub-core/fs/jfs.c
- +++ b/grub-core/fs/jfs.c
- @@ -41,6 +41,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
-
- #define GRUB_JFS_TREE_LEAF 2
-
- +/*
- + * Define max entries stored in-line in an inode.
- + * https://jfs.sourceforge.net/project/pub/jfslayout.pdf
- + */
- +#define GRUB_JFS_INODE_INLINE_ENTRIES 8
- +
- struct grub_jfs_sblock
- {
- /* The magic for JFS. It should contain the string "JFS1". */
- @@ -203,9 +209,9 @@ struct grub_jfs_inode
- grub_uint8_t freecnt;
- grub_uint8_t freelist;
- grub_uint32_t idotdot;
- - grub_uint8_t sorted[8];
- + grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES];
- } header;
- - struct grub_jfs_leaf_dirent dirents[8];
- + struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES];
- } GRUB_PACKED dir;
- /* Fast symlink. */
- struct
- @@ -453,6 +459,13 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
- /* Check if the entire tree is contained within the inode. */
- if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
- {
- + if (inode->dir.header.count > GRUB_JFS_INODE_INLINE_ENTRIES)
- + {
- + grub_free (diro);
- + grub_error (GRUB_ERR_BAD_FS, N_("invalid JFS inode"));
- + return 0;
- + }
- +
- diro->leaf = inode->dir.dirents;
- diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
- diro->sorted = inode->dir.header.sorted;
- --
- 2.50.1
|