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