malloc: Use overflow checking primitives where we do complex allocations
This attempts to fix the places where we do the following where arithmetic_expr may include unvalidated data: X = grub_malloc(arithmetic_expr); It accomplishes this by doing the arithmetic ahead of time using grub_add(), grub_sub(), grub_mul() and testing for overflow before proceeding. Among other issues, this fixes: - allocation of integer overflow in grub_video_bitmap_create() reported by Chris Coulson, - allocation of integer overflow in grub_png_decode_image_header() reported by Chris Coulson, - allocation of integer overflow in grub_squash_read_symlink() reported by Chris Coulson, - allocation of integer overflow in grub_ext2_read_symlink() reported by Chris Coulson, - allocation of integer overflow in read_section_as_string() reported by Chris Coulson. Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 Signed-off-by: Peter Jones <pjones@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
f725fa7cb2
commit
3f05d693d1
23 changed files with 382 additions and 113 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
|
|||
enum grub_video_blit_format blit_format)
|
||||
{
|
||||
struct grub_video_mode_info *mode_info;
|
||||
unsigned int size;
|
||||
grub_size_t size;
|
||||
|
||||
if (!bitmap)
|
||||
return grub_error (GRUB_ERR_BUG, "invalid argument");
|
||||
|
@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
|
|||
|
||||
mode_info->pitch = width * mode_info->bytes_per_pixel;
|
||||
|
||||
/* Calculate size needed for the data. */
|
||||
size = (width * mode_info->bytes_per_pixel) * height;
|
||||
/* Calculate size needed for the data. */
|
||||
if (grub_mul (width, mode_info->bytes_per_pixel, &size) ||
|
||||
grub_mul (size, height, &size))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
(*bitmap)->data = grub_zalloc (size);
|
||||
if (! (*bitmap)->data)
|
||||
{
|
||||
grub_free (*bitmap);
|
||||
*bitmap = 0;
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
goto fail;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
grub_free (*bitmap);
|
||||
*bitmap = NULL;
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
/* Frees all resources allocated by bitmap. */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/bufio.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data)
|
|||
data->bpp <<= 1;
|
||||
|
||||
data->color_bits = color_bits;
|
||||
data->row_bytes = data->image_width * data->bpp;
|
||||
|
||||
if (grub_mul (data->image_width, data->bpp, &data->row_bytes))
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
|
||||
if (data->color_bits <= 4)
|
||||
data->row_bytes = (data->image_width * data->color_bits + 7) / 8;
|
||||
{
|
||||
if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes))
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
|
||||
data->row_bytes >>= 3;
|
||||
}
|
||||
|
||||
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
||||
if (data->is_16bit || data->is_gray || data->is_palette)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue