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