2
1

0012-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. From 6be7ccfcc33da513de66f71de63fdc129fa019c2 Mon Sep 17 00:00:00 2001
  2. From: Daniel Axtens <dja@axtens.net>
  3. Date: Wed, 7 Jul 2021 15:38:19 +1000
  4. Subject: [PATCH] video/readers/jpeg: Block int underflow -> wild pointer write
  5. Certain 1 px wide images caused a wild pointer write in
  6. grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
  7. we have the following loop:
  8. for (; data->r1 < nr1 && (!data->dri || rst);
  9. data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
  10. We did not check if vb * width >= hb * nc1.
  11. On a 64-bit platform, if that turns out to be negative, it will underflow,
  12. be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
  13. we see data->bitmap_ptr jump, e.g.:
  14. 0x6180_0000_0480 to
  15. 0x6181_0000_0498
  16. ^
  17. ~--- carry has occurred and this pointer is now far away from
  18. any object.
  19. On a 32-bit platform, it will decrement the pointer, creating a pointer
  20. that won't crash but will overwrite random data.
  21. Catch the underflow and error out.
  22. Fixes: CVE-2021-3697
  23. Signed-off-by: Daniel Axtens <dja@axtens.net>
  24. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  25. Upstream: 22a3f97d39f6a10b08ad7fd1cc47c4dcd10413f6
  26. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  27. ---
  28. grub-core/video/readers/jpeg.c | 10 +++++++++-
  29. 1 file changed, 9 insertions(+), 1 deletion(-)
  30. diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
  31. index e31602f76..1d256af01 100644
  32. --- a/grub-core/video/readers/jpeg.c
  33. +++ b/grub-core/video/readers/jpeg.c
  34. @@ -23,6 +23,7 @@
  35. #include <grub/mm.h>
  36. #include <grub/misc.h>
  37. #include <grub/bufio.h>
  38. +#include <grub/safemath.h>
  39. GRUB_MOD_LICENSE ("GPLv3+");
  40. @@ -639,6 +640,7 @@ static grub_err_t
  41. grub_jpeg_decode_data (struct grub_jpeg_data *data)
  42. {
  43. unsigned c1, vb, hb, nr1, nc1;
  44. + unsigned stride_a, stride_b, stride;
  45. int rst = data->dri;
  46. vb = 8 << data->log_vs;
  47. @@ -650,8 +652,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
  48. return grub_error(GRUB_ERR_BAD_FILE_TYPE,
  49. "jpeg: attempted to decode data before start of stream");
  50. + if (grub_mul(vb, data->image_width, &stride_a) ||
  51. + grub_mul(hb, nc1, &stride_b) ||
  52. + grub_sub(stride_a, stride_b, &stride))
  53. + return grub_error (GRUB_ERR_BAD_FILE_TYPE,
  54. + "jpeg: cannot decode image with these dimensions");
  55. +
  56. for (; data->r1 < nr1 && (!data->dri || rst);
  57. - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
  58. + data->r1++, data->bitmap_ptr += stride * 3)
  59. for (c1 = 0; c1 < nc1 && (!data->dri || rst);
  60. c1++, rst--, data->bitmap_ptr += hb * 3)
  61. {
  62. --
  63. 2.41.0