0105-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. From 2ca0e5dbcdcb6fc93ccae39a0f39d0dba4a7ff20 Mon Sep 17 00:00:00 2001
  2. From: Daniel Axtens <dja@axtens.net>
  3. Date: Tue, 2 Feb 2021 16:59:35 +1100
  4. Subject: [PATCH] fs/hfsplus: Don't use uninitialized data on corrupt
  5. filesystems
  6. Valgrind identified the following use of uninitialized data:
  7. ==2782220== Conditional jump or move depends on uninitialised value(s)
  8. ==2782220== at 0x42B364: grub_hfsplus_btree_search (hfsplus.c:566)
  9. ==2782220== by 0x42B21D: grub_hfsplus_read_block (hfsplus.c:185)
  10. ==2782220== by 0x42A693: grub_fshelp_read_file (fshelp.c:386)
  11. ==2782220== by 0x42C598: grub_hfsplus_read_file (hfsplus.c:219)
  12. ==2782220== by 0x42C598: grub_hfsplus_mount (hfsplus.c:330)
  13. ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
  14. ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73)
  15. ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186)
  16. ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284)
  17. ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
  18. ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59)
  19. ==2782220== by 0x4045A6: fstest (grub-fstest.c:433)
  20. ==2782220== by 0x4045A6: main (grub-fstest.c:772)
  21. ==2782220== Uninitialised value was created by a heap allocation
  22. ==2782220== at 0x483C7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  23. ==2782220== by 0x4C0305: grub_malloc (mm.c:42)
  24. ==2782220== by 0x42C21D: grub_hfsplus_mount (hfsplus.c:239)
  25. ==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
  26. ==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73)
  27. ==2782220== by 0x407C94: grub_ls_list_files (ls.c:186)
  28. ==2782220== by 0x407C94: grub_cmd_ls (ls.c:284)
  29. ==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
  30. ==2782220== by 0x4045A6: execute_command (grub-fstest.c:59)
  31. ==2782220== by 0x4045A6: fstest (grub-fstest.c:433)
  32. ==2782220== by 0x4045A6: main (grub-fstest.c:772)
  33. This happens when the process of reading the catalog file goes sufficiently
  34. wrong that there's an attempt to read the extent overflow file, which has
  35. not yet been loaded. Keep track of when the extent overflow file is
  36. fully loaded and refuse to use it before then.
  37. The load valgrind doesn't like is btree->nodesize, and that's then used
  38. to allocate a data structure. It looks like there are subsequently a lot
  39. of reads based on that pointer so OOB reads are likely, and indeed crashes
  40. (albeit difficult-to-replicate ones) have been observed in fuzzing.
  41. Signed-off-by: Daniel Axtens <dja@axtens.net>
  42. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  43. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
  44. ---
  45. grub-core/fs/hfsplus.c | 14 ++++++++++++++
  46. include/grub/hfsplus.h | 2 ++
  47. 2 files changed, 16 insertions(+)
  48. diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
  49. index 1c7791b..361e5be 100644
  50. --- a/grub-core/fs/hfsplus.c
  51. +++ b/grub-core/fs/hfsplus.c
  52. @@ -177,6 +177,17 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
  53. break;
  54. }
  55. + /*
  56. + * If the extent overflow tree isn't ready yet, we can't look
  57. + * in it. This can happen where the catalog file is corrupted.
  58. + */
  59. + if (!node->data->extoverflow_tree_ready)
  60. + {
  61. + grub_error (GRUB_ERR_BAD_FS,
  62. + "attempted to read extent overflow tree before loading");
  63. + break;
  64. + }
  65. +
  66. /* Set up the key to look for in the extent overflow file. */
  67. extoverflow.extkey.fileid = node->fileid;
  68. extoverflow.extkey.type = 0;
  69. @@ -241,6 +252,7 @@ grub_hfsplus_mount (grub_disk_t disk)
  70. return 0;
  71. data->disk = disk;
  72. + data->extoverflow_tree_ready = 0;
  73. /* Read the bootblock. */
  74. grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
  75. @@ -357,6 +369,8 @@ grub_hfsplus_mount (grub_disk_t disk)
  76. if (data->extoverflow_tree.nodesize < 2)
  77. goto fail;
  78. + data->extoverflow_tree_ready = 1;
  79. +
  80. if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0,
  81. sizeof (struct grub_hfsplus_btnode),
  82. sizeof (header), (char *) &header) <= 0)
  83. diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h
  84. index 117740a..e14dd31 100644
  85. --- a/include/grub/hfsplus.h
  86. +++ b/include/grub/hfsplus.h
  87. @@ -113,6 +113,8 @@ struct grub_hfsplus_data
  88. struct grub_hfsplus_btree extoverflow_tree;
  89. struct grub_hfsplus_btree attr_tree;
  90. + int extoverflow_tree_ready;
  91. +
  92. struct grub_hfsplus_file dirroot;
  93. struct grub_hfsplus_file opened_file;
  94. --
  95. 2.14.2