0006-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. From 472e180b6aac8cb4f25affa687e68f9be4e3df79 Mon Sep 17 00:00:00 2001
  2. From: Lidong Chen <lidong.chen@oracle.com>
  3. Date: Fri, 22 Nov 2024 06:27:58 +0000
  4. Subject: [PATCH] fs/tar: Integer overflow leads to heap OOB write
  5. Both namesize and linksize are derived from hd.size, a 12-digit octal
  6. number parsed by read_number(). Later direct arithmetic calculation like
  7. "namesize + 1" and "linksize + 1" may exceed the maximum value of
  8. grub_size_t leading to heap OOB write. This patch fixes the issue by
  9. using grub_add() and checking for an overflow.
  10. Fixes: CVE-2024-45780
  11. Reported-by: Nils Langius <nils@langius.de>
  12. Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
  13. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  14. Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
  15. Upstream: 0087bc6902182fe5cedce2d034c75a79cf6dd4f3
  16. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  17. ---
  18. grub-core/fs/tar.c | 23 ++++++++++++++++++-----
  19. 1 file changed, 18 insertions(+), 5 deletions(-)
  20. diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
  21. index 646bce5eb..386c09022 100644
  22. --- a/grub-core/fs/tar.c
  23. +++ b/grub-core/fs/tar.c
  24. @@ -25,6 +25,7 @@
  25. #include <grub/mm.h>
  26. #include <grub/dl.h>
  27. #include <grub/i18n.h>
  28. +#include <grub/safemath.h>
  29. GRUB_MOD_LICENSE ("GPLv3+");
  30. @@ -76,6 +77,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  31. {
  32. struct head hd;
  33. int reread = 0, have_longname = 0, have_longlink = 0;
  34. + grub_size_t sz;
  35. data->hofs = data->next_hofs;
  36. *name = NULL;
  37. @@ -98,7 +100,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  38. {
  39. grub_err_t err;
  40. grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
  41. - *name = grub_malloc (namesize + 1);
  42. +
  43. + if (grub_add (namesize, 1, &sz))
  44. + return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
  45. +
  46. + *name = grub_malloc (sz);
  47. if (*name == NULL)
  48. return grub_errno;
  49. err = grub_disk_read (data->disk, 0,
  50. @@ -118,15 +124,19 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  51. {
  52. grub_err_t err;
  53. grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
  54. - if (data->linkname_alloc < linksize + 1)
  55. +
  56. + if (grub_add (linksize, 1, &sz))
  57. + return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
  58. +
  59. + if (data->linkname_alloc < sz)
  60. {
  61. char *n;
  62. - n = grub_calloc (2, linksize + 1);
  63. + n = grub_calloc (2, sz);
  64. if (!n)
  65. return grub_errno;
  66. grub_free (data->linkname);
  67. data->linkname = n;
  68. - data->linkname_alloc = 2 * (linksize + 1);
  69. + data->linkname_alloc = 2 * (sz);
  70. }
  71. err = grub_disk_read (data->disk, 0,
  72. @@ -149,7 +159,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  73. while (extra_size < sizeof (hd.prefix)
  74. && hd.prefix[extra_size])
  75. extra_size++;
  76. - *name = grub_malloc (sizeof (hd.name) + extra_size + 2);
  77. +
  78. + if (grub_add (sizeof (hd.name) + 2, extra_size, &sz))
  79. + return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow"));
  80. + *name = grub_malloc (sz);
  81. if (*name == NULL)
  82. return grub_errno;
  83. if (hd.prefix[0])
  84. --
  85. 2.50.1