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