summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-pri...
diff options
context:
space:
mode:
authorYongxin Liu <yongxin.liu@windriver.com>2020-11-04 08:43:33 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-11-12 13:07:52 +0000
commitda5ad8a4232beb4de7c0940ef193578e99d36e0f (patch)
treeab44d798a6623873f592b052258bb4a39c044e3e /meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch
parent5b716fa8e2562a1f942c2d920a3f727c3841c4f3 (diff)
downloadpoky-da5ad8a4232beb4de7c0940ef193578e99d36e0f.tar.gz
grub: clean up CVE patches
Clean up several patches introduced in commit 6732918498 ("grub:fix several CVEs in grub 2.04"). 1) Add CVE tags to individual patches. 2) Rename upstream patches and prefix them with CVE tags. 3) Add description of reference to upstream patch. (From OE-Core rev: 4f395ad49ef9035954d0fda7b7df14dea18b49a0) Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry picked from commit bcb8b6719beaf6625e6b703e91958fe8afba5819) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch')
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch1330
1 files changed, 1330 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch b/meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch
new file mode 100644
index 0000000000..896a2145d4
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2020-14309-CVE-2020-14310-CVE-2020-14311-malloc-Use-overflow-checking-primitives-where-we-do-.patch
@@ -0,0 +1,1330 @@
1From eb77d1ef65e25746acff43545f62a71360b15eec Mon Sep 17 00:00:00 2001
2From: Peter Jones <pjones@redhat.com>
3Date: Mon, 15 Jun 2020 12:28:27 -0400
4Subject: [PATCH 6/9] malloc: Use overflow checking primitives where we do
5 complex allocations
6
7This attempts to fix the places where we do the following where
8arithmetic_expr may include unvalidated data:
9
10 X = grub_malloc(arithmetic_expr);
11
12It accomplishes this by doing the arithmetic ahead of time using grub_add(),
13grub_sub(), grub_mul() and testing for overflow before proceeding.
14
15Among other issues, this fixes:
16 - allocation of integer overflow in grub_video_bitmap_create()
17 reported by Chris Coulson,
18 - allocation of integer overflow in grub_png_decode_image_header()
19 reported by Chris Coulson,
20 - allocation of integer overflow in grub_squash_read_symlink()
21 reported by Chris Coulson,
22 - allocation of integer overflow in grub_ext2_read_symlink()
23 reported by Chris Coulson,
24 - allocation of integer overflow in read_section_as_string()
25 reported by Chris Coulson.
26
27Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311
28
29Signed-off-by: Peter Jones <pjones@redhat.com>
30Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
31
32Upstream-Status: Backport
33CVE: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311
34
35Reference to upstream patch:
36https://git.savannah.gnu.org/cgit/grub.git/commit/?id=3f05d693d1274965ffbe4ba99080dc2c570944c6
37
38Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
39---
40 grub-core/commands/legacycfg.c | 29 +++++++++++++++++++-----
41 grub-core/commands/wildcard.c | 36 ++++++++++++++++++++++++-----
42 grub-core/disk/ldm.c | 32 ++++++++++++++++++--------
43 grub-core/font/font.c | 7 +++++-
44 grub-core/fs/btrfs.c | 28 +++++++++++++++--------
45 grub-core/fs/ext2.c | 10 ++++++++-
46 grub-core/fs/iso9660.c | 51 +++++++++++++++++++++++++++++-------------
47 grub-core/fs/sfs.c | 27 +++++++++++++++++-----
48 grub-core/fs/squash4.c | 45 ++++++++++++++++++++++++++++---------
49 grub-core/fs/udf.c | 41 +++++++++++++++++++++------------
50 grub-core/fs/xfs.c | 11 +++++----
51 grub-core/fs/zfs/zfs.c | 22 ++++++++++++------
52 grub-core/fs/zfs/zfscrypt.c | 7 +++++-
53 grub-core/lib/arg.c | 20 +++++++++++++++--
54 grub-core/loader/i386/bsd.c | 8 ++++++-
55 grub-core/net/dns.c | 9 +++++++-
56 grub-core/normal/charset.c | 10 +++++++--
57 grub-core/normal/cmdline.c | 14 ++++++++++--
58 grub-core/normal/menu_entry.c | 13 +++++++++--
59 grub-core/script/argv.c | 16 +++++++++++--
60 grub-core/script/lexer.c | 21 ++++++++++++++---
61 grub-core/video/bitmap.c | 25 +++++++++++++--------
62 grub-core/video/readers/png.c | 13 +++++++++--
63 23 files changed, 382 insertions(+), 113 deletions(-)
64
65diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
66index 5e3ec0d..cc5971f 100644
67--- a/grub-core/commands/legacycfg.c
68+++ b/grub-core/commands/legacycfg.c
69@@ -32,6 +32,7 @@
70 #include <grub/auth.h>
71 #include <grub/disk.h>
72 #include <grub/partition.h>
73+#include <grub/safemath.h>
74
75 GRUB_MOD_LICENSE ("GPLv3+");
76
77@@ -104,13 +105,22 @@ legacy_file (const char *filename)
78 if (newsuffix)
79 {
80 char *t;
81-
82+ grub_size_t sz;
83+
84+ if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) ||
85+ grub_add (sz, 1, &sz))
86+ {
87+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
88+ goto fail_0;
89+ }
90+
91 t = suffix;
92- suffix = grub_realloc (suffix, grub_strlen (suffix)
93- + grub_strlen (newsuffix) + 1);
94+ suffix = grub_realloc (suffix, sz);
95 if (!suffix)
96 {
97 grub_free (t);
98+
99+ fail_0:
100 grub_free (entrysrc);
101 grub_free (parsed);
102 grub_free (newsuffix);
103@@ -154,13 +164,22 @@ legacy_file (const char *filename)
104 else
105 {
106 char *t;
107+ grub_size_t sz;
108+
109+ if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) ||
110+ grub_add (sz, 1, &sz))
111+ {
112+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
113+ goto fail_1;
114+ }
115
116 t = entrysrc;
117- entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
118- + grub_strlen (parsed) + 1);
119+ entrysrc = grub_realloc (entrysrc, sz);
120 if (!entrysrc)
121 {
122 grub_free (t);
123+
124+ fail_1:
125 grub_free (parsed);
126 grub_free (suffix);
127 return grub_errno;
128diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
129index 4a106ca..cc32903 100644
130--- a/grub-core/commands/wildcard.c
131+++ b/grub-core/commands/wildcard.c
132@@ -23,6 +23,7 @@
133 #include <grub/file.h>
134 #include <grub/device.h>
135 #include <grub/script_sh.h>
136+#include <grub/safemath.h>
137
138 #include <regex.h>
139
140@@ -48,6 +49,7 @@ merge (char **dest, char **ps)
141 int i;
142 int j;
143 char **p;
144+ grub_size_t sz;
145
146 if (! dest)
147 return ps;
148@@ -60,7 +62,12 @@ merge (char **dest, char **ps)
149 for (j = 0; ps[j]; j++)
150 ;
151
152- p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
153+ if (grub_add (i, j, &sz) ||
154+ grub_add (sz, 1, &sz) ||
155+ grub_mul (sz, sizeof (char *), &sz))
156+ return dest;
157+
158+ p = grub_realloc (dest, sz);
159 if (! p)
160 {
161 grub_free (dest);
162@@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
163 char ch;
164 int i = 0;
165 unsigned len = end - start;
166- char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
167+ char *buffer;
168+ grub_size_t sz;
169
170+ /* Worst case size is (len * 2 + 2 + 1). */
171+ if (grub_mul (len, 2, &sz) ||
172+ grub_add (sz, 3, &sz))
173+ return 1;
174+
175+ buffer = grub_malloc (sz);
176 if (! buffer)
177 return 1;
178
179@@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
180 struct match_devices_ctx *ctx = data;
181 char **t;
182 char *buffer;
183+ grub_size_t sz;
184
185 /* skip partitions if asked to. */
186 if (ctx->noparts && grub_strchr (name, ','))
187@@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data)
188 if (regexec (ctx->regexp, buffer, 0, 0, 0))
189 {
190 grub_dprintf ("expand", "not matched\n");
191+ fail:
192 grub_free (buffer);
193 return 0;
194 }
195
196- t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
197+ if (grub_add (ctx->ndev, 2, &sz) ||
198+ grub_mul (sz, sizeof (char *), &sz))
199+ goto fail;
200+
201+ t = grub_realloc (ctx->devs, sz);
202 if (! t)
203 {
204 grub_free (buffer);
205@@ -300,6 +320,7 @@ match_files_iter (const char *name,
206 struct match_files_ctx *ctx = data;
207 char **t;
208 char *buffer;
209+ grub_size_t sz;
210
211 /* skip . and .. names */
212 if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
213@@ -315,9 +336,14 @@ match_files_iter (const char *name,
214 if (! buffer)
215 return 1;
216
217- t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
218- if (! t)
219+ if (grub_add (ctx->nfile, 2, &sz) ||
220+ grub_mul (sz, sizeof (char *), &sz))
221+ goto fail;
222+
223+ t = grub_realloc (ctx->files, sz);
224+ if (!t)
225 {
226+ fail:
227 grub_free (buffer);
228 return 1;
229 }
230diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
231index e632370..58f8a53 100644
232--- a/grub-core/disk/ldm.c
233+++ b/grub-core/disk/ldm.c
234@@ -25,6 +25,7 @@
235 #include <grub/msdos_partition.h>
236 #include <grub/gpt_partition.h>
237 #include <grub/i18n.h>
238+#include <grub/safemath.h>
239
240 #ifdef GRUB_UTIL
241 #include <grub/emu/misc.h>
242@@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
243 struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
244 / sizeof (struct grub_ldm_vblk)];
245 unsigned i;
246+ grub_size_t sz;
247 err = grub_disk_read (disk, cursec, 0,
248 sizeof(vblk), &vblk);
249 if (err)
250@@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
251 grub_free (lv);
252 goto fail2;
253 }
254- lv->name = grub_malloc (*ptr + 1);
255+ if (grub_add (*ptr, 1, &sz))
256+ {
257+ grub_free (lv->internal_id);
258+ grub_free (lv);
259+ goto fail2;
260+ }
261+ lv->name = grub_malloc (sz);
262 if (!lv->name)
263 {
264 grub_free (lv->internal_id);
265@@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
266 if (lv->segments->node_alloc == lv->segments->node_count)
267 {
268 void *t;
269- lv->segments->node_alloc *= 2;
270- t = grub_realloc (lv->segments->nodes,
271- sizeof (*lv->segments->nodes)
272- * lv->segments->node_alloc);
273+ grub_size_t sz;
274+
275+ if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
276+ grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
277+ goto fail2;
278+
279+ t = grub_realloc (lv->segments->nodes, sz);
280 if (!t)
281 goto fail2;
282 lv->segments->nodes = t;
283@@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
284 if (comp->segment_alloc == comp->segment_count)
285 {
286 void *t;
287- comp->segment_alloc *= 2;
288- t = grub_realloc (comp->segments,
289- comp->segment_alloc
290- * sizeof (*comp->segments));
291+ grub_size_t sz;
292+
293+ if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
294+ grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
295+ goto fail2;
296+
297+ t = grub_realloc (comp->segments, sz);
298 if (!t)
299 goto fail2;
300 comp->segments = t;
301diff --git a/grub-core/font/font.c b/grub-core/font/font.c
302index 8e118b3..5edb477 100644
303--- a/grub-core/font/font.c
304+++ b/grub-core/font/font.c
305@@ -30,6 +30,7 @@
306 #include <grub/unicode.h>
307 #include <grub/fontformat.h>
308 #include <grub/env.h>
309+#include <grub/safemath.h>
310
311 GRUB_MOD_LICENSE ("GPLv3+");
312
313@@ -360,9 +361,13 @@ static char *
314 read_section_as_string (struct font_file_section *section)
315 {
316 char *str;
317+ grub_size_t sz;
318 grub_ssize_t ret;
319
320- str = grub_malloc (section->length + 1);
321+ if (grub_add (section->length, 1, &sz))
322+ return NULL;
323+
324+ str = grub_malloc (sz);
325 if (!str)
326 return 0;
327
328diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
329index 11272ef..2b65bd5 100644
330--- a/grub-core/fs/btrfs.c
331+++ b/grub-core/fs/btrfs.c
332@@ -40,6 +40,7 @@
333 #include <grub/btrfs.h>
334 #include <grub/crypto.h>
335 #include <grub/diskfilter.h>
336+#include <grub/safemath.h>
337
338 GRUB_MOD_LICENSE ("GPLv3+");
339
340@@ -329,9 +330,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
341 if (desc->allocated < desc->depth)
342 {
343 void *newdata;
344- desc->allocated *= 2;
345- newdata = grub_realloc (desc->data, sizeof (desc->data[0])
346- * desc->allocated);
347+ grub_size_t sz;
348+
349+ if (grub_mul (desc->allocated, 2, &desc->allocated) ||
350+ grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
351+ return GRUB_ERR_OUT_OF_RANGE;
352+
353+ newdata = grub_realloc (desc->data, sz);
354 if (!newdata)
355 return grub_errno;
356 desc->data = newdata;
357@@ -622,16 +627,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
358 if (data->n_devices_attached > data->n_devices_allocated)
359 {
360 void *tmp;
361- data->n_devices_allocated = 2 * data->n_devices_attached + 1;
362- data->devices_attached
363- = grub_realloc (tmp = data->devices_attached,
364- data->n_devices_allocated
365- * sizeof (data->devices_attached[0]));
366+ grub_size_t sz;
367+
368+ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
369+ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
370+ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
371+ goto fail;
372+
373+ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
374 if (!data->devices_attached)
375 {
376+ data->devices_attached = tmp;
377+
378+ fail:
379 if (ctx.dev_found)
380 grub_device_close (ctx.dev_found);
381- data->devices_attached = tmp;
382 return NULL;
383 }
384 }
385diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
386index 9b38980..ac33bcd 100644
387--- a/grub-core/fs/ext2.c
388+++ b/grub-core/fs/ext2.c
389@@ -46,6 +46,7 @@
390 #include <grub/dl.h>
391 #include <grub/types.h>
392 #include <grub/fshelp.h>
393+#include <grub/safemath.h>
394
395 GRUB_MOD_LICENSE ("GPLv3+");
396
397@@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
398 {
399 char *symlink;
400 struct grub_fshelp_node *diro = node;
401+ grub_size_t sz;
402
403 if (! diro->inode_read)
404 {
405@@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
406 }
407 }
408
409- symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
410+ if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
411+ {
412+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
413+ return NULL;
414+ }
415+
416+ symlink = grub_malloc (sz);
417 if (! symlink)
418 return 0;
419
420diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
421index 4f1b52a..7ba5b30 100644
422--- a/grub-core/fs/iso9660.c
423+++ b/grub-core/fs/iso9660.c
424@@ -28,6 +28,7 @@
425 #include <grub/fshelp.h>
426 #include <grub/charset.h>
427 #include <grub/datetime.h>
428+#include <grub/safemath.h>
429
430 GRUB_MOD_LICENSE ("GPLv3+");
431
432@@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx,
433 int len2)
434 {
435 int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
436+ grub_size_t sz;
437
438- ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
439+ if (grub_add (size, len2, &sz) ||
440+ grub_add (sz, 1, &sz))
441+ return;
442+
443+ ctx->symlink = grub_realloc (ctx->symlink, sz);
444 if (! ctx->symlink)
445 return;
446
447@@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
448 {
449 grub_size_t off = 0, csize = 1;
450 char *old;
451+ grub_size_t sz;
452+
453 csize = entry->len - 5;
454 old = ctx->filename;
455 if (ctx->filename_alloc)
456 {
457 off = grub_strlen (ctx->filename);
458- ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
459+ if (grub_add (csize, off, &sz) ||
460+ grub_add (sz, 1, &sz))
461+ return GRUB_ERR_OUT_OF_RANGE;
462+ ctx->filename = grub_realloc (ctx->filename, sz);
463 }
464 else
465 {
466 off = 0;
467- ctx->filename = grub_zalloc (csize + 1);
468+ if (grub_add (csize, 1, &sz))
469+ return GRUB_ERR_OUT_OF_RANGE;
470+ ctx->filename = grub_zalloc (sz);
471 }
472 if (!ctx->filename)
473 {
474@@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
475 if (node->have_dirents >= node->alloc_dirents)
476 {
477 struct grub_fshelp_node *new_node;
478- node->alloc_dirents *= 2;
479- new_node = grub_realloc (node,
480- sizeof (struct grub_fshelp_node)
481- + ((node->alloc_dirents
482- - ARRAY_SIZE (node->dirents))
483- * sizeof (node->dirents[0])));
484+ grub_size_t sz;
485+
486+ if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
487+ grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
488+ grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
489+ grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
490+ goto fail_0;
491+
492+ new_node = grub_realloc (node, sz);
493 if (!new_node)
494 {
495+ fail_0:
496 if (ctx.filename_alloc)
497 grub_free (ctx.filename);
498 grub_free (node);
499@@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
500 * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
501 {
502 struct grub_fshelp_node *new_node;
503- new_node = grub_realloc (node,
504- sizeof (struct grub_fshelp_node)
505- + ((node->alloc_dirents
506- - ARRAY_SIZE (node->dirents))
507- * sizeof (node->dirents[0]))
508- + grub_strlen (ctx.symlink) + 1);
509+ grub_size_t sz;
510+
511+ if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
512+ grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
513+ grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
514+ grub_add (sz, grub_strlen (ctx.symlink), &sz))
515+ goto fail_1;
516+
517+ new_node = grub_realloc (node, sz);
518 if (!new_node)
519 {
520+ fail_1:
521 if (ctx.filename_alloc)
522 grub_free (ctx.filename);
523 grub_free (node);
524diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
525index 90f7fb3..de2b107 100644
526--- a/grub-core/fs/sfs.c
527+++ b/grub-core/fs/sfs.c
528@@ -26,6 +26,7 @@
529 #include <grub/types.h>
530 #include <grub/fshelp.h>
531 #include <grub/charset.h>
532+#include <grub/safemath.h>
533
534 GRUB_MOD_LICENSE ("GPLv3+");
535
536@@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
537 if (node->cache && node->cache_size >= node->cache_allocated)
538 {
539 struct cache_entry *e = node->cache;
540- e = grub_realloc (node->cache,node->cache_allocated * 2
541- * sizeof (e[0]));
542+ grub_size_t sz;
543+
544+ if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
545+ goto fail;
546+
547+ e = grub_realloc (node->cache, sz);
548 if (!e)
549 {
550+ fail:
551 grub_errno = 0;
552 grub_free (node->cache);
553 node->cache = 0;
554@@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
555 grub_size_t len = grub_strlen (name);
556 grub_uint8_t *name_u8;
557 int ret;
558+ grub_size_t sz;
559+
560+ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
561+ grub_add (sz, 1, &sz))
562+ return 1;
563+
564 *node = grub_malloc (sizeof (**node));
565 if (!*node)
566 return 1;
567- name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
568+ name_u8 = grub_malloc (sz);
569 if (!name_u8)
570 {
571 grub_free (*node);
572@@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
573 data = grub_sfs_mount (disk);
574 if (data)
575 {
576- grub_size_t len = grub_strlen (data->label);
577- *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
578+ grub_size_t sz, len = grub_strlen (data->label);
579+
580+ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
581+ grub_add (sz, 1, &sz))
582+ return GRUB_ERR_OUT_OF_RANGE;
583+
584+ *label = grub_malloc (sz);
585 if (*label)
586 *grub_latin1_to_utf8 ((grub_uint8_t *) *label,
587 (const grub_uint8_t *) data->label,
588diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
589index 95d5c1e..7851238 100644
590--- a/grub-core/fs/squash4.c
591+++ b/grub-core/fs/squash4.c
592@@ -26,6 +26,7 @@
593 #include <grub/types.h>
594 #include <grub/fshelp.h>
595 #include <grub/deflate.h>
596+#include <grub/safemath.h>
597 #include <minilzo.h>
598
599 #include "xz.h"
600@@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
601 {
602 char *ret;
603 grub_err_t err;
604- ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
605+ grub_size_t sz;
606+
607+ if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
608+ {
609+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
610+ return NULL;
611+ }
612+
613+ ret = grub_malloc (sz);
614+ if (!ret)
615+ return NULL;
616
617 err = read_chunk (node->data, ret,
618 grub_le_to_cpu32 (node->ino.symlink.namelen),
619@@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
620
621 {
622 grub_fshelp_node_t node;
623- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
624+ grub_size_t sz;
625+
626+ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
627+ grub_add (sz, sizeof (*node), &sz))
628+ return 0;
629+
630+ node = grub_malloc (sz);
631 if (!node)
632 return 0;
633- grub_memcpy (node, dir,
634- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
635+ grub_memcpy (node, dir, sz);
636 if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
637 return 1;
638
639@@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
640 {
641 grub_err_t err;
642
643- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
644+ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
645+ grub_add (sz, sizeof (*node), &sz))
646+ return 0;
647+
648+ node = grub_malloc (sz);
649 if (!node)
650 return 0;
651
652- grub_memcpy (node, dir,
653- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
654+ grub_memcpy (node, dir, sz);
655
656 node->stsize--;
657 err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
658@@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
659 enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
660 struct grub_squash_dirent di;
661 struct grub_squash_inode ino;
662+ grub_size_t sz;
663
664 err = read_chunk (dir->data, &di, sizeof (di),
665 grub_le_to_cpu64 (dir->data->sb.diroffset)
666@@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
667 if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
668 filetype = GRUB_FSHELP_SYMLINK;
669
670- node = grub_malloc (sizeof (*node)
671- + (dir->stsize + 1) * sizeof (dir->stack[0]));
672+ if (grub_add (dir->stsize, 1, &sz) ||
673+ grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
674+ grub_add (sz, sizeof (*node), &sz))
675+ return 0;
676+
677+ node = grub_malloc (sz);
678 if (! node)
679 return 0;
680
681- grub_memcpy (node, dir,
682- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
683+ grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
684
685 node->ino = ino;
686 node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
687diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
688index a837616..21ac7f4 100644
689--- a/grub-core/fs/udf.c
690+++ b/grub-core/fs/udf.c
691@@ -28,6 +28,7 @@
692 #include <grub/charset.h>
693 #include <grub/datetime.h>
694 #include <grub/udf.h>
695+#include <grub/safemath.h>
696
697 GRUB_MOD_LICENSE ("GPLv3+");
698
699@@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
700 utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
701 }
702 if (!outbuf)
703- outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
704+ {
705+ grub_size_t size;
706+
707+ if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) ||
708+ grub_add (size, 1, &size))
709+ goto fail;
710+
711+ outbuf = grub_malloc (size);
712+ }
713 if (outbuf)
714 *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
715+
716+ fail:
717 grub_free (utf16);
718 return outbuf;
719 }
720@@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
721 grub_size_t sz = U64 (node->block.fe.file_size);
722 grub_uint8_t *raw;
723 const grub_uint8_t *ptr;
724- char *out, *optr;
725+ char *out = NULL, *optr;
726
727 if (sz < 4)
728 return NULL;
729@@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
730 if (!raw)
731 return NULL;
732 if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
733- {
734- grub_free (raw);
735- return NULL;
736- }
737+ goto fail_1;
738
739- out = grub_malloc (sz * 2 + 1);
740+ if (grub_mul (sz, 2, &sz) ||
741+ grub_add (sz, 1, &sz))
742+ goto fail_0;
743+
744+ out = grub_malloc (sz);
745 if (!out)
746 {
747+ fail_0:
748 grub_free (raw);
749 return NULL;
750 }
751@@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
752 {
753 grub_size_t s;
754 if ((grub_size_t) (ptr - raw + 4) > sz)
755- goto fail;
756+ goto fail_1;
757 if (!(ptr[2] == 0 && ptr[3] == 0))
758- goto fail;
759+ goto fail_1;
760 s = 4 + ptr[1];
761 if ((grub_size_t) (ptr - raw + s) > sz)
762- goto fail;
763+ goto fail_1;
764 switch (*ptr)
765 {
766 case 1:
767 if (ptr[1])
768- goto fail;
769+ goto fail_1;
770 /* Fallthrough. */
771 case 2:
772 /* in 4 bytes. out: 1 byte. */
773@@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
774 if (optr != out)
775 *optr++ = '/';
776 if (!read_string (ptr + 4, s - 4, optr))
777- goto fail;
778+ goto fail_1;
779 optr += grub_strlen (optr);
780 break;
781 default:
782- goto fail;
783+ goto fail_1;
784 }
785 ptr += s;
786 }
787@@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
788 grub_free (raw);
789 return out;
790
791- fail:
792+ fail_1:
793 grub_free (raw);
794 grub_free (out);
795 grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
796diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
797index 96ffecb..ea65902 100644
798--- a/grub-core/fs/xfs.c
799+++ b/grub-core/fs/xfs.c
800@@ -25,6 +25,7 @@
801 #include <grub/dl.h>
802 #include <grub/types.h>
803 #include <grub/fshelp.h>
804+#include <grub/safemath.h>
805
806 GRUB_MOD_LICENSE ("GPLv3+");
807
808@@ -899,6 +900,7 @@ static struct grub_xfs_data *
809 grub_xfs_mount (grub_disk_t disk)
810 {
811 struct grub_xfs_data *data = 0;
812+ grub_size_t sz;
813
814 data = grub_zalloc (sizeof (struct grub_xfs_data));
815 if (!data)
816@@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
817 if (!grub_xfs_sb_valid(data))
818 goto fail;
819
820- data = grub_realloc (data,
821- sizeof (struct grub_xfs_data)
822- - sizeof (struct grub_xfs_inode)
823- + grub_xfs_inode_size(data) + 1);
824+ if (grub_add (grub_xfs_inode_size (data),
825+ sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
826+ goto fail;
827+
828+ data = grub_realloc (data, sz);
829
830 if (! data)
831 goto fail;
832diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
833index 381dde5..36d0373 100644
834--- a/grub-core/fs/zfs/zfs.c
835+++ b/grub-core/fs/zfs/zfs.c
836@@ -55,6 +55,7 @@
837 #include <grub/deflate.h>
838 #include <grub/crypto.h>
839 #include <grub/i18n.h>
840+#include <grub/safemath.h>
841
842 GRUB_MOD_LICENSE ("GPLv3+");
843
844@@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data,
845 if (data->n_devices_attached > data->n_devices_allocated)
846 {
847 void *tmp;
848- data->n_devices_allocated = 2 * data->n_devices_attached + 1;
849- data->devices_attached
850- = grub_realloc (tmp = data->devices_attached,
851- data->n_devices_allocated
852- * sizeof (data->devices_attached[0]));
853+ grub_size_t sz;
854+
855+ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
856+ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
857+ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
858+ return GRUB_ERR_OUT_OF_RANGE;
859+
860+ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
861 if (!data->devices_attached)
862 {
863 data->devices_attached = tmp;
864@@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
865 {
866 char *nvpair;
867 char *ret;
868- grub_size_t size;
869+ grub_size_t size, sz;
870 int found;
871
872 found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
873 &size, 0);
874 if (!found)
875 return 0;
876- ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
877+
878+ if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
879+ return 0;
880+
881+ ret = grub_zalloc (sz);
882 if (!ret)
883 return 0;
884 grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
885diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c
886index 1402e0b..de3b015 100644
887--- a/grub-core/fs/zfs/zfscrypt.c
888+++ b/grub-core/fs/zfs/zfscrypt.c
889@@ -22,6 +22,7 @@
890 #include <grub/misc.h>
891 #include <grub/disk.h>
892 #include <grub/partition.h>
893+#include <grub/safemath.h>
894 #include <grub/dl.h>
895 #include <grub/types.h>
896 #include <grub/zfs/zfs.h>
897@@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
898 int passphrase)
899 {
900 struct grub_zfs_wrap_key *key;
901+ grub_size_t sz;
902+
903 if (!passphrase && keylen > 32)
904 keylen = 32;
905- key = grub_malloc (sizeof (*key) + keylen);
906+ if (grub_add (sizeof (*key), keylen, &sz))
907+ return GRUB_ERR_OUT_OF_RANGE;
908+ key = grub_malloc (sz);
909 if (!key)
910 return grub_errno;
911 key->is_passphrase = passphrase;
912diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
913index fd7744a..3288609 100644
914--- a/grub-core/lib/arg.c
915+++ b/grub-core/lib/arg.c
916@@ -23,6 +23,7 @@
917 #include <grub/term.h>
918 #include <grub/extcmd.h>
919 #include <grub/i18n.h>
920+#include <grub/safemath.h>
921
922 /* Built-in parser for default options. */
923 static const struct grub_arg_option help_options[] =
924@@ -216,7 +217,13 @@ static inline grub_err_t
925 add_arg (char ***argl, int *num, char *s)
926 {
927 char **p = *argl;
928- *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *));
929+ grub_size_t sz;
930+
931+ if (grub_add (++(*num), 1, &sz) ||
932+ grub_mul (sz, sizeof (char *), &sz))
933+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
934+
935+ *argl = grub_realloc (*argl, sz);
936 if (! *argl)
937 {
938 grub_free (p);
939@@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
940 grub_size_t argcnt;
941 struct grub_arg_list *list;
942 const struct grub_arg_option *options;
943+ grub_size_t sz0, sz1;
944
945 options = extcmd->options;
946 if (! options)
947@@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
948 argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
949 }
950
951- list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt);
952+ if (grub_mul (sizeof (*list), i, &sz0) ||
953+ grub_mul (sizeof (char *), argcnt, &sz1) ||
954+ grub_add (sz0, sz1, &sz0))
955+ {
956+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
957+ return 0;
958+ }
959+
960+ list = grub_zalloc (sz0);
961 if (! list)
962 return 0;
963
964diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
965index 3730ed3..b92cbe9 100644
966--- a/grub-core/loader/i386/bsd.c
967+++ b/grub-core/loader/i386/bsd.c
968@@ -35,6 +35,7 @@
969 #include <grub/ns8250.h>
970 #include <grub/bsdlabel.h>
971 #include <grub/crypto.h>
972+#include <grub/safemath.h>
973 #include <grub/verify.h>
974 #ifdef GRUB_MACHINE_PCBIOS
975 #include <grub/machine/int.h>
976@@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void)
977 struct grub_netbsd_btinfo_modules *mods;
978 unsigned i;
979 grub_err_t err;
980+ grub_size_t sz;
981
982 for (mod = netbsd_mods; mod; mod = mod->next)
983 modcnt++;
984
985- mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
986+ if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) ||
987+ grub_add (sz, sizeof (*mods), &sz))
988+ return GRUB_ERR_OUT_OF_RANGE;
989+
990+ mods = grub_malloc (sz);
991 if (!mods)
992 return grub_errno;
993
994diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
995index e332d5e..906ec7d 100644
996--- a/grub-core/net/dns.c
997+++ b/grub-core/net/dns.c
998@@ -22,6 +22,7 @@
999 #include <grub/i18n.h>
1000 #include <grub/err.h>
1001 #include <grub/time.h>
1002+#include <grub/safemath.h>
1003
1004 struct dns_cache_element
1005 {
1006@@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s)
1007 {
1008 int na = dns_servers_alloc * 2;
1009 struct grub_net_network_level_address *ns;
1010+ grub_size_t sz;
1011+
1012 if (na < 8)
1013 na = 8;
1014- ns = grub_realloc (dns_servers, na * sizeof (ns[0]));
1015+
1016+ if (grub_mul (na, sizeof (ns[0]), &sz))
1017+ return GRUB_ERR_OUT_OF_RANGE;
1018+
1019+ ns = grub_realloc (dns_servers, sz);
1020 if (!ns)
1021 return grub_errno;
1022 dns_servers_alloc = na;
1023diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
1024index d57fb72..4dfcc31 100644
1025--- a/grub-core/normal/charset.c
1026+++ b/grub-core/normal/charset.c
1027@@ -48,6 +48,7 @@
1028 #include <grub/unicode.h>
1029 #include <grub/term.h>
1030 #include <grub/normal.h>
1031+#include <grub/safemath.h>
1032
1033 #if HAVE_FONT_SOURCE
1034 #include "widthspec.h"
1035@@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
1036 {
1037 struct grub_unicode_combining *n;
1038 unsigned j;
1039+ grub_size_t sz;
1040
1041 if (!haveout)
1042 continue;
1043@@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
1044 n = out->combining_inline;
1045 else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
1046 {
1047- n = grub_realloc (out->combining_ptr,
1048- sizeof (n[0]) * (out->ncomb + 1));
1049+ if (grub_add (out->ncomb, 1, &sz) ||
1050+ grub_mul (sz, sizeof (n[0]), &sz))
1051+ goto fail;
1052+
1053+ n = grub_realloc (out->combining_ptr, sz);
1054 if (!n)
1055 {
1056+ fail:
1057 grub_errno = GRUB_ERR_NONE;
1058 continue;
1059 }
1060diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
1061index c57242e..de03fe6 100644
1062--- a/grub-core/normal/cmdline.c
1063+++ b/grub-core/normal/cmdline.c
1064@@ -28,6 +28,7 @@
1065 #include <grub/env.h>
1066 #include <grub/i18n.h>
1067 #include <grub/charset.h>
1068+#include <grub/safemath.h>
1069
1070 static grub_uint32_t *kill_buf;
1071
1072@@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
1073 if (len + (*llen) >= (*max_len))
1074 {
1075 grub_uint32_t *nbuf;
1076- (*max_len) *= 2;
1077- nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
1078+ grub_size_t sz;
1079+
1080+ if (grub_mul (*max_len, 2, max_len) ||
1081+ grub_mul (*max_len, sizeof (grub_uint32_t), &sz))
1082+ {
1083+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
1084+ goto fail;
1085+ }
1086+
1087+ nbuf = grub_realloc ((*buf), sz);
1088 if (nbuf)
1089 (*buf) = nbuf;
1090 else
1091 {
1092+ fail:
1093 grub_print_error ();
1094 grub_errno = GRUB_ERR_NONE;
1095 (*max_len) /= 2;
1096diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
1097index 1993995..50eef91 100644
1098--- a/grub-core/normal/menu_entry.c
1099+++ b/grub-core/normal/menu_entry.c
1100@@ -27,6 +27,7 @@
1101 #include <grub/auth.h>
1102 #include <grub/i18n.h>
1103 #include <grub/charset.h>
1104+#include <grub/safemath.h>
1105
1106 enum update_mode
1107 {
1108@@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra)
1109 {
1110 if (linep->max_len < linep->len + extra)
1111 {
1112- linep->max_len = 2 * (linep->len + extra);
1113- linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
1114+ grub_size_t sz0, sz1;
1115+
1116+ if (grub_add (linep->len, extra, &sz0) ||
1117+ grub_mul (sz0, 2, &sz0) ||
1118+ grub_add (sz0, 1, &sz1) ||
1119+ grub_mul (sz1, sizeof (linep->buf[0]), &sz1))
1120+ return 0;
1121+
1122+ linep->buf = grub_realloc (linep->buf, sz1);
1123 if (! linep->buf)
1124 return 0;
1125+ linep->max_len = sz0;
1126 }
1127
1128 return 1;
1129diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c
1130index 217ec5d..5751fdd 100644
1131--- a/grub-core/script/argv.c
1132+++ b/grub-core/script/argv.c
1133@@ -20,6 +20,7 @@
1134 #include <grub/mm.h>
1135 #include <grub/misc.h>
1136 #include <grub/script_sh.h>
1137+#include <grub/safemath.h>
1138
1139 /* Return nearest power of two that is >= v. */
1140 static unsigned
1141@@ -81,11 +82,16 @@ int
1142 grub_script_argv_next (struct grub_script_argv *argv)
1143 {
1144 char **p = argv->args;
1145+ grub_size_t sz;
1146
1147 if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
1148 return 0;
1149
1150- p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
1151+ if (grub_add (argv->argc, 2, &sz) ||
1152+ grub_mul (sz, sizeof (char *), &sz))
1153+ return 1;
1154+
1155+ p = grub_realloc (p, round_up_exp (sz));
1156 if (! p)
1157 return 1;
1158
1159@@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s,
1160 {
1161 grub_size_t a;
1162 char *p = argv->args[argv->argc - 1];
1163+ grub_size_t sz;
1164
1165 if (! s)
1166 return 0;
1167
1168 a = p ? grub_strlen (p) : 0;
1169
1170- p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char)));
1171+ if (grub_add (a, slen, &sz) ||
1172+ grub_add (sz, 1, &sz) ||
1173+ grub_mul (sz, sizeof (char), &sz))
1174+ return 1;
1175+
1176+ p = grub_realloc (p, round_up_exp (sz));
1177 if (! p)
1178 return 1;
1179
1180diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
1181index c6bd317..5fb0cbd 100644
1182--- a/grub-core/script/lexer.c
1183+++ b/grub-core/script/lexer.c
1184@@ -24,6 +24,7 @@
1185 #include <grub/mm.h>
1186 #include <grub/script_sh.h>
1187 #include <grub/i18n.h>
1188+#include <grub/safemath.h>
1189
1190 #define yytext_ptr char *
1191 #include "grub_script.tab.h"
1192@@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
1193 old = lexer->recording;
1194 if (lexer->recordlen < len)
1195 lexer->recordlen = len;
1196- lexer->recordlen *= 2;
1197+
1198+ if (grub_mul (lexer->recordlen, 2, &lexer->recordlen))
1199+ goto fail;
1200+
1201 lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
1202 if (!lexer->recording)
1203 {
1204+ fail:
1205 grub_free (old);
1206 lexer->recordpos = 0;
1207 lexer->recordlen = 0;
1208@@ -130,7 +135,7 @@ int
1209 grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
1210 const char *input)
1211 {
1212- grub_size_t len = 0;
1213+ grub_size_t len = 0, sz;
1214 char *p = 0;
1215 char *line = 0;
1216 YY_BUFFER_STATE buffer;
1217@@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
1218 }
1219 else if (len && line[len - 1] != '\n')
1220 {
1221- p = grub_realloc (line, len + 2);
1222+ if (grub_add (len, 2, &sz))
1223+ {
1224+ grub_free (line);
1225+ grub_script_yyerror (parserstate, N_("overflow is detected"));
1226+ return 1;
1227+ }
1228+
1229+ p = grub_realloc (line, sz);
1230 if (p)
1231 {
1232 p[len++] = '\n';
1233 p[len] = '\0';
1234 }
1235+ else
1236+ grub_free (line);
1237+
1238 line = p;
1239 }
1240
1241diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c
1242index b2e0315..6256e20 100644
1243--- a/grub-core/video/bitmap.c
1244+++ b/grub-core/video/bitmap.c
1245@@ -23,6 +23,7 @@
1246 #include <grub/mm.h>
1247 #include <grub/misc.h>
1248 #include <grub/i18n.h>
1249+#include <grub/safemath.h>
1250
1251 GRUB_MOD_LICENSE ("GPLv3+");
1252
1253@@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
1254 enum grub_video_blit_format blit_format)
1255 {
1256 struct grub_video_mode_info *mode_info;
1257- unsigned int size;
1258+ grub_size_t size;
1259
1260 if (!bitmap)
1261 return grub_error (GRUB_ERR_BUG, "invalid argument");
1262@@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
1263
1264 mode_info->pitch = width * mode_info->bytes_per_pixel;
1265
1266- /* Calculate size needed for the data. */
1267- size = (width * mode_info->bytes_per_pixel) * height;
1268+ /* Calculate size needed for the data. */
1269+ if (grub_mul (width, mode_info->bytes_per_pixel, &size) ||
1270+ grub_mul (size, height, &size))
1271+ {
1272+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
1273+ goto fail;
1274+ }
1275
1276 (*bitmap)->data = grub_zalloc (size);
1277 if (! (*bitmap)->data)
1278- {
1279- grub_free (*bitmap);
1280- *bitmap = 0;
1281-
1282- return grub_errno;
1283- }
1284+ goto fail;
1285
1286 return GRUB_ERR_NONE;
1287+
1288+ fail:
1289+ grub_free (*bitmap);
1290+ *bitmap = NULL;
1291+
1292+ return grub_errno;
1293 }
1294
1295 /* Frees all resources allocated by bitmap. */
1296diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
1297index 61bd645..0157ff7 100644
1298--- a/grub-core/video/readers/png.c
1299+++ b/grub-core/video/readers/png.c
1300@@ -23,6 +23,7 @@
1301 #include <grub/mm.h>
1302 #include <grub/misc.h>
1303 #include <grub/bufio.h>
1304+#include <grub/safemath.h>
1305
1306 GRUB_MOD_LICENSE ("GPLv3+");
1307
1308@@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data)
1309 data->bpp <<= 1;
1310
1311 data->color_bits = color_bits;
1312- data->row_bytes = data->image_width * data->bpp;
1313+
1314+ if (grub_mul (data->image_width, data->bpp, &data->row_bytes))
1315+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
1316+
1317 if (data->color_bits <= 4)
1318- data->row_bytes = (data->image_width * data->color_bits + 7) / 8;
1319+ {
1320+ if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes))
1321+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
1322+
1323+ data->row_bytes >>= 3;
1324+ }
1325
1326 #ifndef GRUB_CPU_WORDS_BIGENDIAN
1327 if (data->is_16bit || data->is_gray || data->is_palette)
1328--
13292.14.4
1330