Blame SOURCES/0288-font-Fix-an-integer-underflow-in-blit_comb.patch

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