nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone
a9bbe0
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
a9bbe0
From: Zhang Boyang <zhangboyang.id@gmail.com>
a9bbe0
Date: Mon, 24 Oct 2022 08:05:35 +0800
a9bbe0
Subject: [PATCH] font: Fix an integer underflow in blit_comb()
a9bbe0
a9bbe0
The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
a9bbe0
evaluate to a very big invalid value even if both ctx.bounds.height and
a9bbe0
combining_glyphs[i]->height are small integers. For example, if
a9bbe0
ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
a9bbe0
expression evaluates to 2147483647 (expected -1). This is because
a9bbe0
coordinates are allowed to be negative but ctx.bounds.height is an
a9bbe0
unsigned int. So, the subtraction operates on unsigned ints and
a9bbe0
underflows to a very big value. The division makes things even worse.
a9bbe0
The quotient is still an invalid value even if converted back to int.
a9bbe0
a9bbe0
This patch fixes the problem by casting ctx.bounds.height to int. As
a9bbe0
a result the subtraction will operate on int and grub_uint16_t which
a9bbe0
will be promoted to an int. So, the underflow will no longer happen. Other
a9bbe0
uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
a9bbe0
to ensure coordinates are always calculated on signed integers.
a9bbe0
a9bbe0
Fixes: CVE-2022-3775
a9bbe0
a9bbe0
Reported-by: Daniel Axtens <dja@axtens.net>
a9bbe0
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
a9bbe0
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
a9bbe0
(cherry picked from commit 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4)
a9bbe0
(cherry picked from commit 05e532fb707bbf79aa4e1efbde4d208d7da89d6b)
a9bbe0
(cherry picked from commit 0b2592fbb245d53c5c42885d695ece03ddb0eb12)
a9bbe0
---
a9bbe0
 grub-core/font/font.c | 16 ++++++++--------
a9bbe0
 1 file changed, 8 insertions(+), 8 deletions(-)
a9bbe0
a9bbe0
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
a9bbe0
index 31786ab339..fc9d92fce4 100644
a9bbe0
--- a/grub-core/font/font.c
a9bbe0
+++ b/grub-core/font/font.c
a9bbe0
@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
a9bbe0
   ctx.bounds.height = main_glyph->height;
a9bbe0
 
a9bbe0
   above_rightx = main_glyph->offset_x + main_glyph->width;
a9bbe0
-  above_righty = ctx.bounds.y + ctx.bounds.height;
a9bbe0
+  above_righty = ctx.bounds.y + (int) ctx.bounds.height;
a9bbe0
 
a9bbe0
   above_leftx = main_glyph->offset_x;
a9bbe0
-  above_lefty = ctx.bounds.y + ctx.bounds.height;
a9bbe0
+  above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
a9bbe0
 
a9bbe0
-  below_rightx = ctx.bounds.x + ctx.bounds.width;
a9bbe0
+  below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
a9bbe0
   below_righty = ctx.bounds.y;
a9bbe0
 
a9bbe0
   comb = grub_unicode_get_comb (glyph_id);
a9bbe0
@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
a9bbe0
 
a9bbe0
       if (!combining_glyphs[i])
a9bbe0
 	continue;
a9bbe0
-      targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
a9bbe0
+      targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
a9bbe0
       /* CGJ is to avoid diacritics reordering. */
a9bbe0
       if (comb[i].code
a9bbe0
 	  == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
a9bbe0
@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
a9bbe0
 	case GRUB_UNICODE_COMB_OVERLAY:
a9bbe0
 	  do_blit (combining_glyphs[i],
a9bbe0
 		   targetx,
a9bbe0
-		   (ctx.bounds.height - combining_glyphs[i]->height) / 2
a9bbe0
-		   - (ctx.bounds.height + ctx.bounds.y), &ctx;;
a9bbe0
+		   ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
a9bbe0
+		   - ((int) ctx.bounds.height + ctx.bounds.y), &ctx;;
a9bbe0
 	  if (min_devwidth < combining_glyphs[i]->width)
a9bbe0
 	    min_devwidth = combining_glyphs[i]->width;
a9bbe0
 	  break;
a9bbe0
@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
a9bbe0
 	  /* Fallthrough.  */
a9bbe0
 	case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
a9bbe0
 	  do_blit (combining_glyphs[i], targetx,
a9bbe0
-		   -(ctx.bounds.height + ctx.bounds.y + space
a9bbe0
+		   -((int) ctx.bounds.height + ctx.bounds.y + space
a9bbe0
 		     + combining_glyphs[i]->height), &ctx;;
a9bbe0
 	  if (min_devwidth < combining_glyphs[i]->width)
a9bbe0
 	    min_devwidth = combining_glyphs[i]->width;
a9bbe0
@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
a9bbe0
 
a9bbe0
 	case GRUB_UNICODE_COMB_HEBREW_DAGESH:
a9bbe0
 	  do_blit (combining_glyphs[i], targetx,
a9bbe0
-		   -(ctx.bounds.height / 2 + ctx.bounds.y
a9bbe0
+		   -((int) ctx.bounds.height / 2 + ctx.bounds.y
a9bbe0
 		     + combining_glyphs[i]->height / 2), &ctx;;
a9bbe0
 	  if (min_devwidth < combining_glyphs[i]->width)
a9bbe0
 	    min_devwidth = combining_glyphs[i]->width;