Blame SOURCES/0287-fbutil-Fix-integer-overflow.patch

fd0330
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
fd0330
From: Zhang Boyang <zhangboyang.id@gmail.com>
fd0330
Date: Tue, 6 Sep 2022 03:03:21 +0800
fd0330
Subject: [PATCH] fbutil: Fix integer overflow
fd0330
fd0330
Expressions like u64 = u32 * u32 are unsafe because their products are
fd0330
truncated to u32 even if left hand side is u64. This patch fixes all
fd0330
problems like that one in fbutil.
fd0330
fd0330
To get right result not only left hand side have to be u64 but it's also
fd0330
necessary to cast at least one of the operands of all leaf operators of
fd0330
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
fd0330
u64 = (u64)u32 * u32 + (u64)u32 * u32.
fd0330
fd0330
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
fd0330
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
fd0330
not overflow grub_uint64_t.
fd0330
fd0330
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
fd0330
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
fd0330
fd0330
This patch also adds a comment to grub_video_fb_get_video_ptr() which
fd0330
says it's arguments must be valid and no sanity check is performed
fd0330
(like its siblings in grub-core/video/fb/fbutil.c).
fd0330
fd0330
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
fd0330
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
fd0330
(cherry picked from commit 50a11a81bc842c58962244a2dc86bbd31a426e12)
fd0330
---
fd0330
 grub-core/video/fb/fbutil.c |  4 ++--
fd0330
 include/grub/fbutil.h       | 13 +++++++++----
fd0330
 2 files changed, 11 insertions(+), 6 deletions(-)
fd0330
fd0330
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
fd0330
index b98bb51fe8..25ef39f47d 100644
fd0330
--- a/grub-core/video/fb/fbutil.c
fd0330
+++ b/grub-core/video/fb/fbutil.c
fd0330
@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source,
fd0330
     case 1:
fd0330
       if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
fd0330
         {
fd0330
-          int bit_index = y * source->mode_info->width + x;
fd0330
+          grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
fd0330
           grub_uint8_t *ptr = source->data + bit_index / 8;
fd0330
           int bit_pos = 7 - bit_index % 8;
fd0330
           color = (*ptr >> bit_pos) & 0x01;
fd0330
@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source,
fd0330
     case 1:
fd0330
       if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
fd0330
         {
fd0330
-          int bit_index = y * source->mode_info->width + x;
fd0330
+          grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
fd0330
           grub_uint8_t *ptr = source->data + bit_index / 8;
fd0330
           int bit_pos = 7 - bit_index % 8;
fd0330
           *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
fd0330
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
fd0330
index 4205eb917f..78a1ab3b45 100644
fd0330
--- a/include/grub/fbutil.h
fd0330
+++ b/include/grub/fbutil.h
fd0330
@@ -31,14 +31,19 @@ struct grub_video_fbblit_info
fd0330
   grub_uint8_t *data;
fd0330
 };
fd0330
 
fd0330
-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
fd0330
-   and it doesn't make sense, in general, to ask for a pointer
fd0330
-   to a particular pixel's data.  */
fd0330
+/*
fd0330
+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
fd0330
+ * and it doesn't make sense, in general, to ask for a pointer
fd0330
+ * to a particular pixel's data.
fd0330
+ *
fd0330
+ * This function assumes that bounds checking has been done in previous phase
fd0330
+ * and they are opted out in here.
fd0330
+ */
fd0330
 static inline void *
fd0330
 grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
fd0330
               unsigned int x, unsigned int y)
fd0330
 {
fd0330
-  return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel;
fd0330
+  return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel;
fd0330
 }
fd0330
 
fd0330
 /* Advance pointer by VAL bytes. If there is no unaligned access available,