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
|
@ -25,6 +25,7 @@
|
|||
#include <grub/msdos_partition.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/misc.h>
|
||||
|
@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
|
|||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_ldm_vblk)];
|
||||
unsigned i;
|
||||
grub_size_t sz;
|
||||
err = grub_disk_read (disk, cursec, 0,
|
||||
sizeof(vblk), &vblk);
|
||||
if (err)
|
||||
|
@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
|
|||
grub_free (lv);
|
||||
goto fail2;
|
||||
}
|
||||
lv->name = grub_malloc (*ptr + 1);
|
||||
if (grub_add (*ptr, 1, &sz))
|
||||
{
|
||||
grub_free (lv->internal_id);
|
||||
grub_free (lv);
|
||||
goto fail2;
|
||||
}
|
||||
lv->name = grub_malloc (sz);
|
||||
if (!lv->name)
|
||||
{
|
||||
grub_free (lv->internal_id);
|
||||
|
@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
|
|||
if (lv->segments->node_alloc == lv->segments->node_count)
|
||||
{
|
||||
void *t;
|
||||
lv->segments->node_alloc *= 2;
|
||||
t = grub_realloc (lv->segments->nodes,
|
||||
sizeof (*lv->segments->nodes)
|
||||
* lv->segments->node_alloc);
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
|
||||
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
|
||||
goto fail2;
|
||||
|
||||
t = grub_realloc (lv->segments->nodes, sz);
|
||||
if (!t)
|
||||
goto fail2;
|
||||
lv->segments->nodes = t;
|
||||
|
@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
|
|||
if (comp->segment_alloc == comp->segment_count)
|
||||
{
|
||||
void *t;
|
||||
comp->segment_alloc *= 2;
|
||||
t = grub_realloc (comp->segments,
|
||||
comp->segment_alloc
|
||||
* sizeof (*comp->segments));
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
|
||||
grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
|
||||
goto fail2;
|
||||
|
||||
t = grub_realloc (comp->segments, sz);
|
||||
if (!t)
|
||||
goto fail2;
|
||||
comp->segments = t;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue