blob: 853efd0486b6b8c16a6088e09d28e4f5c3518c8e [file] [log] [blame]
Andrew Geissler517393d2023-01-13 08:55:19 -06001From fdbe7209152ad6f09a1166f64f162017f2145ba3 Mon Sep 17 00:00:00 2001
2From: Zhang Boyang <zhangboyang.id@gmail.com>
3Date: Mon, 24 Oct 2022 08:05:35 +0800
4Subject: [PATCH] font: Fix an integer underflow in blit_comb()
5
6The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
7evaluate to a very big invalid value even if both ctx.bounds.height and
8combining_glyphs[i]->height are small integers. For example, if
9ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
10expression evaluates to 2147483647 (expected -1). This is because
11coordinates are allowed to be negative but ctx.bounds.height is an
12unsigned int. So, the subtraction operates on unsigned ints and
13underflows to a very big value. The division makes things even worse.
14The quotient is still an invalid value even if converted back to int.
15
16This patch fixes the problem by casting ctx.bounds.height to int. As
17a result the subtraction will operate on int and grub_uint16_t which
18will be promoted to an int. So, the underflow will no longer happen. Other
19uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
20to ensure coordinates are always calculated on signed integers.
21
22Fixes: CVE-2022-3775
23
24Reported-by: Daniel Axtens <dja@axtens.net>
25Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
26Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
27
28Upstream-Status: Backport from
29[https://git.savannah.gnu.org/cgit/grub.git/commit/?id=992c06191babc1e109caf40d6a07ec6fdef427af]
30CVE: CVE-2022-3775
31
32Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
33
34---
35 grub-core/font/font.c | 16 ++++++++--------
36 1 file changed, 8 insertions(+), 8 deletions(-)
37
38diff --git a/grub-core/font/font.c b/grub-core/font/font.c
39index 0ff5525..7b1cbde 100644
40--- a/grub-core/font/font.c
41+++ b/grub-core/font/font.c
42@@ -1206,12 +1206,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
43 ctx.bounds.height = main_glyph->height;
44
45 above_rightx = main_glyph->offset_x + main_glyph->width;
46- above_righty = ctx.bounds.y + ctx.bounds.height;
47+ above_righty = ctx.bounds.y + (int) ctx.bounds.height;
48
49 above_leftx = main_glyph->offset_x;
50- above_lefty = ctx.bounds.y + ctx.bounds.height;
51+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
52
53- below_rightx = ctx.bounds.x + ctx.bounds.width;
54+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
55 below_righty = ctx.bounds.y;
56
57 comb = grub_unicode_get_comb (glyph_id);
58@@ -1224,7 +1224,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
59
60 if (!combining_glyphs[i])
61 continue;
62- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
63+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
64 /* CGJ is to avoid diacritics reordering. */
65 if (comb[i].code
66 == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
67@@ -1234,8 +1234,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
68 case GRUB_UNICODE_COMB_OVERLAY:
69 do_blit (combining_glyphs[i],
70 targetx,
71- (ctx.bounds.height - combining_glyphs[i]->height) / 2
72- - (ctx.bounds.height + ctx.bounds.y), &ctx);
73+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
74+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx);
75 if (min_devwidth < combining_glyphs[i]->width)
76 min_devwidth = combining_glyphs[i]->width;
77 break;
78@@ -1308,7 +1308,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
79 /* Fallthrough. */
80 case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
81 do_blit (combining_glyphs[i], targetx,
82- -(ctx.bounds.height + ctx.bounds.y + space
83+ -((int) ctx.bounds.height + ctx.bounds.y + space
84 + combining_glyphs[i]->height), &ctx);
85 if (min_devwidth < combining_glyphs[i]->width)
86 min_devwidth = combining_glyphs[i]->width;
87@@ -1316,7 +1316,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
88
89 case GRUB_UNICODE_COMB_HEBREW_DAGESH:
90 do_blit (combining_glyphs[i], targetx,
91- -(ctx.bounds.height / 2 + ctx.bounds.y
92+ -((int) ctx.bounds.height / 2 + ctx.bounds.y
93 + combining_glyphs[i]->height / 2), &ctx);
94 if (min_devwidth < combining_glyphs[i]->width)
95 min_devwidth = combining_glyphs[i]->width;