0011-fs-jfs-Fix-OOB-read-in-jfs_getent.patch 2.4 KB

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