| From 7ce3259f67ac2cd93acb0ec0080c24b3b69e66c6 Mon Sep 17 00:00:00 2001 |
| From: Darren Kenny <darren.kenny@oracle.com> |
| Date: Wed, 4 Nov 2020 15:10:51 +0000 |
| Subject: [PATCH] video/fb/fbfill: Fix potential integer overflow |
| |
| The multiplication of 2 unsigned 32-bit integers may overflow before |
| promotion to unsigned 64-bit. We should ensure that the multiplication |
| is done with overflow detection. Additionally, use grub_sub() for |
| subtraction. |
| |
| Fixes: CID 73640, CID 73697, CID 73702, CID 73823 |
| |
| Signed-off-by: Darren Kenny <darren.kenny@oracle.com> |
| Signed-off-by: Marco A Benatto <mbenatto@redhat.com> |
| Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> |
| Signed-off-by: Stefan SΓΈrensen <stefan.sorensen@spectralink.com> |
| --- |
| grub-core/video/fb/fbfill.c | 17 +++++++++++++---- |
| 1 file changed, 13 insertions(+), 4 deletions(-) |
| |
| diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c |
| index 11816d0..a37acd1 100644 |
| --- a/grub-core/video/fb/fbfill.c |
| +++ b/grub-core/video/fb/fbfill.c |
| @@ -31,6 +31,7 @@ |
| #include <grub/fbfill.h> |
| #include <grub/fbutil.h> |
| #include <grub/types.h> |
| +#include <grub/safemath.h> |
| #include <grub/video.h> |
| |
| /* Generic filler that works for every supported mode. */ |
| @@ -61,7 +62,9 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, |
| |
| /* Calculate the number of bytes to advance from the end of one line |
| to the beginning of the next line. */ |
| - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; |
| + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || |
| + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) |
| + return; |
| |
| /* Get the start address. */ |
| dstptr = grub_video_fb_get_video_ptr (dst, x, y); |
| @@ -98,7 +101,9 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, |
| #endif |
| /* Calculate the number of bytes to advance from the end of one line |
| to the beginning of the next line. */ |
| - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; |
| + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || |
| + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) |
| + return; |
| |
| /* Get the start address. */ |
| dstptr = grub_video_fb_get_video_ptr (dst, x, y); |
| @@ -131,7 +136,9 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, |
| |
| /* Calculate the number of bytes to advance from the end of one line |
| to the beginning of the next line. */ |
| - rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width); |
| + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || |
| + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) |
| + return; |
| |
| /* Get the start address. */ |
| dstptr = grub_video_fb_get_video_ptr (dst, x, y); |
| @@ -161,7 +168,9 @@ grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst, |
| |
| /* Calculate the number of bytes to advance from the end of one line |
| to the beginning of the next line. */ |
| - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; |
| + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || |
| + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) |
| + return; |
| |
| /* Get the start address. */ |
| dstptr = grub_video_fb_get_video_ptr (dst, x, y); |
| -- |
| 2.14.2 |
| |