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

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