123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326 |
- From 4ad7e85adc3803788d65707a9db11fd681aebe4a Mon Sep 17 00:00:00 2001
- From: Peter Jones <pjones@redhat.com>
- Date: Mon, 15 Jun 2020 12:28:27 -0400
- Subject: [PATCH] malloc: Use overflow checking primitives where we do
- complex allocations
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- 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>
- Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
- ---
- grub-core/commands/legacycfg.c | 29 +++++++++++++++----
- grub-core/commands/wildcard.c | 36 ++++++++++++++++++++----
- grub-core/disk/ldm.c | 32 +++++++++++++++------
- grub-core/font/font.c | 7 ++++-
- grub-core/fs/btrfs.c | 28 +++++++++++++------
- grub-core/fs/ext2.c | 10 ++++++-
- grub-core/fs/iso9660.c | 51 ++++++++++++++++++++++++----------
- grub-core/fs/sfs.c | 27 ++++++++++++++----
- grub-core/fs/squash4.c | 45 ++++++++++++++++++++++--------
- grub-core/fs/udf.c | 41 +++++++++++++++++----------
- grub-core/fs/xfs.c | 11 +++++---
- grub-core/fs/zfs/zfs.c | 22 ++++++++++-----
- grub-core/fs/zfs/zfscrypt.c | 7 ++++-
- grub-core/lib/arg.c | 20 +++++++++++--
- grub-core/loader/i386/bsd.c | 8 +++++-
- grub-core/net/dns.c | 9 +++++-
- grub-core/normal/charset.c | 10 +++++--
- grub-core/normal/cmdline.c | 14 ++++++++--
- grub-core/normal/menu_entry.c | 13 +++++++--
- grub-core/script/argv.c | 16 +++++++++--
- grub-core/script/lexer.c | 21 ++++++++++++--
- grub-core/video/bitmap.c | 25 +++++++++++------
- grub-core/video/readers/png.c | 13 +++++++--
- 23 files changed, 382 insertions(+), 113 deletions(-)
- diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
- index 5e3ec0d5e..cc5971f4d 100644
- --- a/grub-core/commands/legacycfg.c
- +++ b/grub-core/commands/legacycfg.c
- @@ -32,6 +32,7 @@
- #include <grub/auth.h>
- #include <grub/disk.h>
- #include <grub/partition.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -104,13 +105,22 @@ legacy_file (const char *filename)
- if (newsuffix)
- {
- 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;
- - suffix = grub_realloc (suffix, grub_strlen (suffix)
- - + grub_strlen (newsuffix) + 1);
- + suffix = grub_realloc (suffix, sz);
- if (!suffix)
- {
- grub_free (t);
- +
- + fail_0:
- grub_free (entrysrc);
- grub_free (parsed);
- grub_free (newsuffix);
- @@ -154,13 +164,22 @@ legacy_file (const char *filename)
- else
- {
- 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;
- - entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
- - + grub_strlen (parsed) + 1);
- + entrysrc = grub_realloc (entrysrc, sz);
- if (!entrysrc)
- {
- grub_free (t);
- +
- + fail_1:
- grub_free (parsed);
- grub_free (suffix);
- return grub_errno;
- diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
- index 4a106ca04..cc3290311 100644
- --- a/grub-core/commands/wildcard.c
- +++ b/grub-core/commands/wildcard.c
- @@ -23,6 +23,7 @@
- #include <grub/file.h>
- #include <grub/device.h>
- #include <grub/script_sh.h>
- +#include <grub/safemath.h>
-
- #include <regex.h>
-
- @@ -48,6 +49,7 @@ merge (char **dest, char **ps)
- int i;
- int j;
- char **p;
- + grub_size_t sz;
-
- if (! dest)
- return ps;
- @@ -60,7 +62,12 @@ merge (char **dest, char **ps)
- 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)
- {
- grub_free (dest);
- @@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
- char ch;
- int i = 0;
- 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)
- return 1;
-
- @@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
- struct match_devices_ctx *ctx = data;
- char **t;
- char *buffer;
- + grub_size_t sz;
-
- /* skip partitions if asked to. */
- 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))
- {
- grub_dprintf ("expand", "not matched\n");
- + fail:
- grub_free (buffer);
- 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)
- {
- grub_free (buffer);
- @@ -300,6 +320,7 @@ match_files_iter (const char *name,
- struct match_files_ctx *ctx = data;
- char **t;
- char *buffer;
- + grub_size_t sz;
-
- /* skip . and .. names */
- if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
- @@ -315,9 +336,14 @@ match_files_iter (const char *name,
- if (! buffer)
- return 1;
-
- - t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
- - if (! t)
- + if (grub_add (ctx->nfile, 2, &sz) ||
- + grub_mul (sz, sizeof (char *), &sz))
- + goto fail;
- +
- + t = grub_realloc (ctx->files, sz);
- + if (!t)
- {
- + fail:
- grub_free (buffer);
- return 1;
- }
- diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
- index e6323701a..58f8a53e1 100644
- --- a/grub-core/disk/ldm.c
- +++ b/grub-core/disk/ldm.c
- @@ -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;
- diff --git a/grub-core/font/font.c b/grub-core/font/font.c
- index 8e118b315..5edb477ac 100644
- --- a/grub-core/font/font.c
- +++ b/grub-core/font/font.c
- @@ -30,6 +30,7 @@
- #include <grub/unicode.h>
- #include <grub/fontformat.h>
- #include <grub/env.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -360,9 +361,13 @@ static char *
- read_section_as_string (struct font_file_section *section)
- {
- char *str;
- + grub_size_t sz;
- 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)
- return 0;
-
- diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
- index 11272efc1..2b65bd56a 100644
- --- a/grub-core/fs/btrfs.c
- +++ b/grub-core/fs/btrfs.c
- @@ -40,6 +40,7 @@
- #include <grub/btrfs.h>
- #include <grub/crypto.h>
- #include <grub/diskfilter.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -329,9 +330,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
- if (desc->allocated < desc->depth)
- {
- void *newdata;
- - desc->allocated *= 2;
- - newdata = grub_realloc (desc->data, sizeof (desc->data[0])
- - * desc->allocated);
- + grub_size_t sz;
- +
- + 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)
- return grub_errno;
- desc->data = newdata;
- @@ -622,16 +627,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
- if (data->n_devices_attached > data->n_devices_allocated)
- {
- void *tmp;
- - data->n_devices_allocated = 2 * data->n_devices_attached + 1;
- - data->devices_attached
- - = grub_realloc (tmp = data->devices_attached,
- - data->n_devices_allocated
- - * sizeof (data->devices_attached[0]));
- + grub_size_t sz;
- +
- + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
- + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
- + 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)
- {
- + data->devices_attached = tmp;
- +
- + fail:
- if (ctx.dev_found)
- grub_device_close (ctx.dev_found);
- - data->devices_attached = tmp;
- return NULL;
- }
- }
- diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
- index 9b389802a..ac33bcd68 100644
- --- a/grub-core/fs/ext2.c
- +++ b/grub-core/fs/ext2.c
- @@ -46,6 +46,7 @@
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/fshelp.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
- {
- char *symlink;
- struct grub_fshelp_node *diro = node;
- + grub_size_t sz;
-
- 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)
- return 0;
-
- diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
- index 4f1b52a55..7ba5b300b 100644
- --- a/grub-core/fs/iso9660.c
- +++ b/grub-core/fs/iso9660.c
- @@ -28,6 +28,7 @@
- #include <grub/fshelp.h>
- #include <grub/charset.h>
- #include <grub/datetime.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx,
- int len2)
- {
- 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)
- return;
-
- @@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
- {
- grub_size_t off = 0, csize = 1;
- char *old;
- + grub_size_t sz;
- +
- csize = entry->len - 5;
- old = ctx->filename;
- if (ctx->filename_alloc)
- {
- 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
- {
- 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)
- {
- @@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
- if (node->have_dirents >= node->alloc_dirents)
- {
- struct grub_fshelp_node *new_node;
- - node->alloc_dirents *= 2;
- - new_node = grub_realloc (node,
- - sizeof (struct grub_fshelp_node)
- - + ((node->alloc_dirents
- - - ARRAY_SIZE (node->dirents))
- - * sizeof (node->dirents[0])));
- + grub_size_t sz;
- +
- + if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
- + grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
- + grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
- + grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
- + goto fail_0;
- +
- + new_node = grub_realloc (node, sz);
- if (!new_node)
- {
- + fail_0:
- if (ctx.filename_alloc)
- grub_free (ctx.filename);
- 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)
- {
- struct grub_fshelp_node *new_node;
- - new_node = grub_realloc (node,
- - sizeof (struct grub_fshelp_node)
- - + ((node->alloc_dirents
- - - ARRAY_SIZE (node->dirents))
- - * sizeof (node->dirents[0]))
- - + grub_strlen (ctx.symlink) + 1);
- + grub_size_t sz;
- +
- + if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
- + grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
- + grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
- + grub_add (sz, grub_strlen (ctx.symlink), &sz))
- + goto fail_1;
- +
- + new_node = grub_realloc (node, sz);
- if (!new_node)
- {
- + fail_1:
- if (ctx.filename_alloc)
- grub_free (ctx.filename);
- grub_free (node);
- diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
- index 90f7fb379..de2b107a4 100644
- --- a/grub-core/fs/sfs.c
- +++ b/grub-core/fs/sfs.c
- @@ -26,6 +26,7 @@
- #include <grub/types.h>
- #include <grub/fshelp.h>
- #include <grub/charset.h>
- +#include <grub/safemath.h>
-
- 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)
- {
- struct cache_entry *e = node->cache;
- - e = grub_realloc (node->cache,node->cache_allocated * 2
- - * sizeof (e[0]));
- + grub_size_t sz;
- +
- + if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
- + goto fail;
- +
- + e = grub_realloc (node->cache, sz);
- if (!e)
- {
- + fail:
- grub_errno = 0;
- grub_free (node->cache);
- node->cache = 0;
- @@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
- grub_size_t len = grub_strlen (name);
- grub_uint8_t *name_u8;
- 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));
- if (!*node)
- return 1;
- - name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
- + name_u8 = grub_malloc (sz);
- if (!name_u8)
- {
- grub_free (*node);
- @@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
- data = grub_sfs_mount (disk);
- if (data)
- {
- - grub_size_t len = grub_strlen (data->label);
- - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
- + grub_size_t sz, len = grub_strlen (data->label);
- +
- + 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)
- *grub_latin1_to_utf8 ((grub_uint8_t *) *label,
- (const grub_uint8_t *) data->label,
- diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
- index 95d5c1e1f..785123894 100644
- --- a/grub-core/fs/squash4.c
- +++ b/grub-core/fs/squash4.c
- @@ -26,6 +26,7 @@
- #include <grub/types.h>
- #include <grub/fshelp.h>
- #include <grub/deflate.h>
- +#include <grub/safemath.h>
- #include <minilzo.h>
-
- #include "xz.h"
- @@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
- {
- char *ret;
- 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,
- 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;
- - 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)
- return 0;
- - grub_memcpy (node, dir,
- - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
- + grub_memcpy (node, dir, sz);
- if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
- return 1;
-
- @@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
- {
- 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)
- return 0;
-
- - grub_memcpy (node, dir,
- - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
- + grub_memcpy (node, dir, sz);
-
- node->stsize--;
- 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;
- struct grub_squash_dirent di;
- struct grub_squash_inode ino;
- + grub_size_t sz;
-
- err = read_chunk (dir->data, &di, sizeof (di),
- 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)
- filetype = GRUB_FSHELP_SYMLINK;
-
- - node = grub_malloc (sizeof (*node)
- - + (dir->stsize + 1) * sizeof (dir->stack[0]));
- + if (grub_add (dir->stsize, 1, &sz) ||
- + grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
- + grub_add (sz, sizeof (*node), &sz))
- + return 0;
- +
- + node = grub_malloc (sz);
- if (! node)
- return 0;
-
- - grub_memcpy (node, dir,
- - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
- + grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
-
- node->ino = ino;
- node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
- diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
- index a83761674..21ac7f446 100644
- --- a/grub-core/fs/udf.c
- +++ b/grub-core/fs/udf.c
- @@ -28,6 +28,7 @@
- #include <grub/charset.h>
- #include <grub/datetime.h>
- #include <grub/udf.h>
- +#include <grub/safemath.h>
-
- 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];
- }
- 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)
- *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
- +
- + fail:
- grub_free (utf16);
- 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_uint8_t *raw;
- const grub_uint8_t *ptr;
- - char *out, *optr;
- + char *out = NULL, *optr;
-
- if (sz < 4)
- return NULL;
- @@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- if (!raw)
- return NULL;
- if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
- - {
- - grub_free (raw);
- - return NULL;
- - }
- + goto fail_1;
-
- - 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)
- {
- + fail_0:
- grub_free (raw);
- return NULL;
- }
- @@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- {
- grub_size_t s;
- if ((grub_size_t) (ptr - raw + 4) > sz)
- - goto fail;
- + goto fail_1;
- if (!(ptr[2] == 0 && ptr[3] == 0))
- - goto fail;
- + goto fail_1;
- s = 4 + ptr[1];
- if ((grub_size_t) (ptr - raw + s) > sz)
- - goto fail;
- + goto fail_1;
- switch (*ptr)
- {
- case 1:
- if (ptr[1])
- - goto fail;
- + goto fail_1;
- /* Fallthrough. */
- case 2:
- /* in 4 bytes. out: 1 byte. */
- @@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- if (optr != out)
- *optr++ = '/';
- if (!read_string (ptr + 4, s - 4, optr))
- - goto fail;
- + goto fail_1;
- optr += grub_strlen (optr);
- break;
- default:
- - goto fail;
- + goto fail_1;
- }
- ptr += s;
- }
- @@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- grub_free (raw);
- return out;
-
- - fail:
- + fail_1:
- grub_free (raw);
- grub_free (out);
- grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
- diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
- index 96ffecbfc..ea6590290 100644
- --- a/grub-core/fs/xfs.c
- +++ b/grub-core/fs/xfs.c
- @@ -25,6 +25,7 @@
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/fshelp.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -899,6 +900,7 @@ static struct grub_xfs_data *
- grub_xfs_mount (grub_disk_t disk)
- {
- struct grub_xfs_data *data = 0;
- + grub_size_t sz;
-
- data = grub_zalloc (sizeof (struct grub_xfs_data));
- if (!data)
- @@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
- if (!grub_xfs_sb_valid(data))
- goto fail;
-
- - data = grub_realloc (data,
- - sizeof (struct grub_xfs_data)
- - - sizeof (struct grub_xfs_inode)
- - + grub_xfs_inode_size(data) + 1);
- + if (grub_add (grub_xfs_inode_size (data),
- + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
- + goto fail;
- +
- + data = grub_realloc (data, sz);
-
- if (! data)
- goto fail;
- diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
- index 381dde556..36d0373a6 100644
- --- a/grub-core/fs/zfs/zfs.c
- +++ b/grub-core/fs/zfs/zfs.c
- @@ -55,6 +55,7 @@
- #include <grub/deflate.h>
- #include <grub/crypto.h>
- #include <grub/i18n.h>
- +#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
- @@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data,
- if (data->n_devices_attached > data->n_devices_allocated)
- {
- void *tmp;
- - data->n_devices_allocated = 2 * data->n_devices_attached + 1;
- - data->devices_attached
- - = grub_realloc (tmp = data->devices_attached,
- - data->n_devices_allocated
- - * sizeof (data->devices_attached[0]));
- + grub_size_t sz;
- +
- + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
- + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
- + 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)
- {
- data->devices_attached = tmp;
- @@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
- {
- char *nvpair;
- char *ret;
- - grub_size_t size;
- + grub_size_t size, sz;
- int found;
-
- found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
- &size, 0);
- if (!found)
- 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)
- return 0;
- grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
- diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c
- index 1402e0bc2..de3b015f5 100644
- --- a/grub-core/fs/zfs/zfscrypt.c
- +++ b/grub-core/fs/zfs/zfscrypt.c
- @@ -22,6 +22,7 @@
- #include <grub/misc.h>
- #include <grub/disk.h>
- #include <grub/partition.h>
- +#include <grub/safemath.h>
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/zfs/zfs.h>
- @@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
- int passphrase)
- {
- struct grub_zfs_wrap_key *key;
- + grub_size_t sz;
- +
- if (!passphrase && 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)
- return grub_errno;
- key->is_passphrase = passphrase;
- diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
- index fd7744a6f..3288609a5 100644
- --- a/grub-core/lib/arg.c
- +++ b/grub-core/lib/arg.c
- @@ -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;
-
- diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
- index 3730ed382..b92cbe98d 100644
- --- a/grub-core/loader/i386/bsd.c
- +++ b/grub-core/loader/i386/bsd.c
- @@ -35,6 +35,7 @@
- #include <grub/ns8250.h>
- #include <grub/bsdlabel.h>
- #include <grub/crypto.h>
- +#include <grub/safemath.h>
- #include <grub/verify.h>
- #ifdef GRUB_MACHINE_PCBIOS
- #include <grub/machine/int.h>
- @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void)
- struct grub_netbsd_btinfo_modules *mods;
- unsigned i;
- grub_err_t err;
- + grub_size_t sz;
-
- for (mod = netbsd_mods; mod; mod = mod->next)
- 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)
- return grub_errno;
-
- diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
- index e332d5eb4..906ec7d67 100644
- --- a/grub-core/net/dns.c
- +++ b/grub-core/net/dns.c
- @@ -22,6 +22,7 @@
- #include <grub/i18n.h>
- #include <grub/err.h>
- #include <grub/time.h>
- +#include <grub/safemath.h>
-
- 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;
- struct grub_net_network_level_address *ns;
- + grub_size_t sz;
- +
- if (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)
- return grub_errno;
- dns_servers_alloc = na;
- diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
- index d57fb72fa..4dfcc3107 100644
- --- a/grub-core/normal/charset.c
- +++ b/grub-core/normal/charset.c
- @@ -48,6 +48,7 @@
- #include <grub/unicode.h>
- #include <grub/term.h>
- #include <grub/normal.h>
- +#include <grub/safemath.h>
-
- #if HAVE_FONT_SOURCE
- #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;
- unsigned j;
- + grub_size_t sz;
-
- if (!haveout)
- continue;
- @@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
- n = out->combining_inline;
- else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
- {
- - n = grub_realloc (out->combining_ptr,
- - sizeof (n[0]) * (out->ncomb + 1));
- + if (grub_add (out->ncomb, 1, &sz) ||
- + grub_mul (sz, sizeof (n[0]), &sz))
- + goto fail;
- +
- + n = grub_realloc (out->combining_ptr, sz);
- if (!n)
- {
- + fail:
- grub_errno = GRUB_ERR_NONE;
- continue;
- }
- diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
- index c57242e2e..de03fe63b 100644
- --- a/grub-core/normal/cmdline.c
- +++ b/grub-core/normal/cmdline.c
- @@ -28,6 +28,7 @@
- #include <grub/env.h>
- #include <grub/i18n.h>
- #include <grub/charset.h>
- +#include <grub/safemath.h>
-
- static grub_uint32_t *kill_buf;
-
- @@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
- if (len + (*llen) >= (*max_len))
- {
- grub_uint32_t *nbuf;
- - (*max_len) *= 2;
- - nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
- + grub_size_t sz;
- +
- + 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)
- (*buf) = nbuf;
- else
- {
- + fail:
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- (*max_len) /= 2;
- diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
- index 1993995be..50eef918c 100644
- --- a/grub-core/normal/menu_entry.c
- +++ b/grub-core/normal/menu_entry.c
- @@ -27,6 +27,7 @@
- #include <grub/auth.h>
- #include <grub/i18n.h>
- #include <grub/charset.h>
- +#include <grub/safemath.h>
-
- enum update_mode
- {
- @@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra)
- {
- if (linep->max_len < linep->len + extra)
- {
- - linep->max_len = 2 * (linep->len + extra);
- - linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
- + grub_size_t sz0, sz1;
- +
- + 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)
- return 0;
- + linep->max_len = sz0;
- }
-
- return 1;
- diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c
- index 217ec5d1e..5751fdd57 100644
- --- a/grub-core/script/argv.c
- +++ b/grub-core/script/argv.c
- @@ -20,6 +20,7 @@
- #include <grub/mm.h>
- #include <grub/misc.h>
- #include <grub/script_sh.h>
- +#include <grub/safemath.h>
-
- /* Return nearest power of two that is >= v. */
- static unsigned
- @@ -81,11 +82,16 @@ int
- grub_script_argv_next (struct grub_script_argv *argv)
- {
- char **p = argv->args;
- + grub_size_t sz;
-
- if (argv->args && argv->argc && argv->args[argv->argc - 1] == 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)
- return 1;
-
- @@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s,
- {
- grub_size_t a;
- char *p = argv->args[argv->argc - 1];
- + grub_size_t sz;
-
- if (! s)
- return 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)
- return 1;
-
- diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
- index c6bd3172f..5fb0cbd0b 100644
- --- a/grub-core/script/lexer.c
- +++ b/grub-core/script/lexer.c
- @@ -24,6 +24,7 @@
- #include <grub/mm.h>
- #include <grub/script_sh.h>
- #include <grub/i18n.h>
- +#include <grub/safemath.h>
-
- #define yytext_ptr char *
- #include "grub_script.tab.h"
- @@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
- old = lexer->recording;
- if (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);
- if (!lexer->recording)
- {
- + fail:
- grub_free (old);
- lexer->recordpos = 0;
- lexer->recordlen = 0;
- @@ -130,7 +135,7 @@ int
- grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
- const char *input)
- {
- - grub_size_t len = 0;
- + grub_size_t len = 0, sz;
- char *p = 0;
- char *line = 0;
- YY_BUFFER_STATE buffer;
- @@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
- }
- 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)
- {
- p[len++] = '\n';
- p[len] = '\0';
- }
- + else
- + grub_free (line);
- +
- line = p;
- }
-
- diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c
- index b2e031566..6256e209a 100644
- --- a/grub-core/video/bitmap.c
- +++ b/grub-core/video/bitmap.c
- @@ -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. */
- diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
- index 61bd64537..0157ff742 100644
- --- a/grub-core/video/readers/png.c
- +++ b/grub-core/video/readers/png.c
- @@ -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)
- --
- 2.26.2
|