mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-27 17:49:23 +00:00
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>
This commit is contained in:
1 parent
1443833a95
commit
66175696f3
1 file changed
+15
-2
+15
-2
@@ -41,6 +41,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|||||||
|
|
||||||
#define GRUB_JFS_TREE_LEAF 2
|
#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
|
struct grub_jfs_sblock
|
||||||
{
|
{
|
||||||
/* The magic for JFS. It should contain the string "JFS1". */
|
/* 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 freecnt;
|
||||||
grub_uint8_t freelist;
|
grub_uint8_t freelist;
|
||||||
grub_uint32_t idotdot;
|
grub_uint32_t idotdot;
|
||||||
grub_uint8_t sorted[8];
|
grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES];
|
||||||
} header;
|
} header;
|
||||||
struct grub_jfs_leaf_dirent dirents[8];
|
struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES];
|
||||||
} GRUB_PACKED dir;
|
} GRUB_PACKED dir;
|
||||||
/* Fast symlink. */
|
/* Fast symlink. */
|
||||||
struct
|
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. */
|
/* Check if the entire tree is contained within the inode. */
|
||||||
if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
|
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->leaf = inode->dir.dirents;
|
||||||
diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
|
diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
|
||||||
diro->sorted = inode->dir.header.sorted;
|
diro->sorted = inode->dir.header.sorted;
|
||||||
|
|||||||
Reference in new issue
Block a user