123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- From 79bd19e078c5053d800b1b4d3a901083da947e70 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>
- Upstream: 992c06191babc1e109caf40d6a07ec6fdef427af
- Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
- ---
- 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 0ff552578..7b1cbde07 100644
- --- a/grub-core/font/font.c
- +++ b/grub-core/font/font.c
- @@ -1206,12 +1206,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);
- @@ -1224,7 +1224,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)
- @@ -1234,8 +1234,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;
- @@ -1308,7 +1308,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;
- @@ -1316,7 +1316,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;
- --
- 2.41.0
|