0122-disk-lvm-Do-not-overread-metadata.patch 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. From 1155d7dffd3337942cb7583706b429d567d4db86 Mon Sep 17 00:00:00 2001
  2. From: Daniel Axtens <dja@axtens.net>
  3. Date: Thu, 21 Jan 2021 18:35:22 +1100
  4. Subject: [PATCH] disk/lvm: Do not overread metadata
  5. We could reach the end of valid metadata and not realize, leading to
  6. some buffer overreads. Check if we have reached the end and bail.
  7. Signed-off-by: Daniel Axtens <dja@axtens.net>
  8. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  9. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
  10. ---
  11. grub-core/disk/lvm.c | 31 +++++++++++++++++++++++++------
  12. 1 file changed, 25 insertions(+), 6 deletions(-)
  13. diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
  14. index bd5ae87..742ecd6 100644
  15. --- a/grub-core/disk/lvm.c
  16. +++ b/grub-core/disk/lvm.c
  17. @@ -313,17 +313,23 @@ grub_lvm_detect (grub_disk_t disk,
  18. while (1)
  19. {
  20. grub_ssize_t s;
  21. - while (grub_isspace (*p))
  22. + while (grub_isspace (*p) && p < mda_end)
  23. p++;
  24. + if (p == mda_end)
  25. + goto fail4;
  26. +
  27. if (*p == '}')
  28. break;
  29. pv = grub_zalloc (sizeof (*pv));
  30. q = p;
  31. - while (*q != ' ')
  32. + while (*q != ' ' && q < mda_end)
  33. q++;
  34. + if (q == mda_end)
  35. + goto pvs_fail_noname;
  36. +
  37. s = q - p;
  38. pv->name = grub_malloc (s + 1);
  39. grub_memcpy (pv->name, p, s);
  40. @@ -366,6 +372,7 @@ grub_lvm_detect (grub_disk_t disk,
  41. continue;
  42. pvs_fail:
  43. grub_free (pv->name);
  44. + pvs_fail_noname:
  45. grub_free (pv);
  46. goto fail4;
  47. }
  48. @@ -387,18 +394,24 @@ grub_lvm_detect (grub_disk_t disk,
  49. struct grub_diskfilter_segment *seg;
  50. int is_pvmove;
  51. - while (grub_isspace (*p))
  52. + while (grub_isspace (*p) && p < mda_end)
  53. p++;
  54. + if (p == mda_end)
  55. + goto fail4;
  56. +
  57. if (*p == '}')
  58. break;
  59. lv = grub_zalloc (sizeof (*lv));
  60. q = p;
  61. - while (*q != ' ')
  62. + while (*q != ' ' && q < mda_end)
  63. q++;
  64. + if (q == mda_end)
  65. + goto lvs_fail;
  66. +
  67. s = q - p;
  68. lv->name = grub_strndup (p, s);
  69. if (!lv->name)
  70. @@ -570,9 +583,12 @@ grub_lvm_detect (grub_disk_t disk,
  71. if (p == NULL)
  72. goto lvs_segment_fail2;
  73. q = ++p;
  74. - while (*q != '"')
  75. + while (q < mda_end && *q != '"')
  76. q++;
  77. + if (q == mda_end)
  78. + goto lvs_segment_fail2;
  79. +
  80. s = q - p;
  81. stripe->name = grub_malloc (s + 1);
  82. @@ -629,9 +645,12 @@ grub_lvm_detect (grub_disk_t disk,
  83. if (p == NULL)
  84. goto lvs_segment_fail2;
  85. q = ++p;
  86. - while (*q != '"')
  87. + while (q < mda_end && *q != '"')
  88. q++;
  89. + if (q == mda_end)
  90. + goto lvs_segment_fail2;
  91. +
  92. s = q - p;
  93. lvname = grub_malloc (s + 1);
  94. --
  95. 2.14.2