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