1*4882a593SmuzhiyunFrom e8060722acf0bcca037982d7fb29472363ccdfd4 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Zhang Boyang <zhangboyang.id@gmail.com> 3*4882a593SmuzhiyunDate: Fri, 5 Aug 2022 01:58:27 +0800 4*4882a593SmuzhiyunSubject: [PATCH] font: Fix several integer overflows in 5*4882a593Smuzhiyun grub_font_construct_glyph() 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunThis patch fixes several integer overflows in grub_font_construct_glyph(). 8*4882a593SmuzhiyunGlyphs of invalid size, zero or leading to an overflow, are rejected. 9*4882a593SmuzhiyunThe inconsistency between "glyph" and "max_glyph_size" when grub_malloc() 10*4882a593Smuzhiyunreturns NULL is fixed too. 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunFixes: CVE-2022-2601 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunReported-by: Zhang Boyang <zhangboyang.id@gmail.com> 15*4882a593SmuzhiyunSigned-off-by: Zhang Boyang <zhangboyang.id@gmail.com> 16*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 17*4882a593Smuzhiyun 18*4882a593SmuzhiyunUpstream-Status: Backport from 19*4882a593Smuzhiyun[https://git.savannah.gnu.org/cgit/grub.git/commit/?id=768e1ef2fc159f6e14e7246e4be09363708ac39e] 20*4882a593SmuzhiyunCVE: CVE-2022-2601 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunSigned-off-by: Xiangyu Chen <xiangyu.chen@windriver.com> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun--- 25*4882a593Smuzhiyun grub-core/font/font.c | 29 +++++++++++++++++------------ 26*4882a593Smuzhiyun 1 file changed, 17 insertions(+), 12 deletions(-) 27*4882a593Smuzhiyun 28*4882a593Smuzhiyundiff --git a/grub-core/font/font.c b/grub-core/font/font.c 29*4882a593Smuzhiyunindex 876b5b6..0ff5525 100644 30*4882a593Smuzhiyun--- a/grub-core/font/font.c 31*4882a593Smuzhiyun+++ b/grub-core/font/font.c 32*4882a593Smuzhiyun@@ -1515,6 +1515,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, 33*4882a593Smuzhiyun struct grub_video_signed_rect bounds; 34*4882a593Smuzhiyun static struct grub_font_glyph *glyph = 0; 35*4882a593Smuzhiyun static grub_size_t max_glyph_size = 0; 36*4882a593Smuzhiyun+ grub_size_t cur_glyph_size; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun ensure_comb_space (glyph_id); 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun@@ -1531,29 +1532,33 @@ grub_font_construct_glyph (grub_font_t hinted_font, 41*4882a593Smuzhiyun if (!glyph_id->ncomb && !glyph_id->attributes) 42*4882a593Smuzhiyun return main_glyph; 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) 45*4882a593Smuzhiyun+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) || 46*4882a593Smuzhiyun+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size)) 47*4882a593Smuzhiyun+ return main_glyph; 48*4882a593Smuzhiyun+ 49*4882a593Smuzhiyun+ if (max_glyph_size < cur_glyph_size) 50*4882a593Smuzhiyun { 51*4882a593Smuzhiyun grub_free (glyph); 52*4882a593Smuzhiyun- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; 53*4882a593Smuzhiyun- if (max_glyph_size < 8) 54*4882a593Smuzhiyun- max_glyph_size = 8; 55*4882a593Smuzhiyun- glyph = grub_malloc (max_glyph_size); 56*4882a593Smuzhiyun+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size)) 57*4882a593Smuzhiyun+ max_glyph_size = 0; 58*4882a593Smuzhiyun+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL; 59*4882a593Smuzhiyun } 60*4882a593Smuzhiyun if (!glyph) 61*4882a593Smuzhiyun { 62*4882a593Smuzhiyun+ max_glyph_size = 0; 63*4882a593Smuzhiyun grub_errno = GRUB_ERR_NONE; 64*4882a593Smuzhiyun return main_glyph; 65*4882a593Smuzhiyun } 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun- grub_memset (glyph, 0, sizeof (*glyph) 68*4882a593Smuzhiyun- + (bounds.width * bounds.height 69*4882a593Smuzhiyun- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); 70*4882a593Smuzhiyun+ grub_memset (glyph, 0, cur_glyph_size); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun glyph->font = main_glyph->font; 73*4882a593Smuzhiyun- glyph->width = bounds.width; 74*4882a593Smuzhiyun- glyph->height = bounds.height; 75*4882a593Smuzhiyun- glyph->offset_x = bounds.x; 76*4882a593Smuzhiyun- glyph->offset_y = bounds.y; 77*4882a593Smuzhiyun+ if (bounds.width == 0 || bounds.height == 0 || 78*4882a593Smuzhiyun+ grub_cast (bounds.width, &glyph->width) || 79*4882a593Smuzhiyun+ grub_cast (bounds.height, &glyph->height) || 80*4882a593Smuzhiyun+ grub_cast (bounds.x, &glyph->offset_x) || 81*4882a593Smuzhiyun+ grub_cast (bounds.y, &glyph->offset_y)) 82*4882a593Smuzhiyun+ return main_glyph; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) 85*4882a593Smuzhiyun grub_font_blit_glyph_mirror (glyph, main_glyph, 86