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/term.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
/* Built-in parser for default options. */
|
||||
static const struct grub_arg_option help_options[] =
|
||||
|
@ -216,7 +217,13 @@ static inline grub_err_t
|
|||
add_arg (char ***argl, int *num, char *s)
|
||||
{
|
||||
char **p = *argl;
|
||||
*argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *));
|
||||
grub_size_t sz;
|
||||
|
||||
if (grub_add (++(*num), 1, &sz) ||
|
||||
grub_mul (sz, sizeof (char *), &sz))
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
|
||||
*argl = grub_realloc (*argl, sz);
|
||||
if (! *argl)
|
||||
{
|
||||
grub_free (p);
|
||||
|
@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
|
|||
grub_size_t argcnt;
|
||||
struct grub_arg_list *list;
|
||||
const struct grub_arg_option *options;
|
||||
grub_size_t sz0, sz1;
|
||||
|
||||
options = extcmd->options;
|
||||
if (! options)
|
||||
|
@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
|
|||
argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
|
||||
}
|
||||
|
||||
list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt);
|
||||
if (grub_mul (sizeof (*list), i, &sz0) ||
|
||||
grub_mul (sizeof (char *), argcnt, &sz1) ||
|
||||
grub_add (sz0, sz1, &sz0))
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
list = grub_zalloc (sz0);
|
||||
if (! list)
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue