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
|
@ -32,6 +32,7 @@
|
||||||
#include <grub/auth.h>
|
#include <grub/auth.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -104,13 +105,22 @@ legacy_file (const char *filename)
|
||||||
if (newsuffix)
|
if (newsuffix)
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
goto fail_0;
|
||||||
|
}
|
||||||
|
|
||||||
t = suffix;
|
t = suffix;
|
||||||
suffix = grub_realloc (suffix, grub_strlen (suffix)
|
suffix = grub_realloc (suffix, sz);
|
||||||
+ grub_strlen (newsuffix) + 1);
|
|
||||||
if (!suffix)
|
if (!suffix)
|
||||||
{
|
{
|
||||||
grub_free (t);
|
grub_free (t);
|
||||||
|
|
||||||
|
fail_0:
|
||||||
grub_free (entrysrc);
|
grub_free (entrysrc);
|
||||||
grub_free (parsed);
|
grub_free (parsed);
|
||||||
grub_free (newsuffix);
|
grub_free (newsuffix);
|
||||||
|
@ -154,13 +164,22 @@ legacy_file (const char *filename)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *t;
|
char *t;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
goto fail_1;
|
||||||
|
}
|
||||||
|
|
||||||
t = entrysrc;
|
t = entrysrc;
|
||||||
entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
|
entrysrc = grub_realloc (entrysrc, sz);
|
||||||
+ grub_strlen (parsed) + 1);
|
|
||||||
if (!entrysrc)
|
if (!entrysrc)
|
||||||
{
|
{
|
||||||
grub_free (t);
|
grub_free (t);
|
||||||
|
|
||||||
|
fail_1:
|
||||||
grub_free (parsed);
|
grub_free (parsed);
|
||||||
grub_free (suffix);
|
grub_free (suffix);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/device.h>
|
#include <grub/device.h>
|
||||||
#include <grub/script_sh.h>
|
#include <grub/script_sh.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ merge (char **dest, char **ps)
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
char **p;
|
char **p;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (! dest)
|
if (! dest)
|
||||||
return ps;
|
return ps;
|
||||||
|
@ -60,7 +62,12 @@ merge (char **dest, char **ps)
|
||||||
for (j = 0; ps[j]; j++)
|
for (j = 0; ps[j]; j++)
|
||||||
;
|
;
|
||||||
|
|
||||||
p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
|
if (grub_add (i, j, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
p = grub_realloc (dest, sz);
|
||||||
if (! p)
|
if (! p)
|
||||||
{
|
{
|
||||||
grub_free (dest);
|
grub_free (dest);
|
||||||
|
@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
|
||||||
char ch;
|
char ch;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
unsigned len = end - start;
|
unsigned len = end - start;
|
||||||
char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
/* Worst case size is (len * 2 + 2 + 1). */
|
||||||
|
if (grub_mul (len, 2, &sz) ||
|
||||||
|
grub_add (sz, 3, &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
buffer = grub_malloc (sz);
|
||||||
if (! buffer)
|
if (! buffer)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
|
||||||
struct match_devices_ctx *ctx = data;
|
struct match_devices_ctx *ctx = data;
|
||||||
char **t;
|
char **t;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
/* skip partitions if asked to. */
|
/* skip partitions if asked to. */
|
||||||
if (ctx->noparts && grub_strchr (name, ','))
|
if (ctx->noparts && grub_strchr (name, ','))
|
||||||
|
@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data)
|
||||||
if (regexec (ctx->regexp, buffer, 0, 0, 0))
|
if (regexec (ctx->regexp, buffer, 0, 0, 0))
|
||||||
{
|
{
|
||||||
grub_dprintf ("expand", "not matched\n");
|
grub_dprintf ("expand", "not matched\n");
|
||||||
|
fail:
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
|
if (grub_add (ctx->ndev, 2, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
t = grub_realloc (ctx->devs, sz);
|
||||||
if (! t)
|
if (! t)
|
||||||
{
|
{
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
|
@ -300,6 +320,7 @@ match_files_iter (const char *name,
|
||||||
struct match_files_ctx *ctx = data;
|
struct match_files_ctx *ctx = data;
|
||||||
char **t;
|
char **t;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
/* skip . and .. names */
|
/* skip . and .. names */
|
||||||
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
||||||
|
@ -315,9 +336,14 @@ match_files_iter (const char *name,
|
||||||
if (! buffer)
|
if (! buffer)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
|
if (grub_add (ctx->nfile, 2, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
t = grub_realloc (ctx->files, sz);
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_free (buffer);
|
grub_free (buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/msdos_partition.h>
|
#include <grub/msdos_partition.h>
|
||||||
#include <grub/gpt_partition.h>
|
#include <grub/gpt_partition.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/emu/misc.h>
|
#include <grub/emu/misc.h>
|
||||||
|
@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
|
||||||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
||||||
/ sizeof (struct grub_ldm_vblk)];
|
/ sizeof (struct grub_ldm_vblk)];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
grub_size_t sz;
|
||||||
err = grub_disk_read (disk, cursec, 0,
|
err = grub_disk_read (disk, cursec, 0,
|
||||||
sizeof(vblk), &vblk);
|
sizeof(vblk), &vblk);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
|
||||||
grub_free (lv);
|
grub_free (lv);
|
||||||
goto fail2;
|
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)
|
if (!lv->name)
|
||||||
{
|
{
|
||||||
grub_free (lv->internal_id);
|
grub_free (lv->internal_id);
|
||||||
|
@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
|
||||||
if (lv->segments->node_alloc == lv->segments->node_count)
|
if (lv->segments->node_alloc == lv->segments->node_count)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
lv->segments->node_alloc *= 2;
|
grub_size_t sz;
|
||||||
t = grub_realloc (lv->segments->nodes,
|
|
||||||
sizeof (*lv->segments->nodes)
|
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
|
||||||
* 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)
|
if (!t)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
lv->segments->nodes = t;
|
lv->segments->nodes = t;
|
||||||
|
@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
|
||||||
if (comp->segment_alloc == comp->segment_count)
|
if (comp->segment_alloc == comp->segment_count)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
comp->segment_alloc *= 2;
|
grub_size_t sz;
|
||||||
t = grub_realloc (comp->segments,
|
|
||||||
comp->segment_alloc
|
if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
|
||||||
* sizeof (*comp->segments));
|
grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
|
||||||
|
goto fail2;
|
||||||
|
|
||||||
|
t = grub_realloc (comp->segments, sz);
|
||||||
if (!t)
|
if (!t)
|
||||||
goto fail2;
|
goto fail2;
|
||||||
comp->segments = t;
|
comp->segments = t;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <grub/unicode.h>
|
#include <grub/unicode.h>
|
||||||
#include <grub/fontformat.h>
|
#include <grub/fontformat.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -360,9 +361,13 @@ static char *
|
||||||
read_section_as_string (struct font_file_section *section)
|
read_section_as_string (struct font_file_section *section)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
grub_size_t sz;
|
||||||
grub_ssize_t ret;
|
grub_ssize_t ret;
|
||||||
|
|
||||||
str = grub_malloc (section->length + 1);
|
if (grub_add (section->length, 1, &sz))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
str = grub_malloc (sz);
|
||||||
if (!str)
|
if (!str)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <grub/btrfs.h>
|
#include <grub/btrfs.h>
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
#include <grub/diskfilter.h>
|
#include <grub/diskfilter.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -331,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
|
||||||
if (desc->allocated < desc->depth)
|
if (desc->allocated < desc->depth)
|
||||||
{
|
{
|
||||||
void *newdata;
|
void *newdata;
|
||||||
desc->allocated *= 2;
|
grub_size_t sz;
|
||||||
newdata = grub_realloc (desc->data, sizeof (desc->data[0])
|
|
||||||
* desc->allocated);
|
if (grub_mul (desc->allocated, 2, &desc->allocated) ||
|
||||||
|
grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
newdata = grub_realloc (desc->data, sz);
|
||||||
if (!newdata)
|
if (!newdata)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
desc->data = newdata;
|
desc->data = newdata;
|
||||||
|
@ -624,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
|
||||||
if (data->n_devices_attached > data->n_devices_allocated)
|
if (data->n_devices_attached > data->n_devices_allocated)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
grub_size_t sz;
|
||||||
data->devices_attached
|
|
||||||
= grub_realloc (tmp = data->devices_attached,
|
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||||
data->n_devices_allocated
|
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||||
* sizeof (data->devices_attached[0]));
|
grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
|
||||||
if (!data->devices_attached)
|
if (!data->devices_attached)
|
||||||
{
|
{
|
||||||
|
data->devices_attached = tmp;
|
||||||
|
|
||||||
|
fail:
|
||||||
if (ctx.dev_found)
|
if (ctx.dev_found)
|
||||||
grub_device_close (ctx.dev_found);
|
grub_device_close (ctx.dev_found);
|
||||||
data->devices_attached = tmp;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
char *symlink;
|
char *symlink;
|
||||||
struct grub_fshelp_node *diro = node;
|
struct grub_fshelp_node *diro = node;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (! diro->inode_read)
|
if (! diro->inode_read)
|
||||||
{
|
{
|
||||||
|
@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
|
if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
symlink = grub_malloc (sz);
|
||||||
if (! symlink)
|
if (! symlink)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/datetime.h>
|
#include <grub/datetime.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx,
|
||||||
int len2)
|
int len2)
|
||||||
{
|
{
|
||||||
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
|
int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
|
if (grub_add (size, len2, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ctx->symlink = grub_realloc (ctx->symlink, sz);
|
||||||
if (! ctx->symlink)
|
if (! ctx->symlink)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
||||||
{
|
{
|
||||||
grub_size_t off = 0, csize = 1;
|
grub_size_t off = 0, csize = 1;
|
||||||
char *old;
|
char *old;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
csize = entry->len - 5;
|
csize = entry->len - 5;
|
||||||
old = ctx->filename;
|
old = ctx->filename;
|
||||||
if (ctx->filename_alloc)
|
if (ctx->filename_alloc)
|
||||||
{
|
{
|
||||||
off = grub_strlen (ctx->filename);
|
off = grub_strlen (ctx->filename);
|
||||||
ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
|
if (grub_add (csize, off, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
ctx->filename = grub_realloc (ctx->filename, sz);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
off = 0;
|
off = 0;
|
||||||
ctx->filename = grub_zalloc (csize + 1);
|
if (grub_add (csize, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
ctx->filename = grub_zalloc (sz);
|
||||||
}
|
}
|
||||||
if (!ctx->filename)
|
if (!ctx->filename)
|
||||||
{
|
{
|
||||||
|
@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (node->have_dirents >= node->alloc_dirents)
|
if (node->have_dirents >= node->alloc_dirents)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_node *new_node;
|
struct grub_fshelp_node *new_node;
|
||||||
node->alloc_dirents *= 2;
|
grub_size_t sz;
|
||||||
new_node = grub_realloc (node,
|
|
||||||
sizeof (struct grub_fshelp_node)
|
if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
|
||||||
+ ((node->alloc_dirents
|
grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||||
- ARRAY_SIZE (node->dirents))
|
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||||
* sizeof (node->dirents[0])));
|
grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
|
||||||
|
goto fail_0;
|
||||||
|
|
||||||
|
new_node = grub_realloc (node, sz);
|
||||||
if (!new_node)
|
if (!new_node)
|
||||||
{
|
{
|
||||||
|
fail_0:
|
||||||
if (ctx.filename_alloc)
|
if (ctx.filename_alloc)
|
||||||
grub_free (ctx.filename);
|
grub_free (ctx.filename);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
|
* sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
|
||||||
{
|
{
|
||||||
struct grub_fshelp_node *new_node;
|
struct grub_fshelp_node *new_node;
|
||||||
new_node = grub_realloc (node,
|
grub_size_t sz;
|
||||||
sizeof (struct grub_fshelp_node)
|
|
||||||
+ ((node->alloc_dirents
|
if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
|
||||||
- ARRAY_SIZE (node->dirents))
|
grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
|
||||||
* sizeof (node->dirents[0]))
|
grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
|
||||||
+ grub_strlen (ctx.symlink) + 1);
|
grub_add (sz, grub_strlen (ctx.symlink), &sz))
|
||||||
|
goto fail_1;
|
||||||
|
|
||||||
|
new_node = grub_realloc (node, sz);
|
||||||
if (!new_node)
|
if (!new_node)
|
||||||
{
|
{
|
||||||
|
fail_1:
|
||||||
if (ctx.filename_alloc)
|
if (ctx.filename_alloc)
|
||||||
grub_free (ctx.filename);
|
grub_free (ctx.filename);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||||
if (node->cache && node->cache_size >= node->cache_allocated)
|
if (node->cache && node->cache_size >= node->cache_allocated)
|
||||||
{
|
{
|
||||||
struct cache_entry *e = node->cache;
|
struct cache_entry *e = node->cache;
|
||||||
e = grub_realloc (node->cache,node->cache_allocated * 2
|
grub_size_t sz;
|
||||||
* sizeof (e[0]));
|
|
||||||
|
if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
e = grub_realloc (node->cache, sz);
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_errno = 0;
|
grub_errno = 0;
|
||||||
grub_free (node->cache);
|
grub_free (node->cache);
|
||||||
node->cache = 0;
|
node->cache = 0;
|
||||||
|
@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
|
||||||
grub_size_t len = grub_strlen (name);
|
grub_size_t len = grub_strlen (name);
|
||||||
grub_uint8_t *name_u8;
|
grub_uint8_t *name_u8;
|
||||||
int ret;
|
int ret;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
*node = grub_malloc (sizeof (**node));
|
*node = grub_malloc (sizeof (**node));
|
||||||
if (!*node)
|
if (!*node)
|
||||||
return 1;
|
return 1;
|
||||||
name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
name_u8 = grub_malloc (sz);
|
||||||
if (!name_u8)
|
if (!name_u8)
|
||||||
{
|
{
|
||||||
grub_free (*node);
|
grub_free (*node);
|
||||||
|
@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
|
||||||
data = grub_sfs_mount (disk);
|
data = grub_sfs_mount (disk);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
grub_size_t len = grub_strlen (data->label);
|
grub_size_t sz, len = grub_strlen (data->label);
|
||||||
*label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
|
|
||||||
|
if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
*label = grub_malloc (sz);
|
||||||
if (*label)
|
if (*label)
|
||||||
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
*grub_latin1_to_utf8 ((grub_uint8_t *) *label,
|
||||||
(const grub_uint8_t *) data->label,
|
(const grub_uint8_t *) data->label,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
#include <minilzo.h>
|
#include <minilzo.h>
|
||||||
|
|
||||||
#include "xz.h"
|
#include "xz.h"
|
||||||
|
@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
char *ret;
|
char *ret;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = grub_malloc (sz);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
err = read_chunk (node->data, ret,
|
err = read_chunk (node->data, ret,
|
||||||
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
grub_le_to_cpu32 (node->ino.symlink.namelen),
|
||||||
|
@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
{
|
{
|
||||||
grub_fshelp_node_t node;
|
grub_fshelp_node_t node;
|
||||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
grub_size_t sz;
|
||||||
|
|
||||||
|
if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (!node)
|
if (!node)
|
||||||
return 0;
|
return 0;
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz);
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
|
if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (!node)
|
if (!node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz);
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
|
|
||||||
node->stsize--;
|
node->stsize--;
|
||||||
err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
|
err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
|
||||||
|
@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
|
||||||
struct grub_squash_dirent di;
|
struct grub_squash_dirent di;
|
||||||
struct grub_squash_inode ino;
|
struct grub_squash_inode ino;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
err = read_chunk (dir->data, &di, sizeof (di),
|
err = read_chunk (dir->data, &di, sizeof (di),
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
||||||
|
@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
||||||
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
|
||||||
filetype = GRUB_FSHELP_SYMLINK;
|
filetype = GRUB_FSHELP_SYMLINK;
|
||||||
|
|
||||||
node = grub_malloc (sizeof (*node)
|
if (grub_add (dir->stsize, 1, &sz) ||
|
||||||
+ (dir->stsize + 1) * sizeof (dir->stack[0]));
|
grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*node), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
node = grub_malloc (sz);
|
||||||
if (! node)
|
if (! node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memcpy (node, dir,
|
grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
|
||||||
sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
|
|
||||||
|
|
||||||
node->ino = ino;
|
node->ino = ino;
|
||||||
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
#include <grub/datetime.h>
|
#include <grub/datetime.h>
|
||||||
#include <grub/udf.h>
|
#include <grub/udf.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
|
||||||
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
|
||||||
}
|
}
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
|
{
|
||||||
|
grub_size_t size;
|
||||||
|
|
||||||
|
if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) ||
|
||||||
|
grub_add (size, 1, &size))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
outbuf = grub_malloc (size);
|
||||||
|
}
|
||||||
if (outbuf)
|
if (outbuf)
|
||||||
*grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
|
*grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
|
||||||
|
|
||||||
|
fail:
|
||||||
grub_free (utf16);
|
grub_free (utf16);
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
grub_size_t sz = U64 (node->block.fe.file_size);
|
grub_size_t sz = U64 (node->block.fe.file_size);
|
||||||
grub_uint8_t *raw;
|
grub_uint8_t *raw;
|
||||||
const grub_uint8_t *ptr;
|
const grub_uint8_t *ptr;
|
||||||
char *out, *optr;
|
char *out = NULL, *optr;
|
||||||
|
|
||||||
if (sz < 4)
|
if (sz < 4)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
if (!raw)
|
if (!raw)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
|
if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
|
||||||
{
|
goto fail_1;
|
||||||
grub_free (raw);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out = grub_malloc (sz * 2 + 1);
|
if (grub_mul (sz, 2, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz))
|
||||||
|
goto fail_0;
|
||||||
|
|
||||||
|
out = grub_malloc (sz);
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
{
|
||||||
|
fail_0:
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
grub_size_t s;
|
grub_size_t s;
|
||||||
if ((grub_size_t) (ptr - raw + 4) > sz)
|
if ((grub_size_t) (ptr - raw + 4) > sz)
|
||||||
goto fail;
|
goto fail_1;
|
||||||
if (!(ptr[2] == 0 && ptr[3] == 0))
|
if (!(ptr[2] == 0 && ptr[3] == 0))
|
||||||
goto fail;
|
goto fail_1;
|
||||||
s = 4 + ptr[1];
|
s = 4 + ptr[1];
|
||||||
if ((grub_size_t) (ptr - raw + s) > sz)
|
if ((grub_size_t) (ptr - raw + s) > sz)
|
||||||
goto fail;
|
goto fail_1;
|
||||||
switch (*ptr)
|
switch (*ptr)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
if (ptr[1])
|
if (ptr[1])
|
||||||
goto fail;
|
goto fail_1;
|
||||||
/* Fallthrough. */
|
/* Fallthrough. */
|
||||||
case 2:
|
case 2:
|
||||||
/* in 4 bytes. out: 1 byte. */
|
/* in 4 bytes. out: 1 byte. */
|
||||||
|
@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
if (optr != out)
|
if (optr != out)
|
||||||
*optr++ = '/';
|
*optr++ = '/';
|
||||||
if (!read_string (ptr + 4, s - 4, optr))
|
if (!read_string (ptr + 4, s - 4, optr))
|
||||||
goto fail;
|
goto fail_1;
|
||||||
optr += grub_strlen (optr);
|
optr += grub_strlen (optr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail_1;
|
||||||
}
|
}
|
||||||
ptr += s;
|
ptr += s;
|
||||||
}
|
}
|
||||||
|
@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
fail:
|
fail_1:
|
||||||
grub_free (raw);
|
grub_free (raw);
|
||||||
grub_free (out);
|
grub_free (out);
|
||||||
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/fshelp.h>
|
#include <grub/fshelp.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -899,6 +900,7 @@ static struct grub_xfs_data *
|
||||||
grub_xfs_mount (grub_disk_t disk)
|
grub_xfs_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
struct grub_xfs_data *data = 0;
|
struct grub_xfs_data *data = 0;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
data = grub_zalloc (sizeof (struct grub_xfs_data));
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
|
||||||
if (!grub_xfs_sb_valid(data))
|
if (!grub_xfs_sb_valid(data))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data = grub_realloc (data,
|
if (grub_add (grub_xfs_inode_size (data),
|
||||||
sizeof (struct grub_xfs_data)
|
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
|
||||||
- sizeof (struct grub_xfs_inode)
|
goto fail;
|
||||||
+ grub_xfs_inode_size(data) + 1);
|
|
||||||
|
data = grub_realloc (data, sz);
|
||||||
|
|
||||||
if (! data)
|
if (! data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <grub/deflate.h>
|
#include <grub/deflate.h>
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -776,11 +777,14 @@ fill_vdev_info (struct grub_zfs_data *data,
|
||||||
if (data->n_devices_attached > data->n_devices_allocated)
|
if (data->n_devices_attached > data->n_devices_allocated)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
data->n_devices_allocated = 2 * data->n_devices_attached + 1;
|
grub_size_t sz;
|
||||||
data->devices_attached
|
|
||||||
= grub_realloc (tmp = data->devices_attached,
|
if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
|
||||||
data->n_devices_allocated
|
grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
|
||||||
* sizeof (data->devices_attached[0]));
|
grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
|
||||||
if (!data->devices_attached)
|
if (!data->devices_attached)
|
||||||
{
|
{
|
||||||
data->devices_attached = tmp;
|
data->devices_attached = tmp;
|
||||||
|
@ -3471,14 +3475,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
|
||||||
{
|
{
|
||||||
char *nvpair;
|
char *nvpair;
|
||||||
char *ret;
|
char *ret;
|
||||||
grub_size_t size;
|
grub_size_t size, sz;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
||||||
&size, 0);
|
&size, 0);
|
||||||
if (!found)
|
if (!found)
|
||||||
return 0;
|
return 0;
|
||||||
ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
|
|
||||||
|
if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = grub_zalloc (sz);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/zfs/zfs.h>
|
#include <grub/zfs/zfs.h>
|
||||||
|
@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
|
||||||
int passphrase)
|
int passphrase)
|
||||||
{
|
{
|
||||||
struct grub_zfs_wrap_key *key;
|
struct grub_zfs_wrap_key *key;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (!passphrase && keylen > 32)
|
if (!passphrase && keylen > 32)
|
||||||
keylen = 32;
|
keylen = 32;
|
||||||
key = grub_malloc (sizeof (*key) + keylen);
|
if (grub_add (sizeof (*key), keylen, &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
key = grub_malloc (sz);
|
||||||
if (!key)
|
if (!key)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
key->is_passphrase = passphrase;
|
key->is_passphrase = passphrase;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
/* Built-in parser for default options. */
|
/* Built-in parser for default options. */
|
||||||
static const struct grub_arg_option help_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)
|
add_arg (char ***argl, int *num, char *s)
|
||||||
{
|
{
|
||||||
char **p = *argl;
|
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)
|
if (! *argl)
|
||||||
{
|
{
|
||||||
grub_free (p);
|
grub_free (p);
|
||||||
|
@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
|
||||||
grub_size_t argcnt;
|
grub_size_t argcnt;
|
||||||
struct grub_arg_list *list;
|
struct grub_arg_list *list;
|
||||||
const struct grub_arg_option *options;
|
const struct grub_arg_option *options;
|
||||||
|
grub_size_t sz0, sz1;
|
||||||
|
|
||||||
options = extcmd->options;
|
options = extcmd->options;
|
||||||
if (! 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 */
|
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)
|
if (! list)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <grub/ns8250.h>
|
#include <grub/ns8250.h>
|
||||||
#include <grub/bsdlabel.h>
|
#include <grub/bsdlabel.h>
|
||||||
#include <grub/crypto.h>
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
#include <grub/verify.h>
|
#include <grub/verify.h>
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
#ifdef GRUB_MACHINE_PCBIOS
|
||||||
#include <grub/machine/int.h>
|
#include <grub/machine/int.h>
|
||||||
|
@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void)
|
||||||
struct grub_netbsd_btinfo_modules *mods;
|
struct grub_netbsd_btinfo_modules *mods;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
for (mod = netbsd_mods; mod; mod = mod->next)
|
for (mod = netbsd_mods; mod; mod = mod->next)
|
||||||
modcnt++;
|
modcnt++;
|
||||||
|
|
||||||
mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
|
if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) ||
|
||||||
|
grub_add (sz, sizeof (*mods), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
mods = grub_malloc (sz);
|
||||||
if (!mods)
|
if (!mods)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
struct dns_cache_element
|
struct dns_cache_element
|
||||||
{
|
{
|
||||||
|
@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s)
|
||||||
{
|
{
|
||||||
int na = dns_servers_alloc * 2;
|
int na = dns_servers_alloc * 2;
|
||||||
struct grub_net_network_level_address *ns;
|
struct grub_net_network_level_address *ns;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (na < 8)
|
if (na < 8)
|
||||||
na = 8;
|
na = 8;
|
||||||
ns = grub_realloc (dns_servers, na * sizeof (ns[0]));
|
|
||||||
|
if (grub_mul (na, sizeof (ns[0]), &sz))
|
||||||
|
return GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
ns = grub_realloc (dns_servers, sz);
|
||||||
if (!ns)
|
if (!ns)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
dns_servers_alloc = na;
|
dns_servers_alloc = na;
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <grub/unicode.h>
|
#include <grub/unicode.h>
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/normal.h>
|
#include <grub/normal.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#if HAVE_FONT_SOURCE
|
#if HAVE_FONT_SOURCE
|
||||||
#include "widthspec.h"
|
#include "widthspec.h"
|
||||||
|
@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||||
{
|
{
|
||||||
struct grub_unicode_combining *n;
|
struct grub_unicode_combining *n;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (!haveout)
|
if (!haveout)
|
||||||
continue;
|
continue;
|
||||||
|
@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||||
n = out->combining_inline;
|
n = out->combining_inline;
|
||||||
else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
|
else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
|
||||||
{
|
{
|
||||||
n = grub_realloc (out->combining_ptr,
|
if (grub_add (out->ncomb, 1, &sz) ||
|
||||||
sizeof (n[0]) * (out->ncomb + 1));
|
grub_mul (sz, sizeof (n[0]), &sz))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
n = grub_realloc (out->combining_ptr, sz);
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
static grub_uint32_t *kill_buf;
|
static grub_uint32_t *kill_buf;
|
||||||
|
|
||||||
|
@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
|
||||||
if (len + (*llen) >= (*max_len))
|
if (len + (*llen) >= (*max_len))
|
||||||
{
|
{
|
||||||
grub_uint32_t *nbuf;
|
grub_uint32_t *nbuf;
|
||||||
(*max_len) *= 2;
|
grub_size_t sz;
|
||||||
nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
|
|
||||||
|
if (grub_mul (*max_len, 2, max_len) ||
|
||||||
|
grub_mul (*max_len, sizeof (grub_uint32_t), &sz))
|
||||||
|
{
|
||||||
|
grub_errno = GRUB_ERR_OUT_OF_RANGE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbuf = grub_realloc ((*buf), sz);
|
||||||
if (nbuf)
|
if (nbuf)
|
||||||
(*buf) = nbuf;
|
(*buf) = nbuf;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
(*max_len) /= 2;
|
(*max_len) /= 2;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/auth.h>
|
#include <grub/auth.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
enum update_mode
|
enum update_mode
|
||||||
{
|
{
|
||||||
|
@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra)
|
||||||
{
|
{
|
||||||
if (linep->max_len < linep->len + extra)
|
if (linep->max_len < linep->len + extra)
|
||||||
{
|
{
|
||||||
linep->max_len = 2 * (linep->len + extra);
|
grub_size_t sz0, sz1;
|
||||||
linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
|
|
||||||
|
if (grub_add (linep->len, extra, &sz0) ||
|
||||||
|
grub_mul (sz0, 2, &sz0) ||
|
||||||
|
grub_add (sz0, 1, &sz1) ||
|
||||||
|
grub_mul (sz1, sizeof (linep->buf[0]), &sz1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
linep->buf = grub_realloc (linep->buf, sz1);
|
||||||
if (! linep->buf)
|
if (! linep->buf)
|
||||||
return 0;
|
return 0;
|
||||||
|
linep->max_len = sz0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/script_sh.h>
|
#include <grub/script_sh.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
/* Return nearest power of two that is >= v. */
|
/* Return nearest power of two that is >= v. */
|
||||||
static unsigned
|
static unsigned
|
||||||
|
@ -81,11 +82,16 @@ int
|
||||||
grub_script_argv_next (struct grub_script_argv *argv)
|
grub_script_argv_next (struct grub_script_argv *argv)
|
||||||
{
|
{
|
||||||
char **p = argv->args;
|
char **p = argv->args;
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
|
if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
|
if (grub_add (argv->argc, 2, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char *), &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
p = grub_realloc (p, round_up_exp (sz));
|
||||||
if (! p)
|
if (! p)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s,
|
||||||
{
|
{
|
||||||
grub_size_t a;
|
grub_size_t a;
|
||||||
char *p = argv->args[argv->argc - 1];
|
char *p = argv->args[argv->argc - 1];
|
||||||
|
grub_size_t sz;
|
||||||
|
|
||||||
if (! s)
|
if (! s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
a = p ? grub_strlen (p) : 0;
|
a = p ? grub_strlen (p) : 0;
|
||||||
|
|
||||||
p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char)));
|
if (grub_add (a, slen, &sz) ||
|
||||||
|
grub_add (sz, 1, &sz) ||
|
||||||
|
grub_mul (sz, sizeof (char), &sz))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
p = grub_realloc (p, round_up_exp (sz));
|
||||||
if (! p)
|
if (! p)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/script_sh.h>
|
#include <grub/script_sh.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
#define yytext_ptr char *
|
#define yytext_ptr char *
|
||||||
#include "grub_script.tab.h"
|
#include "grub_script.tab.h"
|
||||||
|
@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
|
||||||
old = lexer->recording;
|
old = lexer->recording;
|
||||||
if (lexer->recordlen < len)
|
if (lexer->recordlen < len)
|
||||||
lexer->recordlen = len;
|
lexer->recordlen = len;
|
||||||
lexer->recordlen *= 2;
|
|
||||||
|
if (grub_mul (lexer->recordlen, 2, &lexer->recordlen))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
|
lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
|
||||||
if (!lexer->recording)
|
if (!lexer->recording)
|
||||||
{
|
{
|
||||||
|
fail:
|
||||||
grub_free (old);
|
grub_free (old);
|
||||||
lexer->recordpos = 0;
|
lexer->recordpos = 0;
|
||||||
lexer->recordlen = 0;
|
lexer->recordlen = 0;
|
||||||
|
@ -130,7 +135,7 @@ int
|
||||||
grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
|
grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
|
||||||
const char *input)
|
const char *input)
|
||||||
{
|
{
|
||||||
grub_size_t len = 0;
|
grub_size_t len = 0, sz;
|
||||||
char *p = 0;
|
char *p = 0;
|
||||||
char *line = 0;
|
char *line = 0;
|
||||||
YY_BUFFER_STATE buffer;
|
YY_BUFFER_STATE buffer;
|
||||||
|
@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
|
||||||
}
|
}
|
||||||
else if (len && line[len - 1] != '\n')
|
else if (len && line[len - 1] != '\n')
|
||||||
{
|
{
|
||||||
p = grub_realloc (line, len + 2);
|
if (grub_add (len, 2, &sz))
|
||||||
|
{
|
||||||
|
grub_free (line);
|
||||||
|
grub_script_yyerror (parserstate, N_("overflow is detected"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = grub_realloc (line, sz);
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
p[len++] = '\n';
|
p[len++] = '\n';
|
||||||
p[len] = '\0';
|
p[len] = '\0';
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
grub_free (line);
|
||||||
|
|
||||||
line = p;
|
line = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
|
||||||
enum grub_video_blit_format blit_format)
|
enum grub_video_blit_format blit_format)
|
||||||
{
|
{
|
||||||
struct grub_video_mode_info *mode_info;
|
struct grub_video_mode_info *mode_info;
|
||||||
unsigned int size;
|
grub_size_t size;
|
||||||
|
|
||||||
if (!bitmap)
|
if (!bitmap)
|
||||||
return grub_error (GRUB_ERR_BUG, "invalid argument");
|
return grub_error (GRUB_ERR_BUG, "invalid argument");
|
||||||
|
@ -138,18 +139,24 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
|
||||||
mode_info->pitch = width * mode_info->bytes_per_pixel;
|
mode_info->pitch = width * mode_info->bytes_per_pixel;
|
||||||
|
|
||||||
/* Calculate size needed for the data. */
|
/* Calculate size needed for the data. */
|
||||||
size = (width * mode_info->bytes_per_pixel) * height;
|
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);
|
(*bitmap)->data = grub_zalloc (size);
|
||||||
if (! (*bitmap)->data)
|
if (! (*bitmap)->data)
|
||||||
{
|
goto fail;
|
||||||
grub_free (*bitmap);
|
|
||||||
*bitmap = 0;
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (*bitmap);
|
||||||
|
*bitmap = NULL;
|
||||||
|
|
||||||
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Frees all resources allocated by bitmap. */
|
/* Frees all resources allocated by bitmap. */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/bufio.h>
|
#include <grub/bufio.h>
|
||||||
|
#include <grub/safemath.h>
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data)
|
||||||
data->bpp <<= 1;
|
data->bpp <<= 1;
|
||||||
|
|
||||||
data->color_bits = color_bits;
|
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)
|
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
|
#ifndef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
if (data->is_16bit || data->is_gray || data->is_palette)
|
if (data->is_16bit || data->is_gray || data->is_palette)
|
||||||
|
|
Loading…
Reference in a new issue