1From 08e098b1dbf01e96376f594b337491bc4cfa48dd Mon Sep 17 00:00:00 2001 2From: Darren Kenny <darren.kenny@oracle.com> 3Date: Wed, 4 Nov 2020 14:43:44 +0000 4Subject: [PATCH] video/fb/video_fb: Fix multiple integer overflows 5 6The calculation of the unsigned 64-bit value is being generated by 7multiplying 2, signed or unsigned, 32-bit integers which may overflow 8before promotion to unsigned 64-bit. Fix all of them. 9 10Fixes: CID 73703, CID 73767, CID 73833 11 12Signed-off-by: Darren Kenny <darren.kenny@oracle.com> 13Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 14Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 15--- 16 grub-core/video/fb/video_fb.c | 52 ++++++++++++++++++++++++++++++------------- 17 1 file changed, 36 insertions(+), 16 deletions(-) 18 19diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c 20index 1a602c8..1c9a138 100644 21--- a/grub-core/video/fb/video_fb.c 22+++ b/grub-core/video/fb/video_fb.c 23@@ -25,6 +25,7 @@ 24 #include <grub/fbutil.h> 25 #include <grub/bitmap.h> 26 #include <grub/dl.h> 27+#include <grub/safemath.h> 28 29 GRUB_MOD_LICENSE ("GPLv3+"); 30 31@@ -1417,15 +1418,23 @@ doublebuf_blit_update_screen (void) 32 { 33 if (framebuffer.current_dirty.first_line 34 <= framebuffer.current_dirty.last_line) 35- grub_memcpy ((char *) framebuffer.pages[0] 36- + framebuffer.current_dirty.first_line 37- * framebuffer.back_target->mode_info.pitch, 38- (char *) framebuffer.back_target->data 39- + framebuffer.current_dirty.first_line 40- * framebuffer.back_target->mode_info.pitch, 41- framebuffer.back_target->mode_info.pitch 42- * (framebuffer.current_dirty.last_line 43- - framebuffer.current_dirty.first_line)); 44+ { 45+ grub_size_t copy_size; 46+ 47+ if (grub_sub (framebuffer.current_dirty.last_line, 48+ framebuffer.current_dirty.first_line, ©_size) || 49+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) 50+ { 51+ /* Shouldn't happen, but if it does we've a bug. */ 52+ return GRUB_ERR_BUG; 53+ } 54+ 55+ grub_memcpy ((char *) framebuffer.pages[0] + framebuffer.current_dirty.first_line * 56+ framebuffer.back_target->mode_info.pitch, 57+ (char *) framebuffer.back_target->data + framebuffer.current_dirty.first_line * 58+ framebuffer.back_target->mode_info.pitch, 59+ copy_size); 60+ } 61 framebuffer.current_dirty.first_line 62 = framebuffer.back_target->mode_info.height; 63 framebuffer.current_dirty.last_line = 0; 64@@ -1439,7 +1448,7 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back, 65 volatile void *framebuf) 66 { 67 grub_err_t err; 68- grub_size_t page_size = mode_info.pitch * mode_info.height; 69+ grub_size_t page_size = (grub_size_t) mode_info.pitch * mode_info.height; 70 71 framebuffer.offscreen_buffer = grub_zalloc (page_size); 72 if (! framebuffer.offscreen_buffer) 73@@ -1482,12 +1491,23 @@ doublebuf_pageflipping_update_screen (void) 74 last_line = framebuffer.previous_dirty.last_line; 75 76 if (first_line <= last_line) 77- grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] 78- + first_line * framebuffer.back_target->mode_info.pitch, 79- (char *) framebuffer.back_target->data 80- + first_line * framebuffer.back_target->mode_info.pitch, 81- framebuffer.back_target->mode_info.pitch 82- * (last_line - first_line)); 83+ { 84+ grub_size_t copy_size; 85+ 86+ if (grub_sub (last_line, first_line, ©_size) || 87+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, ©_size)) 88+ { 89+ /* Shouldn't happen, but if it does we've a bug. */ 90+ return GRUB_ERR_BUG; 91+ } 92+ 93+ grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] + first_line * 94+ framebuffer.back_target->mode_info.pitch, 95+ (char *) framebuffer.back_target->data + first_line * 96+ framebuffer.back_target->mode_info.pitch, 97+ copy_size); 98+ } 99+ 100 framebuffer.previous_dirty = framebuffer.current_dirty; 101 framebuffer.current_dirty.first_line 102 = framebuffer.back_target->mode_info.height; 103-- 1042.14.2 105 106