1 From 705b89f19fff03054f7167e1785461492688d61b Mon Sep 17 00:00:00 2001
2 From: Peter Jones <pjones@redhat.com>
3 Date: Wed, 15 Apr 2020 15:45:02 -0400
4 Subject: yylex: Make lexer fatal errors actually be fatal
6 When presented with a command that can't be tokenized to anything
7 smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg),
8 expecting that will stop further processing, as such:
10 #define YY_DO_BEFORE_ACTION \
11 yyg->yytext_ptr = yy_bp; \
12 yyleng = (int) (yy_cp - yy_bp); \
13 yyg->yy_hold_char = *yy_cp; \
15 if ( yyleng >= YYLMAX ) \
16 YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
17 yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \
18 yyg->yy_c_buf_p = yy_cp;
20 The code flex generates expects that YY_FATAL_ERROR() will either return
21 for it or do some form of longjmp(), or handle the error in some way at
22 least, and so the strncpy() call isn't in an "else" clause, and thus if
23 YY_FATAL_ERROR() is *not* actually fatal, it does the call with the
24 questionable limit, and predictable results ensue.
26 Unfortunately, our implementation of YY_FATAL_ERROR() is:
28 #define YY_FATAL_ERROR(msg) \
30 grub_printf (_("fatal error: %s\n"), _(msg)); \
33 The same pattern exists in yyless(), and similar problems exist in users
34 of YY_INPUT(), several places in the main parsing loop,
35 yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack,
36 yy_scan_buffer(), etc.
38 All of these callers expect YY_FATAL_ERROR() to actually be fatal, and
39 the things they do if it returns after calling it are wildly unsafe.
43 Signed-off-by: Peter Jones <pjones@redhat.com>
44 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
46 grub-core/script/yylex.l | 4 ++--
47 1 file changed, 2 insertions(+), 2 deletions(-)
49 diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l
50 index 7b44c37b7..b7203c823 100644
51 --- a/grub-core/script/yylex.l
52 +++ b/grub-core/script/yylex.l
56 * As we don't have access to yyscanner, we cannot do much except to
57 - * print the fatal error.
58 + * print the fatal error and exit.
60 #define YY_FATAL_ERROR(msg) \
62 - grub_printf (_("fatal error: %s\n"), _(msg)); \
63 + grub_fatal (_("fatal error: %s\n"), _(msg));\
66 #define COPY(str, hint) \
68 From 016977edbd5d9f6fbab6412fb8b4d1f50eb432e7 Mon Sep 17 00:00:00 2001
69 From: Peter Jones <pjones@redhat.com>
70 Date: Mon, 15 Jun 2020 10:58:42 -0400
71 Subject: safemath: Add some arithmetic primitives that check for
74 This adds a new header, include/grub/safemath.h, that includes easy to
75 use wrappers for __builtin_{add,sub,mul}_overflow() declared like:
79 where OP is grub_add, grub_sub or grub_mul. OP() returns true in the
80 case where the operation would overflow and res is not modified.
81 Otherwise, false is returned and the operation is executed.
83 These arithmetic primitives require newer compiler versions. So, bump
84 these requirements in the INSTALL file too.
86 Signed-off-by: Peter Jones <pjones@redhat.com>
87 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
89 INSTALL | 22 ++--------------------
90 include/grub/compiler.h | 8 ++++++++
91 include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++
92 3 files changed, 47 insertions(+), 20 deletions(-)
93 create mode 100644 include/grub/safemath.h
95 diff --git a/INSTALL b/INSTALL
96 index 342c158e9..991479b52 100644
99 @@ -11,27 +11,9 @@ GRUB depends on some software packages installed into your system. If
100 you don't have any of them, please obtain and install them before
101 configuring the GRUB.
103 -* GCC 4.1.3 or later
104 - Note: older versions may work but support is limited
106 - Experimental support for clang 3.3 or later (results in much bigger binaries)
107 +* GCC 5.1.0 or later
108 + Experimental support for clang 3.8.0 or later (results in much bigger binaries)
109 for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
110 - Note: clang 3.2 or later works for i386 and x86_64 targets but results in
111 - much bigger binaries.
112 - earlier versions not tested
113 - Note: clang 3.2 or later works for arm
114 - earlier versions not tested
115 - Note: clang on arm64 is not supported due to
116 - https://llvm.org/bugs/show_bug.cgi?id=26030
117 - Note: clang 3.3 or later works for mips(el)
118 - earlier versions fail to generate .reginfo and hence gprel relocations
120 - Note: clang 3.2 or later works for powerpc
121 - earlier versions not tested
122 - Note: clang 3.5 or later works for sparc64
123 - earlier versions return "error: unable to interface with target machine"
124 - Note: clang has no support for ia64 and hence you can't compile GRUB
125 - for ia64 with clang
127 * GNU Bison 2.3 or later
128 * GNU gettext 0.17 or later
129 diff --git a/include/grub/compiler.h b/include/grub/compiler.h
130 index c9e1d7a73..8f3be3ae7 100644
131 --- a/include/grub/compiler.h
132 +++ b/include/grub/compiler.h
134 # define WARN_UNUSED_RESULT
137 +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
138 +# define CLANG_PREREQ(maj,min) \
139 + ((__clang_major__ > (maj)) || \
140 + (__clang_major__ == (maj) && __clang_minor__ >= (min)))
142 +# define CLANG_PREREQ(maj,min) 0
145 #endif /* ! GRUB_COMPILER_HEADER */
146 diff --git a/include/grub/safemath.h b/include/grub/safemath.h
148 index 000000000..c17b89bba
150 +++ b/include/grub/safemath.h
153 + * GRUB -- GRand Unified Bootloader
154 + * Copyright (C) 2020 Free Software Foundation, Inc.
156 + * GRUB is free software: you can redistribute it and/or modify
157 + * it under the terms of the GNU General Public License as published by
158 + * the Free Software Foundation, either version 3 of the License, or
159 + * (at your option) any later version.
161 + * GRUB is distributed in the hope that it will be useful,
162 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
163 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
164 + * GNU General Public License for more details.
166 + * You should have received a copy of the GNU General Public License
167 + * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
169 + * Arithmetic operations that protect against overflow.
172 +#ifndef GRUB_SAFEMATH_H
173 +#define GRUB_SAFEMATH_H 1
175 +#include <grub/compiler.h>
177 +/* These appear in gcc 5.1 and clang 3.8. */
178 +#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
180 +#define grub_add(a, b, res) __builtin_add_overflow(a, b, res)
181 +#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
182 +#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
185 +#error gcc 5.1 or newer or clang 3.8 or newer is required
188 +#endif /* GRUB_SAFEMATH_H */
190 From f80ca28e207484650fc7634545cd3dc6037de3c8 Mon Sep 17 00:00:00 2001
191 From: Peter Jones <pjones@redhat.com>
192 Date: Mon, 15 Jun 2020 12:15:29 -0400
193 Subject: calloc: Make sure we always have an overflow-checking
196 This tries to make sure that everywhere in this source tree, we always have
197 an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.)
198 available, and that they all safely check for overflow and return NULL when
201 Signed-off-by: Peter Jones <pjones@redhat.com>
202 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
204 grub-core/kern/emu/misc.c | 12 +++++++++
205 grub-core/kern/emu/mm.c | 10 ++++++++
206 grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++
207 grub-core/lib/libgcrypt_wrap/mem.c | 11 ++++++--
208 grub-core/lib/posix_wrap/stdlib.h | 8 +++++-
209 include/grub/emu/misc.h | 1 +
210 include/grub/mm.h | 6 +++++
211 7 files changed, 85 insertions(+), 3 deletions(-)
213 diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
214 index 65db79baa..dfd8a8ec4 100644
215 --- a/grub-core/kern/emu/misc.c
216 +++ b/grub-core/kern/emu/misc.c
217 @@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
222 +xcalloc (grub_size_t nmemb, grub_size_t size)
226 + p = calloc (nmemb, size);
228 + grub_util_error ("%s", _("out of memory"));
234 xmalloc (grub_size_t size)
236 diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
237 index f262e95e3..145b01d37 100644
238 --- a/grub-core/kern/emu/mm.c
239 +++ b/grub-core/kern/emu/mm.c
242 #include <grub/i18n.h>
245 +grub_calloc (grub_size_t nmemb, grub_size_t size)
248 + ret = calloc (nmemb, size);
250 + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
255 grub_malloc (grub_size_t size)
257 diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
258 index ee88ff611..f2822a836 100644
259 --- a/grub-core/kern/mm.c
260 +++ b/grub-core/kern/mm.c
263 #include <grub/i18n.h>
264 #include <grub/mm_private.h>
265 +#include <grub/safemath.h>
272 @@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_size_t size)
277 + * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
278 + * integer overflow.
281 +grub_calloc (grub_size_t nmemb, grub_size_t size)
284 + grub_size_t sz = 0;
286 + if (grub_mul (nmemb, size, &sz))
288 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
292 + ret = grub_memalign (0, sz);
296 + grub_memset (ret, 0, sz);
300 /* Allocate SIZE bytes and return the pointer. */
302 grub_malloc (grub_size_t size)
303 @@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
308 +grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size)
313 + grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
315 + ptr = grub_calloc (nmemb, size);
317 + grub_printf ("%p\n", ptr);
322 grub_debug_malloc (const char *file, int line, grub_size_t size)
324 diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
325 index beeb661a3..74c6eafe5 100644
326 --- a/grub-core/lib/libgcrypt_wrap/mem.c
327 +++ b/grub-core/lib/libgcrypt_wrap/mem.c
329 #include <grub/crypto.h>
331 #include <grub/env.h>
332 +#include <grub/safemath.h>
334 GRUB_MOD_LICENSE ("GPLv3+");
336 @@ -36,7 +37,10 @@ void *
337 gcry_xcalloc (size_t n, size_t m)
340 - ret = grub_zalloc (n * m);
342 + if (grub_mul (n, m, &sz))
343 + grub_fatal ("gcry_xcalloc would overflow");
344 + ret = grub_zalloc (sz);
346 grub_fatal ("gcry_xcalloc failed");
348 @@ -56,7 +60,10 @@ void *
349 gcry_xcalloc_secure (size_t n, size_t m)
352 - ret = grub_zalloc (n * m);
354 + if (grub_mul (n, m, &sz))
355 + grub_fatal ("gcry_xcalloc would overflow");
356 + ret = grub_zalloc (sz);
358 grub_fatal ("gcry_xcalloc failed");
360 diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
361 index 3b46f47ff..7a8d385e9 100644
362 --- a/grub-core/lib/posix_wrap/stdlib.h
363 +++ b/grub-core/lib/posix_wrap/stdlib.h
367 #include <grub/misc.h>
368 +#include <grub/safemath.h>
372 @@ -37,7 +38,12 @@ malloc (grub_size_t size)
374 calloc (grub_size_t size, grub_size_t nelem)
376 - return grub_zalloc (size * nelem);
379 + if (grub_mul (size, nelem, &sz))
382 + return grub_zalloc (sz);
386 diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
387 index ce464cfd0..ff9c48a64 100644
388 --- a/include/grub/emu/misc.h
389 +++ b/include/grub/emu/misc.h
390 @@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev);
391 #define GRUB_HOST_PRIuLONG_LONG "llu"
392 #define GRUB_HOST_PRIxLONG_LONG "llx"
394 +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT;
395 void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT;
396 void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT;
397 char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT;
398 diff --git a/include/grub/mm.h b/include/grub/mm.h
399 index 28e2e53eb..9c38dd3ca 100644
400 --- a/include/grub/mm.h
401 +++ b/include/grub/mm.h
405 void grub_mm_init_region (void *addr, grub_size_t size);
406 +void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
407 void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
408 void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
409 void EXPORT_FUNC(grub_free) (void *ptr);
410 @@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug);
411 void grub_mm_dump_free (void);
412 void grub_mm_dump (unsigned lineno);
414 +#define grub_calloc(nmemb, size) \
415 + grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size)
417 #define grub_malloc(size) \
418 grub_debug_malloc (GRUB_FILE, __LINE__, size)
420 @@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno);
421 #define grub_free(ptr) \
422 grub_debug_free (GRUB_FILE, __LINE__, ptr)
424 +void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line,
425 + grub_size_t nmemb, grub_size_t size);
426 void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
428 void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
430 From 65dfa11751111173ce6f492afce13d4a2c2b006c Mon Sep 17 00:00:00 2001
431 From: Peter Jones <pjones@redhat.com>
432 Date: Mon, 15 Jun 2020 12:26:01 -0400
433 Subject: calloc: Use calloc() at most places
435 This modifies most of the places we do some form of:
439 to use calloc(Y, Z) instead.
441 Among other issues, this fixes:
442 - allocation of integer overflow in grub_png_decode_image_header()
443 reported by Chris Coulson,
444 - allocation of integer overflow in luks_recover_key()
445 reported by Chris Coulson,
446 - allocation of integer overflow in grub_lvm_detect()
447 reported by Chris Coulson.
449 Fixes: CVE-2020-14308
451 Signed-off-by: Peter Jones <pjones@redhat.com>
452 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
454 grub-core/bus/usb/usbhub.c | 8 ++++----
455 grub-core/commands/efi/lsefisystab.c | 3 ++-
456 grub-core/commands/legacycfg.c | 6 +++---
457 grub-core/commands/menuentry.c | 2 +-
458 grub-core/commands/nativedisk.c | 2 +-
459 grub-core/commands/parttool.c | 12 +++++++++---
460 grub-core/commands/regexp.c | 2 +-
461 grub-core/commands/search_wrap.c | 2 +-
462 grub-core/disk/diskfilter.c | 4 ++--
463 grub-core/disk/ieee1275/ofdisk.c | 2 +-
464 grub-core/disk/ldm.c | 14 +++++++-------
465 grub-core/disk/luks.c | 2 +-
466 grub-core/disk/lvm.c | 8 ++++----
467 grub-core/disk/xen/xendisk.c | 2 +-
468 grub-core/efiemu/loadcore.c | 2 +-
469 grub-core/efiemu/mm.c | 6 +++---
470 grub-core/font/font.c | 3 +--
471 grub-core/fs/affs.c | 6 +++---
472 grub-core/fs/btrfs.c | 6 +++---
473 grub-core/fs/hfs.c | 2 +-
474 grub-core/fs/hfsplus.c | 6 +++---
475 grub-core/fs/iso9660.c | 2 +-
476 grub-core/fs/ntfs.c | 4 ++--
477 grub-core/fs/sfs.c | 2 +-
478 grub-core/fs/tar.c | 2 +-
479 grub-core/fs/udf.c | 4 ++--
480 grub-core/fs/zfs/zfs.c | 4 ++--
481 grub-core/gfxmenu/gui_string_util.c | 2 +-
482 grub-core/gfxmenu/widget-box.c | 4 ++--
483 grub-core/io/gzio.c | 2 +-
484 grub-core/kern/efi/efi.c | 6 +++---
485 grub-core/kern/emu/hostdisk.c | 2 +-
486 grub-core/kern/fs.c | 2 +-
487 grub-core/kern/misc.c | 2 +-
488 grub-core/kern/parser.c | 2 +-
489 grub-core/kern/uboot/uboot.c | 2 +-
490 grub-core/lib/libgcrypt/cipher/ac.c | 8 ++++----
491 grub-core/lib/libgcrypt/cipher/primegen.c | 4 ++--
492 grub-core/lib/libgcrypt/cipher/pubkey.c | 4 ++--
493 grub-core/lib/priority_queue.c | 2 +-
494 grub-core/lib/reed_solomon.c | 7 +++----
495 grub-core/lib/relocator.c | 10 +++++-----
496 grub-core/lib/zstd/fse_decompress.c | 2 +-
497 grub-core/loader/arm/linux.c | 2 +-
498 grub-core/loader/efi/chainloader.c | 2 +-
499 grub-core/loader/i386/bsdXX.c | 2 +-
500 grub-core/loader/i386/xnu.c | 4 ++--
501 grub-core/loader/macho.c | 2 +-
502 grub-core/loader/multiboot_elfxx.c | 2 +-
503 grub-core/loader/xnu.c | 2 +-
504 grub-core/mmap/mmap.c | 4 ++--
505 grub-core/net/bootp.c | 2 +-
506 grub-core/net/dns.c | 10 +++++-----
507 grub-core/net/net.c | 4 ++--
508 grub-core/normal/charset.c | 10 +++++-----
509 grub-core/normal/cmdline.c | 14 +++++++-------
510 grub-core/normal/menu_entry.c | 14 +++++++-------
511 grub-core/normal/menu_text.c | 4 ++--
512 grub-core/normal/term.c | 4 ++--
513 grub-core/osdep/linux/getroot.c | 6 +++---
514 grub-core/osdep/windows/getroot.c | 2 +-
515 grub-core/osdep/windows/hostdisk.c | 4 ++--
516 grub-core/osdep/windows/init.c | 2 +-
517 grub-core/osdep/windows/platform.c | 4 ++--
518 grub-core/osdep/windows/relpath.c | 2 +-
519 grub-core/partmap/gpt.c | 2 +-
520 grub-core/partmap/msdos.c | 2 +-
521 grub-core/script/execute.c | 2 +-
522 grub-core/tests/fake_input.c | 2 +-
523 grub-core/tests/video_checksum.c | 6 +++---
524 grub-core/video/capture.c | 2 +-
525 grub-core/video/emu/sdl.c | 2 +-
526 grub-core/video/i386/pc/vga.c | 2 +-
527 grub-core/video/readers/png.c | 2 +-
528 include/grub/unicode.h | 4 ++--
529 util/getroot.c | 2 +-
530 util/grub-file.c | 2 +-
531 util/grub-fstest.c | 4 ++--
532 util/grub-install-common.c | 2 +-
533 util/grub-install.c | 4 ++--
534 util/grub-mkimagexx.c | 6 ++----
535 util/grub-mkrescue.c | 4 ++--
536 util/grub-mkstandalone.c | 2 +-
537 util/grub-pe2elf.c | 12 +++++-------
538 util/grub-probe.c | 4 ++--
539 85 files changed, 175 insertions(+), 174 deletions(-)
541 diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
542 index 34a7ff1b5..a06cce302 100644
543 --- a/grub-core/bus/usb/usbhub.c
544 +++ b/grub-core/bus/usb/usbhub.c
545 @@ -149,8 +149,8 @@ grub_usb_add_hub (grub_usb_device_t dev)
546 grub_usb_set_configuration (dev, 1);
548 dev->nports = hubdesc.portcnt;
549 - dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
550 - dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0]));
551 + dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0]));
552 + dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0]));
553 if (!dev->children || !dev->ports)
555 grub_free (dev->children);
556 @@ -268,8 +268,8 @@ grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *d
558 /* Query the number of ports the root Hub has. */
559 hub->nports = controller->dev->hubports (controller);
560 - hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports);
561 - hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports);
562 + hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0]));
563 + hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0]));
564 if (!hub->devices || !hub->ports)
566 grub_free (hub->devices);
567 diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c
568 index df1030221..cd81507f5 100644
569 --- a/grub-core/commands/efi/lsefisystab.c
570 +++ b/grub-core/commands/efi/lsefisystab.c
571 @@ -71,7 +71,8 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
572 grub_printf ("Vendor: ");
574 for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
575 - vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1);
576 + /* Allocate extra 3 bytes to simplify math. */
577 + vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1);
580 *grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
581 diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
582 index db7a8f002..5e3ec0d5e 100644
583 --- a/grub-core/commands/legacycfg.c
584 +++ b/grub-core/commands/legacycfg.c
585 @@ -314,7 +314,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
587 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
589 - cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
590 + cutargs = grub_calloc (argc - 1, sizeof (cutargs[0]));
594 @@ -436,7 +436,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
597 bsdargc = cutargc + 2;
598 - bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
599 + bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0]));
603 @@ -559,7 +559,7 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused
604 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"),
607 - newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
608 + newargs = grub_calloc (argc + 1, sizeof (newargs[0]));
611 grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
612 diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
613 index 2c5363da7..9164df744 100644
614 --- a/grub-core/commands/menuentry.c
615 +++ b/grub-core/commands/menuentry.c
616 @@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
619 /* Save argc, args to pass as parameters to block arg later. */
620 - menu_args = grub_malloc (sizeof (char*) * (argc + 1));
621 + menu_args = grub_calloc (argc + 1, sizeof (char *));
625 diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
626 index 699447d11..7c8f97f6a 100644
627 --- a/grub-core/commands/nativedisk.c
628 +++ b/grub-core/commands/nativedisk.c
629 @@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
631 path_prefix = prefix;
633 - mods = grub_malloc (argc * sizeof (mods[0]));
634 + mods = grub_calloc (argc, sizeof (mods[0]));
638 diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c
639 index 22b46b187..051e31320 100644
640 --- a/grub-core/commands/parttool.c
641 +++ b/grub-core/commands/parttool.c
642 @@ -59,7 +59,13 @@ grub_parttool_register(const char *part_name,
643 for (nargs = 0; args[nargs].name != 0; nargs++);
645 cur->args = (struct grub_parttool_argdesc *)
646 - grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
647 + grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc));
654 grub_memcpy (cur->args, args,
655 (nargs + 1) * sizeof (struct grub_parttool_argdesc));
657 @@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
661 - parsed = (int *) grub_zalloc (argc * sizeof (int));
662 + parsed = (int *) grub_calloc (argc, sizeof (int));
664 for (i = 1; i < argc; i++)
666 @@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
669 pargs = (struct grub_parttool_args *)
670 - grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args));
671 + grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args));
672 for (j = i; j < argc; j++)
675 diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c
676 index f00b184c8..4019164f3 100644
677 --- a/grub-core/commands/regexp.c
678 +++ b/grub-core/commands/regexp.c
679 @@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
683 - matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1));
684 + matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
688 diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
689 index d7fd26b94..47fc8eb99 100644
690 --- a/grub-core/commands/search_wrap.c
691 +++ b/grub-core/commands/search_wrap.c
692 @@ -122,7 +122,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
693 for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++)
696 - hints = grub_malloc (sizeof (hints[0]) * nhints);
697 + hints = grub_calloc (nhints, sizeof (hints[0]));
701 diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
702 index c3b578acf..68ca9e0be 100644
703 --- a/grub-core/disk/diskfilter.c
704 +++ b/grub-core/disk/diskfilter.c
705 @@ -1134,7 +1134,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
706 array->lvs->segments->node_count = nmemb;
707 array->lvs->segments->raid_member_size = disk_size;
708 array->lvs->segments->nodes
709 - = grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0]));
710 + = grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0]));
711 array->lvs->segments->stripe_size = stripe_size;
712 for (i = 0; i < nmemb; i++)
714 @@ -1226,7 +1226,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
716 for (p = disk->partition; p; p = p->parent)
718 - pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0]));
719 + pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0]));
721 for (p = disk->partition; p; p = p->parent)
722 pv->partmaps[s++] = xstrdup (p->partmap->name);
723 diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
724 index f73257e66..03674cb47 100644
725 --- a/grub-core/disk/ieee1275/ofdisk.c
726 +++ b/grub-core/disk/ieee1275/ofdisk.c
727 @@ -297,7 +297,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
728 /* Power machines documentation specify 672 as maximum SAS disks in
729 one system. Using a slightly larger value to be safe. */
731 - table = grub_malloc (table_size * sizeof (grub_uint64_t));
732 + table = grub_calloc (table_size, sizeof (grub_uint64_t));
736 diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
737 index 2a22d2d6c..e6323701a 100644
738 --- a/grub-core/disk/ldm.c
739 +++ b/grub-core/disk/ldm.c
740 @@ -323,8 +323,8 @@ make_vg (grub_disk_t disk,
741 lv->segments->type = GRUB_DISKFILTER_MIRROR;
742 lv->segments->node_count = 0;
743 lv->segments->node_alloc = 8;
744 - lv->segments->nodes = grub_zalloc (sizeof (*lv->segments->nodes)
745 - * lv->segments->node_alloc);
746 + lv->segments->nodes = grub_calloc (lv->segments->node_alloc,
747 + sizeof (*lv->segments->nodes));
748 if (!lv->segments->nodes)
750 ptr = vblk[i].dynamic;
751 @@ -543,8 +543,8 @@ make_vg (grub_disk_t disk,
753 comp->segment_alloc = 8;
754 comp->segment_count = 0;
755 - comp->segments = grub_malloc (sizeof (*comp->segments)
756 - * comp->segment_alloc);
757 + comp->segments = grub_calloc (comp->segment_alloc,
758 + sizeof (*comp->segments));
762 @@ -590,8 +590,8 @@ make_vg (grub_disk_t disk,
764 comp->segments->node_count = read_int (ptr + 1, *ptr);
765 comp->segments->node_alloc = comp->segments->node_count;
766 - comp->segments->nodes = grub_zalloc (sizeof (*comp->segments->nodes)
767 - * comp->segments->node_alloc);
768 + comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
769 + sizeof (*comp->segments->nodes));
770 if (!lv->segments->nodes)
773 @@ -1017,7 +1017,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
774 *nsectors = lv->size;
775 if (*nsectors > max_nsectors)
776 *nsectors = max_nsectors;
777 - *sectors = grub_malloc (*nsectors * sizeof (**sectors));
778 + *sectors = grub_calloc (*nsectors, sizeof (**sectors));
781 for (i = 0; i < *nsectors; i++)
782 diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
783 index 86c50c612..18b3a8bb1 100644
784 --- a/grub-core/disk/luks.c
785 +++ b/grub-core/disk/luks.c
786 @@ -336,7 +336,7 @@ luks_recover_key (grub_disk_t source,
787 && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes)
788 max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes);
790 - split_key = grub_malloc (keysize * max_stripes);
791 + split_key = grub_calloc (keysize, max_stripes);
795 diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
796 index 7b265c780..d1df640b3 100644
797 --- a/grub-core/disk/lvm.c
798 +++ b/grub-core/disk/lvm.c
799 @@ -173,7 +173,7 @@ grub_lvm_detect (grub_disk_t disk,
802 /* Allocate buffer space for the circular worst-case scenario. */
803 - metadatabuf = grub_malloc (2 * mda_size);
804 + metadatabuf = grub_calloc (2, mda_size);
808 @@ -426,7 +426,7 @@ grub_lvm_detect (grub_disk_t disk,
812 - lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count);
813 + lv->segments = grub_calloc (lv->segment_count, sizeof (*seg));
816 for (i = 0; i < lv->segment_count; i++)
817 @@ -483,8 +483,8 @@ grub_lvm_detect (grub_disk_t disk,
818 if (seg->node_count != 1)
819 seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
821 - seg->nodes = grub_zalloc (sizeof (*stripe)
822 - * seg->node_count);
823 + seg->nodes = grub_calloc (seg->node_count,
827 p = grub_strstr (p, "stripes = [");
828 diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c
829 index 48476cbbf..d6612eebd 100644
830 --- a/grub-core/disk/xen/xendisk.c
831 +++ b/grub-core/disk/xen/xendisk.c
832 @@ -426,7 +426,7 @@ grub_xendisk_init (void)
836 - virtdisks = grub_malloc (ctr * sizeof (virtdisks[0]));
837 + virtdisks = grub_calloc (ctr, sizeof (virtdisks[0]));
840 if (grub_xenstore_dir ("device/vbd", fill, &ctr))
841 diff --git a/grub-core/efiemu/loadcore.c b/grub-core/efiemu/loadcore.c
842 index 44085ef81..2b924623f 100644
843 --- a/grub-core/efiemu/loadcore.c
844 +++ b/grub-core/efiemu/loadcore.c
845 @@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e)
847 grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
848 grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
849 - grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
850 + grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym));
853 for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
854 diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c
855 index 52a032f7b..9b8e0d0ad 100644
856 --- a/grub-core/efiemu/mm.c
857 +++ b/grub-core/efiemu/mm.c
858 @@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void)
859 /* Initialize variables*/
860 grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
861 scanline_events = (struct grub_efiemu_mmap_scan *)
862 - grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
863 + grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2);
865 /* Number of chunks can't increase more than by factor of 2 */
866 result = (grub_efi_memory_descriptor_t *)
867 - grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
868 + grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2);
869 if (!result || !scanline_events)
872 @@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void)
874 /* Preallocate mmap */
875 efiemu_mmap = (grub_efi_memory_descriptor_t *)
876 - grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
877 + grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t));
880 grub_efiemu_unload ();
881 diff --git a/grub-core/font/font.c b/grub-core/font/font.c
882 index 85a292557..8e118b315 100644
883 --- a/grub-core/font/font.c
884 +++ b/grub-core/font/font.c
885 @@ -293,8 +293,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
886 font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
888 /* Allocate the character index array. */
889 - font->char_index = grub_malloc (font->num_chars
890 - * sizeof (struct char_index_entry));
891 + font->char_index = grub_calloc (font->num_chars, sizeof (struct char_index_entry));
892 if (!font->char_index)
894 font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
895 diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
896 index 6b6a2bc91..220b3712f 100644
897 --- a/grub-core/fs/affs.c
898 +++ b/grub-core/fs/affs.c
899 @@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node_t node)
902 latin1[symlink_size] = 0;
903 - utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1);
904 + utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size);
908 @@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
912 - hashtable = grub_zalloc (data->htsize * sizeof (*hashtable));
913 + hashtable = grub_calloc (data->htsize, sizeof (*hashtable));
917 @@ -628,7 +628,7 @@ grub_affs_label (grub_device_t device, char **label)
919 if (len > sizeof (file.name))
920 len = sizeof (file.name);
921 - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
922 + *label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len);
924 *grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0';
926 diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
927 index 63f9657a6..4b8380439 100644
928 --- a/grub-core/fs/btrfs.c
929 +++ b/grub-core/fs/btrfs.c
930 @@ -415,7 +415,7 @@ lower_bound (struct grub_btrfs_data *data,
932 desc->allocated = 16;
934 - desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated);
935 + desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0]));
939 @@ -754,7 +754,7 @@ raid56_read_retry (struct grub_btrfs_data *data,
940 grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY;
941 grub_uint64_t i, failed_devices;
943 - buffers = grub_zalloc (sizeof(*buffers) * nstripes);
944 + buffers = grub_calloc (nstripes, sizeof (*buffers));
948 @@ -2167,7 +2167,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
949 *nsectors = 64 * 2 - 1;
950 if (*nsectors > max_nsectors)
951 *nsectors = max_nsectors;
952 - *sectors = grub_malloc (*nsectors * sizeof (**sectors));
953 + *sectors = grub_calloc (*nsectors, sizeof (**sectors));
956 for (i = 0; i < *nsectors; i++)
957 diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
958 index ac0a40990..3fe842b4d 100644
959 --- a/grub-core/fs/hfs.c
960 +++ b/grub-core/fs/hfs.c
961 @@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, char **label)
962 grub_size_t len = data->sblock.volname[0];
963 if (len > sizeof (data->sblock.volname) - 1)
964 len = sizeof (data->sblock.volname) - 1;
965 - *label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1);
966 + *label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len);
968 macroman_to_utf8 (*label, data->sblock.volname + 1,
970 diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
971 index 54786bb1c..dae43becc 100644
972 --- a/grub-core/fs/hfsplus.c
973 +++ b/grub-core/fs/hfsplus.c
974 @@ -720,7 +720,7 @@ list_nodes (void *record, void *hook_arg)
978 - keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname));
979 + keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname));
982 grub_free (filename);
983 @@ -1007,7 +1007,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
984 grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr);
986 label_len = grub_be_to_cpu16 (catkey->namelen);
987 - label_name = grub_malloc (label_len * sizeof (*label_name));
988 + label_name = grub_calloc (label_len, sizeof (*label_name));
992 @@ -1029,7 +1029,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
996 - *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1);
997 + *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1);
1000 grub_free (label_name);
1001 diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
1002 index 49c0c632b..4f1b52a55 100644
1003 --- a/grub-core/fs/iso9660.c
1004 +++ b/grub-core/fs/iso9660.c
1005 @@ -331,7 +331,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len)
1007 grub_uint16_t t[MAX_NAMELEN / 2 + 1];
1009 - p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
1010 + p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
1014 diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
1015 index fc4e1f678..2f34f76da 100644
1016 --- a/grub-core/fs/ntfs.c
1017 +++ b/grub-core/fs/ntfs.c
1018 @@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
1022 - buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1);
1023 - tmp = grub_malloc (len * sizeof (tmp[0]));
1024 + buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1);
1025 + tmp = grub_calloc (len, sizeof (tmp[0]));
1029 diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
1030 index 50c1fe72f..90f7fb379 100644
1031 --- a/grub-core/fs/sfs.c
1032 +++ b/grub-core/fs/sfs.c
1033 @@ -266,7 +266,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
1034 node->next_extent = node->block;
1035 node->cache_size = 0;
1037 - node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size);
1038 + node->cache = grub_calloc (cache_size, sizeof (node->cache[0]));
1042 diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
1043 index 7d63e0c99..c551ed6b5 100644
1044 --- a/grub-core/fs/tar.c
1045 +++ b/grub-core/fs/tar.c
1046 @@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
1047 if (data->linkname_alloc < linksize + 1)
1050 - n = grub_malloc (2 * (linksize + 1));
1051 + n = grub_calloc (2, linksize + 1);
1054 grub_free (data->linkname);
1055 diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
1056 index dc8b6e2d1..a83761674 100644
1057 --- a/grub-core/fs/udf.c
1058 +++ b/grub-core/fs/udf.c
1059 @@ -873,7 +873,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
1063 - utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
1064 + utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
1067 for (i = 0; i < utf16len; i++)
1068 @@ -883,7 +883,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
1071 utf16len = (sz - 1) / 2;
1072 - utf16 = grub_malloc (utf16len * sizeof (utf16[0]));
1073 + utf16 = grub_calloc (utf16len, sizeof (utf16[0]));
1076 for (i = 0; i < utf16len; i++)
1077 diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
1078 index 2f72e42bf..381dde556 100644
1079 --- a/grub-core/fs/zfs/zfs.c
1080 +++ b/grub-core/fs/zfs/zfs.c
1081 @@ -3325,7 +3325,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
1084 zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data);
1085 - subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0]));
1086 + subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0]));
1087 if (!subvol->keyring)
1090 @@ -4336,7 +4336,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
1091 *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
1092 if (*nsectors > max_nsectors)
1093 *nsectors = max_nsectors;
1094 - *sectors = grub_malloc (*nsectors * sizeof (**sectors));
1095 + *sectors = grub_calloc (*nsectors, sizeof (**sectors));
1098 for (i = 0; i < *nsectors; i++)
1099 diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c
1100 index a9a415e31..ba1e1eab3 100644
1101 --- a/grub-core/gfxmenu/gui_string_util.c
1102 +++ b/grub-core/gfxmenu/gui_string_util.c
1103 @@ -55,7 +55,7 @@ canonicalize_path (const char *path)
1107 - char **path_array = grub_malloc (components * sizeof (*path_array));
1108 + char **path_array = grub_calloc (components, sizeof (*path_array));
1112 diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c
1113 index b60602889..470597ded 100644
1114 --- a/grub-core/gfxmenu/widget-box.c
1115 +++ b/grub-core/gfxmenu/widget-box.c
1116 @@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix,
1117 box->content_height = 0;
1119 (struct grub_video_bitmap **)
1120 - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
1121 + grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
1122 box->scaled_pixmaps =
1123 (struct grub_video_bitmap **)
1124 - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *));
1125 + grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *));
1127 /* Initialize all pixmap pointers to NULL so that proper destruction can
1128 be performed if an error is encountered partway through construction. */
1129 diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
1130 index 6208a9763..43d98a7bd 100644
1131 --- a/grub-core/io/gzio.c
1132 +++ b/grub-core/io/gzio.c
1133 @@ -554,7 +554,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
1134 z = 1 << j; /* table entries for j-bit table */
1136 /* allocate and link in new table */
1137 - q = (struct huft *) grub_zalloc ((z + 1) * sizeof (struct huft));
1138 + q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft));
1142 diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
1143 index 96204e39b..ad170c7ce 100644
1144 --- a/grub-core/kern/efi/efi.c
1145 +++ b/grub-core/kern/efi/efi.c
1146 @@ -202,7 +202,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
1148 len = grub_strlen (var);
1149 len16 = len * GRUB_MAX_UTF16_PER_UTF8;
1150 - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
1151 + var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
1154 len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
1155 @@ -237,7 +237,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
1157 len = grub_strlen (var);
1158 len16 = len * GRUB_MAX_UTF16_PER_UTF8;
1159 - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
1160 + var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
1163 len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
1164 @@ -411,7 +411,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
1165 while (len > 0 && fp->path_name[len - 1] == 0)
1168 - dup_name = grub_malloc (len * sizeof (*dup_name));
1169 + dup_name = grub_calloc (len, sizeof (*dup_name));
1173 diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c
1174 index 8ac523953..f90b6c9ce 100644
1175 --- a/grub-core/kern/emu/hostdisk.c
1176 +++ b/grub-core/kern/emu/hostdisk.c
1177 @@ -627,7 +627,7 @@ static char *
1178 grub_util_path_concat_real (size_t n, int ext, va_list ap)
1181 - char **l = xmalloc ((n + ext) * sizeof (l[0]));
1182 + char **l = xcalloc (n + ext, sizeof (l[0]));
1186 diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
1187 index 2b85f4950..f90be6566 100644
1188 --- a/grub-core/kern/fs.c
1189 +++ b/grub-core/kern/fs.c
1190 @@ -151,7 +151,7 @@ grub_fs_blocklist_open (grub_file_t file, const char *name)
1193 /* Allocate a block list. */
1194 - blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1));
1195 + blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block));
1199 diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
1200 index 18cad5803..83c068d61 100644
1201 --- a/grub-core/kern/misc.c
1202 +++ b/grub-core/kern/misc.c
1203 @@ -691,7 +691,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
1204 args->ptr = args->prealloc;
1207 - args->ptr = grub_malloc (args->count * sizeof (args->ptr[0]));
1208 + args->ptr = grub_calloc (args->count, sizeof (args->ptr[0]));
1211 grub_errno = GRUB_ERR_NONE;
1212 diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
1213 index 78175aac2..619db3122 100644
1214 --- a/grub-core/kern/parser.c
1215 +++ b/grub-core/kern/parser.c
1216 @@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *cmdline,
1218 grub_memcpy (args, buffer, bp - buffer);
1220 - *argv = grub_malloc (sizeof (char *) * (*argc + 1));
1221 + *argv = grub_calloc (*argc + 1, sizeof (char *));
1225 diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c
1226 index be4816fe6..aac8f9ae1 100644
1227 --- a/grub-core/kern/uboot/uboot.c
1228 +++ b/grub-core/kern/uboot/uboot.c
1229 @@ -133,7 +133,7 @@ grub_uboot_dev_enum (void)
1233 - enum_devices = grub_malloc (sizeof(struct device_info) * max_devices);
1234 + enum_devices = grub_calloc (max_devices, sizeof(struct device_info));
1238 diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c
1239 index f5e946a2d..63f6fcd11 100644
1240 --- a/grub-core/lib/libgcrypt/cipher/ac.c
1241 +++ b/grub-core/lib/libgcrypt/cipher/ac.c
1242 @@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
1246 - data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
1247 + data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new));
1248 if (! data_mpis_new)
1250 err = gcry_error_from_errno (errno);
1251 @@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
1255 - arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
1256 + arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list));
1259 err = gcry_error_from_errno (errno);
1260 @@ -1283,7 +1283,7 @@ ac_data_construct (const char *identifier, int include_flags,
1261 /* We build a list of arguments to pass to
1262 gcry_sexp_build_array(). */
1263 data_length = _gcry_ac_data_length (data);
1264 - arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
1265 + arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2);
1268 err = gcry_error_from_errno (errno);
1269 @@ -1593,7 +1593,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
1272 /* Allocate list. */
1273 - arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
1274 + arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list));
1277 err = gcry_error_from_errno (errno);
1278 diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c
1279 index 2788e349f..b12e79b19 100644
1280 --- a/grub-core/lib/libgcrypt/cipher/primegen.c
1281 +++ b/grub-core/lib/libgcrypt/cipher/primegen.c
1282 @@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor,
1285 /* Allocate an array to track pool usage. */
1286 - pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
1287 + pool_in_use = gcry_calloc (n, sizeof *pool_in_use);
1290 err = gpg_err_code_from_errno (errno);
1291 @@ -765,7 +765,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
1293 log_fatal ("can't generate a prime with less than %d bits\n", 16);
1295 - mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
1296 + mods = gcry_xcalloc( no_of_small_prime_numbers, sizeof *mods);
1297 /* Make nbits fit into gcry_mpi_t implementation. */
1298 val_2 = mpi_alloc_set_ui( 2 );
1299 val_3 = mpi_alloc_set_ui( 3);
1300 diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c
1301 index 910982141..ca087ad75 100644
1302 --- a/grub-core/lib/libgcrypt/cipher/pubkey.c
1303 +++ b/grub-core/lib/libgcrypt/cipher/pubkey.c
1304 @@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1305 * array to a format string, so we have to do it this way :-(. */
1306 /* FIXME: There is now such a format specifier, so we can
1307 change the code to be more clear. */
1308 - arg_list = malloc (nelem * sizeof *arg_list);
1309 + arg_list = calloc (nelem, sizeof *arg_list);
1312 rc = gpg_err_code_from_syserror ();
1313 @@ -3233,7 +3233,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1317 - arg_list = malloc (nelem * sizeof *arg_list);
1318 + arg_list = calloc (nelem, sizeof *arg_list);
1321 rc = gpg_err_code_from_syserror ();
1322 diff --git a/grub-core/lib/priority_queue.c b/grub-core/lib/priority_queue.c
1323 index 659be0b7f..7d5e7c05a 100644
1324 --- a/grub-core/lib/priority_queue.c
1325 +++ b/grub-core/lib/priority_queue.c
1326 @@ -92,7 +92,7 @@ grub_priority_queue_new (grub_size_t elsize,
1328 struct grub_priority_queue *ret;
1330 - els = grub_malloc (elsize * 8);
1331 + els = grub_calloc (8, elsize);
1334 ret = (struct grub_priority_queue *) grub_malloc (sizeof (*ret));
1335 diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c
1336 index ee9fa7b4f..467305b46 100644
1337 --- a/grub-core/lib/reed_solomon.c
1338 +++ b/grub-core/lib/reed_solomon.c
1343 +#define xcalloc calloc
1344 #define xmalloc malloc
1345 #define grub_memset memset
1346 #define grub_memcpy memcpy
1347 @@ -158,11 +159,9 @@ rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs)
1348 gf_single_t *rs_polynomial;
1351 - m = xmalloc ((s + rs) * sizeof (gf_single_t));
1352 + m = xcalloc (s + rs, sizeof (gf_single_t));
1353 grub_memcpy (m, data, s * sizeof (gf_single_t));
1354 - grub_memset (m + s, 0, rs * sizeof (gf_single_t));
1355 - rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t));
1356 - grub_memset (rs_polynomial, 0, (rs + 1) * sizeof (gf_single_t));
1357 + rs_polynomial = xcalloc (rs + 1, sizeof (gf_single_t));
1358 rs_polynomial[rs] = 1;
1359 /* Multiply with X - a^r */
1360 for (j = 0; j < rs; j++)
1361 diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
1362 index ea3ebc719..5847aac36 100644
1363 --- a/grub-core/lib/relocator.c
1364 +++ b/grub-core/lib/relocator.c
1365 @@ -495,9 +495,9 @@ malloc_in_range (struct grub_relocator *rel,
1369 - eventt = grub_malloc (maxevents * sizeof (events[0]));
1370 + eventt = grub_calloc (maxevents, sizeof (events[0]));
1371 counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0]));
1372 - events = grub_malloc (maxevents * sizeof (events[0]));
1373 + events = grub_calloc (maxevents, sizeof (events[0]));
1374 if (!events || !eventt || !counter)
1376 grub_dprintf ("relocator", "events or counter allocation failed %d\n",
1377 @@ -963,7 +963,7 @@ malloc_in_range (struct grub_relocator *rel,
1381 - res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs);
1382 + res->subchunks = grub_calloc (nallocs, sizeof (res->subchunks[0]));
1383 if (!res->subchunks)
1385 res->nsubchunks = nallocs;
1386 @@ -1562,8 +1562,8 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
1387 count[(chunk->src & 0xff) + 1]++;
1390 - from = grub_malloc (nchunks * sizeof (sorted[0]));
1391 - to = grub_malloc (nchunks * sizeof (sorted[0]));
1392 + from = grub_calloc (nchunks, sizeof (sorted[0]));
1393 + to = grub_calloc (nchunks, sizeof (sorted[0]));
1397 diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c
1398 index 72bbead5b..2227b84bc 100644
1399 --- a/grub-core/lib/zstd/fse_decompress.c
1400 +++ b/grub-core/lib/zstd/fse_decompress.c
1402 FSE_DTable* FSE_createDTable (unsigned tableLog)
1404 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
1405 - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
1406 + return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) );
1409 void FSE_freeDTable (FSE_DTable* dt)
1410 diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
1411 index 092e8e307..979d425df 100644
1412 --- a/grub-core/loader/arm/linux.c
1413 +++ b/grub-core/loader/arm/linux.c
1414 @@ -82,7 +82,7 @@ linux_prepare_atag (void *target_atag)
1416 /* some place for cmdline, initrd and terminator. */
1417 tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4;
1418 - tmp_atag = grub_malloc (tmp_size * sizeof (grub_uint32_t));
1419 + tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t));
1423 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
1424 index cd92ea3f2..daf8c6b54 100644
1425 --- a/grub-core/loader/efi/chainloader.c
1426 +++ b/grub-core/loader/efi/chainloader.c
1427 @@ -116,7 +116,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
1428 fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
1429 fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
1431 - path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
1432 + path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
1436 diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
1437 index af6741d15..a8d8bf7da 100644
1438 --- a/grub-core/loader/i386/bsdXX.c
1439 +++ b/grub-core/loader/i386/bsdXX.c
1440 @@ -48,7 +48,7 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr)
1441 if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
1442 return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
1444 - *shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize);
1445 + *shdr = grub_calloc (e->e_shnum, e->e_shentsize);
1449 diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
1450 index e64ed08f5..b7d176b5d 100644
1451 --- a/grub-core/loader/i386/xnu.c
1452 +++ b/grub-core/loader/i386/xnu.c
1453 @@ -295,7 +295,7 @@ grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *d
1456 len = grub_strlen (name);
1457 - utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
1458 + utf16 = grub_calloc (len, sizeof (grub_uint16_t));
1462 @@ -331,7 +331,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *
1463 grub_uint16_t *utf16;
1466 - utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
1467 + utf16 = grub_calloc (namelen, sizeof (grub_uint16_t));
1470 grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);
1471 diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c
1472 index 085f9c689..05710c48e 100644
1473 --- a/grub-core/loader/macho.c
1474 +++ b/grub-core/loader/macho.c
1475 @@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const char *filename, int is_64bit)
1476 if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
1479 - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
1480 + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch));
1483 if (grub_file_read (macho->file, archs,
1484 diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
1485 index 70cd1db51..cc6853692 100644
1486 --- a/grub-core/loader/multiboot_elfxx.c
1487 +++ b/grub-core/loader/multiboot_elfxx.c
1488 @@ -217,7 +217,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
1490 grub_uint8_t *shdr, *shdrptr;
1492 - shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize);
1493 + shdr = grub_calloc (ehdr->e_shnum, ehdr->e_shentsize);
1497 diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
1498 index 7f74d1d6f..77d7060e1 100644
1499 --- a/grub-core/loader/xnu.c
1500 +++ b/grub-core/loader/xnu.c
1501 @@ -800,7 +800,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
1502 if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC)
1504 narchs = grub_be_to_cpu32 (head.nfat_arch);
1505 - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
1506 + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch));
1509 grub_file_close (file);
1510 diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
1511 index 6a31cbae3..57b4e9a72 100644
1512 --- a/grub-core/mmap/mmap.c
1513 +++ b/grub-core/mmap/mmap.c
1514 @@ -143,9 +143,9 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
1516 /* Initialize variables. */
1517 ctx.scanline_events = (struct grub_mmap_scan *)
1518 - grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
1519 + grub_calloc (mmap_num, sizeof (struct grub_mmap_scan) * 2);
1521 - present = grub_zalloc (sizeof (present[0]) * current_priority);
1522 + present = grub_calloc (current_priority, sizeof (present[0]));
1524 if (! ctx.scanline_events || !present)
1526 diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
1527 index 558d97ba1..dd0ffcdae 100644
1528 --- a/grub-core/net/bootp.c
1529 +++ b/grub-core/net/bootp.c
1530 @@ -1559,7 +1559,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
1532 return grub_error (GRUB_ERR_NET_NO_CARD, N_("no network card found"));
1534 - ifaces = grub_zalloc (ncards * sizeof (ifaces[0]));
1535 + ifaces = grub_calloc (ncards, sizeof (ifaces[0]));
1539 diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
1540 index 5d9afe093..e332d5eb4 100644
1541 --- a/grub-core/net/dns.c
1542 +++ b/grub-core/net/dns.c
1543 @@ -285,8 +285,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
1547 - *data->addresses = grub_malloc (sizeof ((*data->addresses)[0])
1548 - * grub_be_to_cpu16 (head->ancount));
1549 + *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount),
1550 + sizeof ((*data->addresses)[0]));
1551 if (!*data->addresses)
1553 grub_errno = GRUB_ERR_NONE;
1554 @@ -406,8 +406,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
1555 dns_cache[h].addresses = 0;
1556 dns_cache[h].name = grub_strdup (data->oname);
1557 dns_cache[h].naddresses = *data->naddresses;
1558 - dns_cache[h].addresses = grub_malloc (*data->naddresses
1559 - * sizeof (dns_cache[h].addresses[0]));
1560 + dns_cache[h].addresses = grub_calloc (*data->naddresses,
1561 + sizeof (dns_cache[h].addresses[0]));
1562 dns_cache[h].limit_time = grub_get_time_ms () + 1000 * ttl_all;
1563 if (!dns_cache[h].addresses || !dns_cache[h].name)
1565 @@ -479,7 +479,7 @@ grub_net_dns_lookup (const char *name,
1569 - sockets = grub_malloc (sizeof (sockets[0]) * n_servers);
1570 + sockets = grub_calloc (n_servers, sizeof (sockets[0]));
1574 diff --git a/grub-core/net/net.c b/grub-core/net/net.c
1575 index b917a75d5..fed7bc57c 100644
1576 --- a/grub-core/net/net.c
1577 +++ b/grub-core/net/net.c
1578 @@ -333,8 +333,8 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)),
1582 - ifaces = grub_zalloc (ncards * sizeof (ifaces[0]));
1583 - slaacs = grub_zalloc (ncards * sizeof (slaacs[0]));
1584 + ifaces = grub_calloc (ncards, sizeof (ifaces[0]));
1585 + slaacs = grub_calloc (ncards, sizeof (slaacs[0]));
1586 if (!ifaces || !slaacs)
1589 diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
1590 index b0ab47d73..d57fb72fa 100644
1591 --- a/grub-core/normal/charset.c
1592 +++ b/grub-core/normal/charset.c
1593 @@ -203,7 +203,7 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
1595 grub_size_t msg_len = grub_strlen (msg);
1597 - *unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
1598 + *unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t));
1602 @@ -488,7 +488,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
1606 - n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1));
1607 + n = grub_calloc (out->ncomb + 1, sizeof (n[0]));
1610 grub_errno = GRUB_ERR_NONE;
1611 @@ -842,7 +842,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
1615 - visual = grub_malloc (sizeof (visual[0]) * logical_len);
1616 + visual = grub_calloc (logical_len, sizeof (visual[0]));
1620 @@ -1165,8 +1165,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
1622 const grub_uint32_t *line_start = logical, *ptr;
1623 struct grub_unicode_glyph *visual_ptr;
1624 - *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0])
1625 - * (logical_len + 2));
1626 + *visual_out = visual_ptr = grub_calloc (logical_len + 2,
1627 + 3 * sizeof (visual_ptr[0]));
1630 for (ptr = logical; ptr <= logical + logical_len; ptr++)
1631 diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
1632 index c037d5050..c57242e2e 100644
1633 --- a/grub-core/normal/cmdline.c
1634 +++ b/grub-core/normal/cmdline.c
1635 @@ -41,7 +41,7 @@ grub_err_t
1636 grub_set_history (int newsize)
1638 grub_uint32_t **old_hist_lines = hist_lines;
1639 - hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize);
1640 + hist_lines = grub_calloc (newsize, sizeof (grub_uint32_t *));
1642 /* Copy the old lines into the new buffer. */
1644 @@ -114,7 +114,7 @@ static void
1645 grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
1647 grub_free (hist_lines[pos]);
1648 - hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
1649 + hist_lines[pos] = grub_calloc (len + 1, sizeof (grub_uint32_t));
1650 if (!hist_lines[pos])
1652 grub_print_error ();
1653 @@ -349,7 +349,7 @@ grub_cmdline_get (const char *prompt_translated)
1657 - buf = grub_malloc (max_len * sizeof (grub_uint32_t));
1658 + buf = grub_calloc (max_len, sizeof (grub_uint32_t));
1662 @@ -377,7 +377,7 @@ grub_cmdline_get (const char *prompt_translated)
1663 FOR_ACTIVE_TERM_OUTPUTS(cur)
1666 - cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
1667 + cl_terms = grub_calloc (nterms, sizeof (cl_terms[0]));
1671 @@ -385,7 +385,7 @@ grub_cmdline_get (const char *prompt_translated)
1673 cl_term_cur = cl_terms;
1675 - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
1676 + unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t));
1680 @@ -495,7 +495,7 @@ grub_cmdline_get (const char *prompt_translated)
1681 grub_uint32_t *insert;
1683 insertlen = grub_strlen (insertu8);
1684 - insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
1685 + insert = grub_calloc (insertlen + 1, sizeof (grub_uint32_t));
1688 grub_free (insertu8);
1689 @@ -602,7 +602,7 @@ grub_cmdline_get (const char *prompt_translated)
1691 grub_free (kill_buf);
1693 - kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t));
1694 + kill_buf = grub_calloc (n + 1, sizeof (grub_uint32_t));
1697 grub_print_error ();
1698 diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
1699 index cdf3590a3..1993995be 100644
1700 --- a/grub-core/normal/menu_entry.c
1701 +++ b/grub-core/normal/menu_entry.c
1702 @@ -95,8 +95,8 @@ init_line (struct screen *screen, struct line *linep)
1705 linep->max_len = 80;
1706 - linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0]));
1707 - linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0]));
1708 + linep->buf = grub_calloc (linep->max_len + 1, sizeof (linep->buf[0]));
1709 + linep->pos = grub_calloc (screen->nterms, sizeof (linep->pos[0]));
1710 if (! linep->buf || !linep->pos)
1712 grub_free (linep->buf);
1713 @@ -287,7 +287,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
1714 pos = linep->pos + (term_screen - screen->terms);
1717 - *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos));
1718 + *pos = grub_calloc (linep->len + 1, sizeof (**pos));
1720 if (i == region_start || linep == screen->lines + screen->line
1721 || (i > region_start && mode == ALL_LINES))
1722 @@ -471,7 +471,7 @@ insert_string (struct screen *screen, const char *s, int update)
1724 /* Insert the string. */
1725 current_linep = screen->lines + screen->line;
1726 - unicode_msg = grub_malloc ((p - s) * sizeof (grub_uint32_t));
1727 + unicode_msg = grub_calloc (p - s, sizeof (grub_uint32_t));
1731 @@ -1023,7 +1023,7 @@ complete (struct screen *screen, int continuous, int update)
1732 if (completion_buffer.buf)
1734 buflen = grub_strlen (completion_buffer.buf);
1735 - ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
1736 + ucs4 = grub_calloc (buflen + 1, sizeof (grub_uint32_t));
1740 @@ -1268,7 +1268,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
1741 for (i = 0; i < (unsigned) screen->num_lines; i++)
1743 grub_free (screen->lines[i].pos);
1744 - screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0]));
1745 + screen->lines[i].pos = grub_calloc (screen->nterms, sizeof (screen->lines[i].pos[0]));
1746 if (! screen->lines[i].pos)
1748 grub_print_error ();
1749 @@ -1278,7 +1278,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
1753 - screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0]));
1754 + screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0]));
1757 grub_print_error ();
1758 diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
1759 index e22bb91f6..18240e76c 100644
1760 --- a/grub-core/normal/menu_text.c
1761 +++ b/grub-core/normal/menu_text.c
1762 @@ -78,7 +78,7 @@ grub_print_message_indented_real (const char *msg, int margin_left,
1763 grub_size_t msg_len = grub_strlen (msg) + 2;
1766 - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
1767 + unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t));
1771 @@ -211,7 +211,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
1773 title = entry ? entry->title : "";
1774 title_len = grub_strlen (title);
1775 - unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
1776 + unicode_title = grub_calloc (title_len, sizeof (*unicode_title));
1777 if (! unicode_title)
1778 /* XXX How to show this error? */
1780 diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
1781 index a1e5c5a0d..cc8c173b6 100644
1782 --- a/grub-core/normal/term.c
1783 +++ b/grub-core/normal/term.c
1784 @@ -264,7 +264,7 @@ grub_term_save_pos (void)
1785 FOR_ACTIVE_TERM_OUTPUTS(cur)
1788 - ret = grub_malloc (cnt * sizeof (ret[0]));
1789 + ret = grub_calloc (cnt, sizeof (ret[0]));
1793 @@ -1013,7 +1013,7 @@ grub_xnputs (const char *str, grub_size_t msg_len)
1797 - unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t));
1798 + unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t));
1802 diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
1803 index 7adc0f30e..a5bd0752f 100644
1804 --- a/grub-core/osdep/linux/getroot.c
1805 +++ b/grub-core/osdep/linux/getroot.c
1806 @@ -168,7 +168,7 @@ grub_util_raid_getmembers (const char *name, int bootable)
1808 grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno));
1810 - devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *));
1811 + devicelist = xcalloc (info.nr_disks + 1, sizeof (char *));
1813 for (i = 0, j = 0; j < info.nr_disks; i++)
1815 @@ -241,7 +241,7 @@ grub_find_root_devices_from_btrfs (const char *dir)
1819 - ret = xmalloc ((fsi.num_devices + 1) * sizeof (ret[0]));
1820 + ret = xcalloc (fsi.num_devices + 1, sizeof (ret[0]));
1822 for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++)
1824 @@ -396,7 +396,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
1828 - entries = xmalloc (entry_max * sizeof (*entries));
1829 + entries = xcalloc (entry_max, sizeof (*entries));
1832 fp = grub_util_fopen ("/proc/self/mountinfo", "r");
1833 diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c
1834 index 661d95461..eada663b2 100644
1835 --- a/grub-core/osdep/windows/getroot.c
1836 +++ b/grub-core/osdep/windows/getroot.c
1837 @@ -59,7 +59,7 @@ grub_get_mount_point (const TCHAR *path)
1839 for (ptr = path; *ptr; ptr++);
1840 allocsize = (ptr - path + 10) * 2;
1841 - out = xmalloc (allocsize * sizeof (out[0]));
1842 + out = xcalloc (allocsize, sizeof (out[0]));
1844 /* When pointing to EFI system partition GetVolumePathName fails
1845 for ESP root and returns abberant information for everything
1846 diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c
1847 index 355100789..0be327394 100644
1848 --- a/grub-core/osdep/windows/hostdisk.c
1849 +++ b/grub-core/osdep/windows/hostdisk.c
1850 @@ -111,7 +111,7 @@ grub_util_get_windows_path_real (const char *path)
1854 - fpa = xmalloc (alloc * sizeof (fpa[0]));
1855 + fpa = xcalloc (alloc, sizeof (fpa[0]));
1857 len = GetFullPathName (tpath, alloc, fpa, NULL);
1859 @@ -399,7 +399,7 @@ grub_util_fd_opendir (const char *name)
1860 for (l = 0; name_windows[l]; l++);
1861 for (l--; l >= 0 && (name_windows[l] == '\\' || name_windows[l] == '/'); l--);
1863 - pattern = xmalloc ((l + 3) * sizeof (pattern[0]));
1864 + pattern = xcalloc (l + 3, sizeof (pattern[0]));
1865 memcpy (pattern, name_windows, l * sizeof (pattern[0]));
1867 pattern[l + 1] = '*';
1868 diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c
1869 index e8ffd62c6..6297de632 100644
1870 --- a/grub-core/osdep/windows/init.c
1871 +++ b/grub-core/osdep/windows/init.c
1872 @@ -161,7 +161,7 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
1875 targv = CommandLineToArgvW (tcmdline, argc);
1876 - *argv = xmalloc ((*argc + 1) * sizeof (argv[0]));
1877 + *argv = xcalloc (*argc + 1, sizeof (argv[0]));
1879 for (i = 0; i < *argc; i++)
1880 (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]);
1881 diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
1882 index e19a3d9a8..cb626c8c3 100644
1883 --- a/grub-core/osdep/windows/platform.c
1884 +++ b/grub-core/osdep/windows/platform.c
1885 @@ -231,8 +231,8 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
1886 grub_util_error ("%s", _("no EFI routines are available when running in BIOS mode"));
1888 distrib8_len = grub_strlen (efi_distributor);
1889 - distributor16 = xmalloc ((distrib8_len + 1) * GRUB_MAX_UTF16_PER_UTF8
1890 - * sizeof (grub_uint16_t));
1891 + distributor16 = xcalloc (distrib8_len + 1,
1892 + GRUB_MAX_UTF16_PER_UTF8 * sizeof (grub_uint16_t));
1893 distrib16_len = grub_utf8_to_utf16 (distributor16, distrib8_len * GRUB_MAX_UTF16_PER_UTF8,
1894 (const grub_uint8_t *) efi_distributor,
1896 diff --git a/grub-core/osdep/windows/relpath.c b/grub-core/osdep/windows/relpath.c
1897 index cb0861744..478e8ef14 100644
1898 --- a/grub-core/osdep/windows/relpath.c
1899 +++ b/grub-core/osdep/windows/relpath.c
1900 @@ -72,7 +72,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
1901 if (dirwindows[0] && dirwindows[1] == ':')
1904 - ret = xmalloc (sizeof (ret[0]) * (flen - offset + 2));
1905 + ret = xcalloc (flen - offset + 2, sizeof (ret[0]));
1906 if (dirwindows[offset] != '\\'
1907 && dirwindows[offset] != '/'
1908 && dirwindows[offset])
1909 diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
1910 index 103f6796f..72a2e37cd 100644
1911 --- a/grub-core/partmap/gpt.c
1912 +++ b/grub-core/partmap/gpt.c
1913 @@ -199,7 +199,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
1914 *nsectors = ctx.len;
1915 if (*nsectors > max_nsectors)
1916 *nsectors = max_nsectors;
1917 - *sectors = grub_malloc (*nsectors * sizeof (**sectors));
1918 + *sectors = grub_calloc (*nsectors, sizeof (**sectors));
1921 for (i = 0; i < *nsectors; i++)
1922 diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
1923 index 7b8e45076..ee3f24982 100644
1924 --- a/grub-core/partmap/msdos.c
1925 +++ b/grub-core/partmap/msdos.c
1926 @@ -337,7 +337,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
1927 avail_nsectors = *nsectors;
1928 if (*nsectors > max_nsectors)
1929 *nsectors = max_nsectors;
1930 - *sectors = grub_malloc (*nsectors * sizeof (**sectors));
1931 + *sectors = grub_calloc (*nsectors, sizeof (**sectors));
1934 for (i = 0; i < *nsectors; i++)
1935 diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
1936 index ee299fd0e..c8d6806fe 100644
1937 --- a/grub-core/script/execute.c
1938 +++ b/grub-core/script/execute.c
1939 @@ -553,7 +553,7 @@ gettext_append (struct grub_script_argv *result, const char *orig_str)
1940 for (iptr = orig_str; *iptr; iptr++)
1943 - ctx.allowed_strings = grub_malloc (sizeof (ctx.allowed_strings[0]) * dollar_cnt);
1944 + ctx.allowed_strings = grub_calloc (dollar_cnt, sizeof (ctx.allowed_strings[0]));
1946 if (parse_string (orig_str, gettext_save_allow, &ctx, 0))
1948 diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c
1949 index 2d6085298..b5eb516be 100644
1950 --- a/grub-core/tests/fake_input.c
1951 +++ b/grub-core/tests/fake_input.c
1952 @@ -49,7 +49,7 @@ grub_terminal_input_fake_sequence (int *seq_in, int nseq_in)
1953 saved = grub_term_inputs;
1956 - seq = grub_malloc (nseq_in * sizeof (seq[0]));
1957 + seq = grub_calloc (nseq_in, sizeof (seq[0]));
1961 diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c
1962 index 74d5b65e5..44d081069 100644
1963 --- a/grub-core/tests/video_checksum.c
1964 +++ b/grub-core/tests/video_checksum.c
1965 @@ -336,7 +336,7 @@ grub_video_capture_write_bmp (const char *fname,
1969 - grub_uint8_t *buffer = xmalloc (mode_info->width * 3);
1970 + grub_uint8_t *buffer = xcalloc (3, mode_info->width);
1971 grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1);
1972 grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1);
1973 grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1);
1974 @@ -367,7 +367,7 @@ grub_video_capture_write_bmp (const char *fname,
1978 - grub_uint8_t *buffer = xmalloc (mode_info->width * 3);
1979 + grub_uint8_t *buffer = xcalloc (3, mode_info->width);
1980 grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1);
1981 grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1);
1982 grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1);
1983 @@ -407,7 +407,7 @@ grub_video_capture_write_bmp (const char *fname,
1987 - grub_uint8_t *buffer = xmalloc (mode_info->width * 3);
1988 + grub_uint8_t *buffer = xcalloc (3, mode_info->width);
1989 grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1);
1990 grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1);
1991 grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1);
1992 diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c
1993 index 4f83c7441..4d3195e01 100644
1994 --- a/grub-core/video/capture.c
1995 +++ b/grub-core/video/capture.c
1996 @@ -89,7 +89,7 @@ grub_video_capture_start (const struct grub_video_mode_info *mode_info,
1997 framebuffer.mode_info = *mode_info;
1998 framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info);
2000 - framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch);
2001 + framebuffer.ptr = grub_calloc (framebuffer.mode_info.height, framebuffer.mode_info.pitch);
2002 if (!framebuffer.ptr)
2005 diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c
2006 index a2f639f66..0ebab6f57 100644
2007 --- a/grub-core/video/emu/sdl.c
2008 +++ b/grub-core/video/emu/sdl.c
2009 @@ -172,7 +172,7 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count,
2010 if (start + count > mode_info.number_of_colors)
2011 count = mode_info.number_of_colors - start;
2013 - tmp = grub_malloc (count * sizeof (tmp[0]));
2014 + tmp = grub_calloc (count, sizeof (tmp[0]));
2015 for (i = 0; i < count; i++)
2017 tmp[i].r = palette_data[i].r;
2018 diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c
2019 index 01f47112d..b2f776c99 100644
2020 --- a/grub-core/video/i386/pc/vga.c
2021 +++ b/grub-core/video/i386/pc/vga.c
2022 @@ -127,7 +127,7 @@ grub_video_vga_setup (unsigned int width, unsigned int height,
2024 vga_height = height ? : 480;
2026 - framebuffer.temporary_buffer = grub_malloc (vga_height * VGA_WIDTH);
2027 + framebuffer.temporary_buffer = grub_calloc (vga_height, VGA_WIDTH);
2028 framebuffer.front_page = 0;
2029 framebuffer.back_page = 0;
2030 if (!framebuffer.temporary_buffer)
2031 diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
2032 index 777e71334..61bd64537 100644
2033 --- a/grub-core/video/readers/png.c
2034 +++ b/grub-core/video/readers/png.c
2035 @@ -309,7 +309,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
2036 if (data->is_16bit || data->is_gray || data->is_palette)
2039 - data->image_data = grub_malloc (data->image_height * data->row_bytes);
2040 + data->image_data = grub_calloc (data->image_height, data->row_bytes);
2044 diff --git a/include/grub/unicode.h b/include/grub/unicode.h
2045 index a0403e91f..4de986a85 100644
2046 --- a/include/grub/unicode.h
2047 +++ b/include/grub/unicode.h
2048 @@ -293,7 +293,7 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
2049 grub_memcpy (out, in, sizeof (*in));
2050 if (in->ncomb > ARRAY_SIZE (out->combining_inline))
2052 - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
2053 + out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0]));
2054 if (!out->combining_ptr)
2057 @@ -315,7 +315,7 @@ grub_unicode_set_glyph (struct grub_unicode_glyph *out,
2058 grub_memcpy (out, in, sizeof (*in));
2059 if (in->ncomb > ARRAY_SIZE (out->combining_inline))
2061 - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
2062 + out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0]));
2063 if (!out->combining_ptr)
2065 grub_memcpy (out->combining_ptr, in->combining_ptr,
2066 diff --git a/util/getroot.c b/util/getroot.c
2067 index cdd41153c..6ae35ecaa 100644
2068 --- a/util/getroot.c
2069 +++ b/util/getroot.c
2070 @@ -200,7 +200,7 @@ make_device_name (const char *drive)
2074 - ret = xmalloc (strlen (drive) * 2);
2075 + ret = xcalloc (2, strlen (drive));
2077 for (iptr = drive; *iptr; iptr++)
2079 diff --git a/util/grub-file.c b/util/grub-file.c
2080 index 50c18b683..b2e7dd69f 100644
2081 --- a/util/grub-file.c
2082 +++ b/util/grub-file.c
2083 @@ -54,7 +54,7 @@ main (int argc, char *argv[])
2085 grub_util_host_init (&argc, &argv);
2087 - argv2 = xmalloc (argc * sizeof (argv2[0]));
2088 + argv2 = xcalloc (argc, sizeof (argv2[0]));
2090 if (argc == 2 && strcmp (argv[1], "--version") == 0)
2092 diff --git a/util/grub-fstest.c b/util/grub-fstest.c
2093 index f14e02d97..57246af7c 100644
2094 --- a/util/grub-fstest.c
2095 +++ b/util/grub-fstest.c
2096 @@ -650,7 +650,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
2097 if (args_count < num_disks)
2099 if (args_count == 0)
2100 - images = xmalloc (num_disks * sizeof (images[0]));
2101 + images = xcalloc (num_disks, sizeof (images[0]));
2102 images[args_count] = grub_canonicalize_file_name (arg);
2105 @@ -734,7 +734,7 @@ main (int argc, char *argv[])
2107 grub_util_host_init (&argc, &argv);
2109 - args = xmalloc (argc * sizeof (args[0]));
2110 + args = xcalloc (argc, sizeof (args[0]));
2112 argp_parse (&argp, argc, argv, 0, 0, 0);
2114 diff --git a/util/grub-install-common.c b/util/grub-install-common.c
2115 index fdfe2c7ea..447504d3f 100644
2116 --- a/util/grub-install-common.c
2117 +++ b/util/grub-install-common.c
2118 @@ -286,7 +286,7 @@ handle_install_list (struct install_list *il, const char *val,
2121 il->n_alloc = il->n_entries + 1;
2122 - il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0]));
2123 + il->entries = xcalloc (il->n_alloc, sizeof (il->entries[0]));
2125 for (ce = il->entries; ; ce++)
2127 diff --git a/util/grub-install.c b/util/grub-install.c
2128 index 666cef3d2..bd6d8dbb3 100644
2129 --- a/util/grub-install.c
2130 +++ b/util/grub-install.c
2131 @@ -655,7 +655,7 @@ device_map_check_duplicates (const char *dev_map)
2135 - d = xmalloc (alloced * sizeof (d[0]));
2136 + d = xcalloc (alloced, sizeof (d[0]));
2138 while (fgets (buf, sizeof (buf), fp))
2140 @@ -1374,7 +1374,7 @@ main (int argc, char *argv[])
2144 - grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1));
2145 + grub_drives = xcalloc (ndev + 1, sizeof (grub_drives[0]));
2147 for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++,
2149 diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
2150 index bc087c2b5..d97d0e7be 100644
2151 --- a/util/grub-mkimagexx.c
2152 +++ b/util/grub-mkimagexx.c
2153 @@ -2294,10 +2294,8 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
2154 + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize);
2155 smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset);
2157 - smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections);
2158 - memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections);
2159 - smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections);
2160 - memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections);
2161 + smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs));
2162 + smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs));
2164 SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target);
2166 diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
2167 index 45d6140d3..cb972f120 100644
2168 --- a/util/grub-mkrescue.c
2169 +++ b/util/grub-mkrescue.c
2170 @@ -441,8 +441,8 @@ main (int argc, char *argv[])
2171 xorriso = xstrdup ("xorriso");
2172 label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
2174 - argp_argv = xmalloc (sizeof (argp_argv[0]) * argc);
2175 - xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc);
2176 + argp_argv = xcalloc (argc, sizeof (argp_argv[0]));
2177 + xorriso_tail_argv = xcalloc (argc, sizeof (argp_argv[0]));
2179 xorriso_tail_argc = 0;
2181 diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
2182 index 4907d44c0..edf309717 100644
2183 --- a/util/grub-mkstandalone.c
2184 +++ b/util/grub-mkstandalone.c
2185 @@ -296,7 +296,7 @@ main (int argc, char *argv[])
2186 grub_util_host_init (&argc, &argv);
2187 grub_util_disable_fd_syncs ();
2189 - files = xmalloc ((argc + 1) * sizeof (files[0]));
2190 + files = xcalloc (argc + 1, sizeof (files[0]));
2192 argp_parse (&argp, argc, argv, 0, 0, 0);
2194 diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c
2195 index 0d4084a10..11331294f 100644
2196 --- a/util/grub-pe2elf.c
2197 +++ b/util/grub-pe2elf.c
2198 @@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char *name, char *image,
2199 char *pe_strtab = (image + pe_chdr->symtab_offset
2200 + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol));
2202 - section_map = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (int));
2203 + section_map = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (int));
2205 - shdr = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (shdr[0]));
2206 + shdr = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (shdr[0]));
2208 idx_reloc = pe_chdr->num_sections + 1;
2210 @@ -233,7 +233,7 @@ write_reloc_section (FILE* fp, const char *name, char *image,
2212 pe_sec = pe_shdr + shdr[i].sh_link;
2213 pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset);
2214 - rel = (elf_reloc_t *) xmalloc (pe_sec->num_relocations * sizeof (elf_reloc_t));
2215 + rel = (elf_reloc_t *) xcalloc (pe_sec->num_relocations, sizeof (elf_reloc_t));
2219 @@ -365,12 +365,10 @@ write_symbol_table (FILE* fp, const char *name, char *image,
2220 pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset);
2221 pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols);
2223 - symtab = (Elf_Sym *) xmalloc ((pe_chdr->num_symbols + 1) *
2224 - sizeof (Elf_Sym));
2225 - memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf_Sym));
2226 + symtab = (Elf_Sym *) xcalloc (pe_chdr->num_symbols + 1, sizeof (Elf_Sym));
2229 - symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int));
2230 + symtab_map = (int *) xcalloc (pe_chdr->num_symbols, sizeof (int));
2232 for (i = 0; i < (int) pe_chdr->num_symbols;
2233 i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1)
2234 diff --git a/util/grub-probe.c b/util/grub-probe.c
2235 index 81d27eead..cbe6ed94c 100644
2236 --- a/util/grub-probe.c
2237 +++ b/util/grub-probe.c
2238 @@ -361,8 +361,8 @@ probe (const char *path, char **device_names, char delim)
2239 grub_util_pull_device (*curdev);
2243 - drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1));
2245 + drives_names = xcalloc (ndev + 1, sizeof (drives_names[0]));
2247 for (curdev = device_names, curdrive = drives_names; *curdev; curdev++,
2250 From d84e89f4734711d8ff3c84b6c58985c824b4d889 Mon Sep 17 00:00:00 2001
2251 From: Peter Jones <pjones@redhat.com>
2252 Date: Mon, 15 Jun 2020 12:28:27 -0400
2253 Subject: malloc: Use overflow checking primitives where we do
2256 This attempts to fix the places where we do the following where
2257 arithmetic_expr may include unvalidated data:
2259 X = grub_malloc(arithmetic_expr);
2261 It accomplishes this by doing the arithmetic ahead of time using grub_add(),
2262 grub_sub(), grub_mul() and testing for overflow before proceeding.
2264 Among other issues, this fixes:
2265 - allocation of integer overflow in grub_video_bitmap_create()
2266 reported by Chris Coulson,
2267 - allocation of integer overflow in grub_png_decode_image_header()
2268 reported by Chris Coulson,
2269 - allocation of integer overflow in grub_squash_read_symlink()
2270 reported by Chris Coulson,
2271 - allocation of integer overflow in grub_ext2_read_symlink()
2272 reported by Chris Coulson,
2273 - allocation of integer overflow in read_section_as_string()
2274 reported by Chris Coulson.
2276 Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311
2278 Signed-off-by: Peter Jones <pjones@redhat.com>
2279 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2281 grub-core/commands/legacycfg.c | 29 +++++++++++++++----
2282 grub-core/commands/wildcard.c | 36 ++++++++++++++++++++----
2283 grub-core/disk/ldm.c | 32 +++++++++++++++------
2284 grub-core/font/font.c | 7 ++++-
2285 grub-core/fs/btrfs.c | 28 +++++++++++++------
2286 grub-core/fs/ext2.c | 10 ++++++-
2287 grub-core/fs/iso9660.c | 51 ++++++++++++++++++++++++----------
2288 grub-core/fs/sfs.c | 27 ++++++++++++++----
2289 grub-core/fs/squash4.c | 45 ++++++++++++++++++++++--------
2290 grub-core/fs/udf.c | 41 +++++++++++++++++----------
2291 grub-core/fs/xfs.c | 11 +++++---
2292 grub-core/fs/zfs/zfs.c | 22 ++++++++++-----
2293 grub-core/fs/zfs/zfscrypt.c | 7 ++++-
2294 grub-core/lib/arg.c | 20 +++++++++++--
2295 grub-core/loader/i386/bsd.c | 8 +++++-
2296 grub-core/net/dns.c | 9 +++++-
2297 grub-core/normal/charset.c | 10 +++++--
2298 grub-core/normal/cmdline.c | 14 ++++++++--
2299 grub-core/normal/menu_entry.c | 13 +++++++--
2300 grub-core/script/argv.c | 16 +++++++++--
2301 grub-core/script/lexer.c | 21 ++++++++++++--
2302 grub-core/video/bitmap.c | 25 +++++++++++------
2303 grub-core/video/readers/png.c | 13 +++++++--
2304 23 files changed, 382 insertions(+), 113 deletions(-)
2306 diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
2307 index 5e3ec0d5e..cc5971f4d 100644
2308 --- a/grub-core/commands/legacycfg.c
2309 +++ b/grub-core/commands/legacycfg.c
2311 #include <grub/auth.h>
2312 #include <grub/disk.h>
2313 #include <grub/partition.h>
2314 +#include <grub/safemath.h>
2316 GRUB_MOD_LICENSE ("GPLv3+");
2318 @@ -104,13 +105,22 @@ legacy_file (const char *filename)
2325 + if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) ||
2326 + grub_add (sz, 1, &sz))
2328 + grub_errno = GRUB_ERR_OUT_OF_RANGE;
2333 - suffix = grub_realloc (suffix, grub_strlen (suffix)
2334 - + grub_strlen (newsuffix) + 1);
2335 + suffix = grub_realloc (suffix, sz);
2341 grub_free (entrysrc);
2343 grub_free (newsuffix);
2344 @@ -154,13 +164,22 @@ legacy_file (const char *filename)
2350 + if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) ||
2351 + grub_add (sz, 1, &sz))
2353 + grub_errno = GRUB_ERR_OUT_OF_RANGE;
2358 - entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
2359 - + grub_strlen (parsed) + 1);
2360 + entrysrc = grub_realloc (entrysrc, sz);
2369 diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
2370 index 4a106ca04..cc3290311 100644
2371 --- a/grub-core/commands/wildcard.c
2372 +++ b/grub-core/commands/wildcard.c
2374 #include <grub/file.h>
2375 #include <grub/device.h>
2376 #include <grub/script_sh.h>
2377 +#include <grub/safemath.h>
2381 @@ -48,6 +49,7 @@ merge (char **dest, char **ps)
2389 @@ -60,7 +62,12 @@ merge (char **dest, char **ps)
2390 for (j = 0; ps[j]; j++)
2393 - p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
2394 + if (grub_add (i, j, &sz) ||
2395 + grub_add (sz, 1, &sz) ||
2396 + grub_mul (sz, sizeof (char *), &sz))
2399 + p = grub_realloc (dest, sz);
2403 @@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
2406 unsigned len = end - start;
2407 - char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
2411 + /* Worst case size is (len * 2 + 2 + 1). */
2412 + if (grub_mul (len, 2, &sz) ||
2413 + grub_add (sz, 3, &sz))
2416 + buffer = grub_malloc (sz);
2420 @@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
2421 struct match_devices_ctx *ctx = data;
2426 /* skip partitions if asked to. */
2427 if (ctx->noparts && grub_strchr (name, ','))
2428 @@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data)
2429 if (regexec (ctx->regexp, buffer, 0, 0, 0))
2431 grub_dprintf ("expand", "not matched\n");
2437 - t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
2438 + if (grub_add (ctx->ndev, 2, &sz) ||
2439 + grub_mul (sz, sizeof (char *), &sz))
2442 + t = grub_realloc (ctx->devs, sz);
2446 @@ -300,6 +320,7 @@ match_files_iter (const char *name,
2447 struct match_files_ctx *ctx = data;
2452 /* skip . and .. names */
2453 if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
2454 @@ -315,9 +336,14 @@ match_files_iter (const char *name,
2458 - t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
2460 + if (grub_add (ctx->nfile, 2, &sz) ||
2461 + grub_mul (sz, sizeof (char *), &sz))
2464 + t = grub_realloc (ctx->files, sz);
2471 diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
2472 index e6323701a..58f8a53e1 100644
2473 --- a/grub-core/disk/ldm.c
2474 +++ b/grub-core/disk/ldm.c
2476 #include <grub/msdos_partition.h>
2477 #include <grub/gpt_partition.h>
2478 #include <grub/i18n.h>
2479 +#include <grub/safemath.h>
2482 #include <grub/emu/misc.h>
2483 @@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
2484 struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
2485 / sizeof (struct grub_ldm_vblk)];
2488 err = grub_disk_read (disk, cursec, 0,
2489 sizeof(vblk), &vblk);
2491 @@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
2495 - lv->name = grub_malloc (*ptr + 1);
2496 + if (grub_add (*ptr, 1, &sz))
2498 + grub_free (lv->internal_id);
2502 + lv->name = grub_malloc (sz);
2505 grub_free (lv->internal_id);
2506 @@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
2507 if (lv->segments->node_alloc == lv->segments->node_count)
2510 - lv->segments->node_alloc *= 2;
2511 - t = grub_realloc (lv->segments->nodes,
2512 - sizeof (*lv->segments->nodes)
2513 - * lv->segments->node_alloc);
2516 + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
2517 + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
2520 + t = grub_realloc (lv->segments->nodes, sz);
2523 lv->segments->nodes = t;
2524 @@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
2525 if (comp->segment_alloc == comp->segment_count)
2528 - comp->segment_alloc *= 2;
2529 - t = grub_realloc (comp->segments,
2530 - comp->segment_alloc
2531 - * sizeof (*comp->segments));
2534 + if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
2535 + grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
2538 + t = grub_realloc (comp->segments, sz);
2542 diff --git a/grub-core/font/font.c b/grub-core/font/font.c
2543 index 8e118b315..5edb477ac 100644
2544 --- a/grub-core/font/font.c
2545 +++ b/grub-core/font/font.c
2547 #include <grub/unicode.h>
2548 #include <grub/fontformat.h>
2549 #include <grub/env.h>
2550 +#include <grub/safemath.h>
2552 GRUB_MOD_LICENSE ("GPLv3+");
2554 @@ -360,9 +361,13 @@ static char *
2555 read_section_as_string (struct font_file_section *section)
2561 - str = grub_malloc (section->length + 1);
2562 + if (grub_add (section->length, 1, &sz))
2565 + str = grub_malloc (sz);
2569 diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
2570 index 4b8380439..27339bdb3 100644
2571 --- a/grub-core/fs/btrfs.c
2572 +++ b/grub-core/fs/btrfs.c
2574 #include <grub/btrfs.h>
2575 #include <grub/crypto.h>
2576 #include <grub/diskfilter.h>
2577 +#include <grub/safemath.h>
2579 GRUB_MOD_LICENSE ("GPLv3+");
2581 @@ -331,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
2582 if (desc->allocated < desc->depth)
2585 - desc->allocated *= 2;
2586 - newdata = grub_realloc (desc->data, sizeof (desc->data[0])
2587 - * desc->allocated);
2590 + if (grub_mul (desc->allocated, 2, &desc->allocated) ||
2591 + grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
2592 + return GRUB_ERR_OUT_OF_RANGE;
2594 + newdata = grub_realloc (desc->data, sz);
2597 desc->data = newdata;
2598 @@ -624,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
2599 if (data->n_devices_attached > data->n_devices_allocated)
2602 - data->n_devices_allocated = 2 * data->n_devices_attached + 1;
2603 - data->devices_attached
2604 - = grub_realloc (tmp = data->devices_attached,
2605 - data->n_devices_allocated
2606 - * sizeof (data->devices_attached[0]));
2609 + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
2610 + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
2611 + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
2614 + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
2615 if (!data->devices_attached)
2617 + data->devices_attached = tmp;
2621 grub_device_close (ctx.dev_found);
2622 - data->devices_attached = tmp;
2626 diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
2627 index 9b389802a..ac33bcd68 100644
2628 --- a/grub-core/fs/ext2.c
2629 +++ b/grub-core/fs/ext2.c
2631 #include <grub/dl.h>
2632 #include <grub/types.h>
2633 #include <grub/fshelp.h>
2634 +#include <grub/safemath.h>
2636 GRUB_MOD_LICENSE ("GPLv3+");
2638 @@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
2641 struct grub_fshelp_node *diro = node;
2644 if (! diro->inode_read)
2646 @@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
2650 - symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
2651 + if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
2653 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
2657 + symlink = grub_malloc (sz);
2661 diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
2662 index 4f1b52a55..7ba5b300b 100644
2663 --- a/grub-core/fs/iso9660.c
2664 +++ b/grub-core/fs/iso9660.c
2666 #include <grub/fshelp.h>
2667 #include <grub/charset.h>
2668 #include <grub/datetime.h>
2669 +#include <grub/safemath.h>
2671 GRUB_MOD_LICENSE ("GPLv3+");
2673 @@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx,
2676 int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
2679 - ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
2680 + if (grub_add (size, len2, &sz) ||
2681 + grub_add (sz, 1, &sz))
2684 + ctx->symlink = grub_realloc (ctx->symlink, sz);
2688 @@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
2690 grub_size_t off = 0, csize = 1;
2694 csize = entry->len - 5;
2695 old = ctx->filename;
2696 if (ctx->filename_alloc)
2698 off = grub_strlen (ctx->filename);
2699 - ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
2700 + if (grub_add (csize, off, &sz) ||
2701 + grub_add (sz, 1, &sz))
2702 + return GRUB_ERR_OUT_OF_RANGE;
2703 + ctx->filename = grub_realloc (ctx->filename, sz);
2708 - ctx->filename = grub_zalloc (csize + 1);
2709 + if (grub_add (csize, 1, &sz))
2710 + return GRUB_ERR_OUT_OF_RANGE;
2711 + ctx->filename = grub_zalloc (sz);
2715 @@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
2716 if (node->have_dirents >= node->alloc_dirents)
2718 struct grub_fshelp_node *new_node;
2719 - node->alloc_dirents *= 2;
2720 - new_node = grub_realloc (node,
2721 - sizeof (struct grub_fshelp_node)
2722 - + ((node->alloc_dirents
2723 - - ARRAY_SIZE (node->dirents))
2724 - * sizeof (node->dirents[0])));
2727 + if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
2728 + grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
2729 + grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
2730 + grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
2733 + new_node = grub_realloc (node, sz);
2737 if (ctx.filename_alloc)
2738 grub_free (ctx.filename);
2740 @@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
2741 * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
2743 struct grub_fshelp_node *new_node;
2744 - new_node = grub_realloc (node,
2745 - sizeof (struct grub_fshelp_node)
2746 - + ((node->alloc_dirents
2747 - - ARRAY_SIZE (node->dirents))
2748 - * sizeof (node->dirents[0]))
2749 - + grub_strlen (ctx.symlink) + 1);
2752 + if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
2753 + grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
2754 + grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
2755 + grub_add (sz, grub_strlen (ctx.symlink), &sz))
2758 + new_node = grub_realloc (node, sz);
2762 if (ctx.filename_alloc)
2763 grub_free (ctx.filename);
2765 diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
2766 index 90f7fb379..de2b107a4 100644
2767 --- a/grub-core/fs/sfs.c
2768 +++ b/grub-core/fs/sfs.c
2770 #include <grub/types.h>
2771 #include <grub/fshelp.h>
2772 #include <grub/charset.h>
2773 +#include <grub/safemath.h>
2775 GRUB_MOD_LICENSE ("GPLv3+");
2777 @@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
2778 if (node->cache && node->cache_size >= node->cache_allocated)
2780 struct cache_entry *e = node->cache;
2781 - e = grub_realloc (node->cache,node->cache_allocated * 2
2785 + if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
2788 + e = grub_realloc (node->cache, sz);
2793 grub_free (node->cache);
2795 @@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
2796 grub_size_t len = grub_strlen (name);
2797 grub_uint8_t *name_u8;
2801 + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
2802 + grub_add (sz, 1, &sz))
2805 *node = grub_malloc (sizeof (**node));
2808 - name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
2809 + name_u8 = grub_malloc (sz);
2813 @@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
2814 data = grub_sfs_mount (disk);
2817 - grub_size_t len = grub_strlen (data->label);
2818 - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
2819 + grub_size_t sz, len = grub_strlen (data->label);
2821 + if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
2822 + grub_add (sz, 1, &sz))
2823 + return GRUB_ERR_OUT_OF_RANGE;
2825 + *label = grub_malloc (sz);
2827 *grub_latin1_to_utf8 ((grub_uint8_t *) *label,
2828 (const grub_uint8_t *) data->label,
2829 diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
2830 index 95d5c1e1f..785123894 100644
2831 --- a/grub-core/fs/squash4.c
2832 +++ b/grub-core/fs/squash4.c
2834 #include <grub/types.h>
2835 #include <grub/fshelp.h>
2836 #include <grub/deflate.h>
2837 +#include <grub/safemath.h>
2838 #include <minilzo.h>
2841 @@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
2845 - ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
2848 + if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
2850 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
2854 + ret = grub_malloc (sz);
2858 err = read_chunk (node->data, ret,
2859 grub_le_to_cpu32 (node->ino.symlink.namelen),
2860 @@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
2863 grub_fshelp_node_t node;
2864 - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
2867 + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
2868 + grub_add (sz, sizeof (*node), &sz))
2871 + node = grub_malloc (sz);
2874 - grub_memcpy (node, dir,
2875 - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
2876 + grub_memcpy (node, dir, sz);
2877 if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
2880 @@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
2884 - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
2885 + if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
2886 + grub_add (sz, sizeof (*node), &sz))
2889 + node = grub_malloc (sz);
2893 - grub_memcpy (node, dir,
2894 - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
2895 + grub_memcpy (node, dir, sz);
2898 err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
2899 @@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
2900 enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
2901 struct grub_squash_dirent di;
2902 struct grub_squash_inode ino;
2905 err = read_chunk (dir->data, &di, sizeof (di),
2906 grub_le_to_cpu64 (dir->data->sb.diroffset)
2907 @@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
2908 if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
2909 filetype = GRUB_FSHELP_SYMLINK;
2911 - node = grub_malloc (sizeof (*node)
2912 - + (dir->stsize + 1) * sizeof (dir->stack[0]));
2913 + if (grub_add (dir->stsize, 1, &sz) ||
2914 + grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
2915 + grub_add (sz, sizeof (*node), &sz))
2918 + node = grub_malloc (sz);
2922 - grub_memcpy (node, dir,
2923 - sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
2924 + grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
2927 node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
2928 diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
2929 index a83761674..21ac7f446 100644
2930 --- a/grub-core/fs/udf.c
2931 +++ b/grub-core/fs/udf.c
2933 #include <grub/charset.h>
2934 #include <grub/datetime.h>
2935 #include <grub/udf.h>
2936 +#include <grub/safemath.h>
2938 GRUB_MOD_LICENSE ("GPLv3+");
2940 @@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
2941 utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
2944 - outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
2948 + if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) ||
2949 + grub_add (size, 1, &size))
2952 + outbuf = grub_malloc (size);
2955 *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
2961 @@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
2962 grub_size_t sz = U64 (node->block.fe.file_size);
2964 const grub_uint8_t *ptr;
2966 + char *out = NULL, *optr;
2970 @@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
2973 if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
2980 - out = grub_malloc (sz * 2 + 1);
2981 + if (grub_mul (sz, 2, &sz) ||
2982 + grub_add (sz, 1, &sz))
2985 + out = grub_malloc (sz);
2992 @@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
2995 if ((grub_size_t) (ptr - raw + 4) > sz)
2998 if (!(ptr[2] == 0 && ptr[3] == 0))
3002 if ((grub_size_t) (ptr - raw + s) > sz)
3013 /* in 4 bytes. out: 1 byte. */
3014 @@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
3017 if (!read_string (ptr + 4, s - 4, optr))
3020 optr += grub_strlen (optr);
3028 @@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
3036 grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
3037 diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
3038 index 96ffecbfc..ea6590290 100644
3039 --- a/grub-core/fs/xfs.c
3040 +++ b/grub-core/fs/xfs.c
3042 #include <grub/dl.h>
3043 #include <grub/types.h>
3044 #include <grub/fshelp.h>
3045 +#include <grub/safemath.h>
3047 GRUB_MOD_LICENSE ("GPLv3+");
3049 @@ -899,6 +900,7 @@ static struct grub_xfs_data *
3050 grub_xfs_mount (grub_disk_t disk)
3052 struct grub_xfs_data *data = 0;
3055 data = grub_zalloc (sizeof (struct grub_xfs_data));
3057 @@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
3058 if (!grub_xfs_sb_valid(data))
3061 - data = grub_realloc (data,
3062 - sizeof (struct grub_xfs_data)
3063 - - sizeof (struct grub_xfs_inode)
3064 - + grub_xfs_inode_size(data) + 1);
3065 + if (grub_add (grub_xfs_inode_size (data),
3066 + sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
3069 + data = grub_realloc (data, sz);
3073 diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
3074 index 381dde556..36d0373a6 100644
3075 --- a/grub-core/fs/zfs/zfs.c
3076 +++ b/grub-core/fs/zfs/zfs.c
3078 #include <grub/deflate.h>
3079 #include <grub/crypto.h>
3080 #include <grub/i18n.h>
3081 +#include <grub/safemath.h>
3083 GRUB_MOD_LICENSE ("GPLv3+");
3085 @@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data,
3086 if (data->n_devices_attached > data->n_devices_allocated)
3089 - data->n_devices_allocated = 2 * data->n_devices_attached + 1;
3090 - data->devices_attached
3091 - = grub_realloc (tmp = data->devices_attached,
3092 - data->n_devices_allocated
3093 - * sizeof (data->devices_attached[0]));
3096 + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
3097 + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
3098 + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
3099 + return GRUB_ERR_OUT_OF_RANGE;
3101 + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
3102 if (!data->devices_attached)
3104 data->devices_attached = tmp;
3105 @@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
3110 + grub_size_t size, sz;
3113 found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
3117 - ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
3119 + if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
3122 + ret = grub_zalloc (sz);
3125 grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
3126 diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c
3127 index 1402e0bc2..de3b015f5 100644
3128 --- a/grub-core/fs/zfs/zfscrypt.c
3129 +++ b/grub-core/fs/zfs/zfscrypt.c
3131 #include <grub/misc.h>
3132 #include <grub/disk.h>
3133 #include <grub/partition.h>
3134 +#include <grub/safemath.h>
3135 #include <grub/dl.h>
3136 #include <grub/types.h>
3137 #include <grub/zfs/zfs.h>
3138 @@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
3141 struct grub_zfs_wrap_key *key;
3144 if (!passphrase && keylen > 32)
3146 - key = grub_malloc (sizeof (*key) + keylen);
3147 + if (grub_add (sizeof (*key), keylen, &sz))
3148 + return GRUB_ERR_OUT_OF_RANGE;
3149 + key = grub_malloc (sz);
3152 key->is_passphrase = passphrase;
3153 diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
3154 index fd7744a6f..3288609a5 100644
3155 --- a/grub-core/lib/arg.c
3156 +++ b/grub-core/lib/arg.c
3158 #include <grub/term.h>
3159 #include <grub/extcmd.h>
3160 #include <grub/i18n.h>
3161 +#include <grub/safemath.h>
3163 /* Built-in parser for default options. */
3164 static const struct grub_arg_option help_options[] =
3165 @@ -216,7 +217,13 @@ static inline grub_err_t
3166 add_arg (char ***argl, int *num, char *s)
3169 - *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *));
3172 + if (grub_add (++(*num), 1, &sz) ||
3173 + grub_mul (sz, sizeof (char *), &sz))
3174 + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
3176 + *argl = grub_realloc (*argl, sz);
3180 @@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
3182 struct grub_arg_list *list;
3183 const struct grub_arg_option *options;
3184 + grub_size_t sz0, sz1;
3186 options = extcmd->options;
3188 @@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
3189 argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
3192 - list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt);
3193 + if (grub_mul (sizeof (*list), i, &sz0) ||
3194 + grub_mul (sizeof (char *), argcnt, &sz1) ||
3195 + grub_add (sz0, sz1, &sz0))
3197 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
3201 + list = grub_zalloc (sz0);
3205 diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
3206 index 3730ed382..b92cbe98d 100644
3207 --- a/grub-core/loader/i386/bsd.c
3208 +++ b/grub-core/loader/i386/bsd.c
3210 #include <grub/ns8250.h>
3211 #include <grub/bsdlabel.h>
3212 #include <grub/crypto.h>
3213 +#include <grub/safemath.h>
3214 #include <grub/verify.h>
3215 #ifdef GRUB_MACHINE_PCBIOS
3216 #include <grub/machine/int.h>
3217 @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void)
3218 struct grub_netbsd_btinfo_modules *mods;
3223 for (mod = netbsd_mods; mod; mod = mod->next)
3226 - mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
3227 + if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) ||
3228 + grub_add (sz, sizeof (*mods), &sz))
3229 + return GRUB_ERR_OUT_OF_RANGE;
3231 + mods = grub_malloc (sz);
3235 diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
3236 index e332d5eb4..906ec7d67 100644
3237 --- a/grub-core/net/dns.c
3238 +++ b/grub-core/net/dns.c
3240 #include <grub/i18n.h>
3241 #include <grub/err.h>
3242 #include <grub/time.h>
3243 +#include <grub/safemath.h>
3245 struct dns_cache_element
3247 @@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s)
3249 int na = dns_servers_alloc * 2;
3250 struct grub_net_network_level_address *ns;
3255 - ns = grub_realloc (dns_servers, na * sizeof (ns[0]));
3257 + if (grub_mul (na, sizeof (ns[0]), &sz))
3258 + return GRUB_ERR_OUT_OF_RANGE;
3260 + ns = grub_realloc (dns_servers, sz);
3263 dns_servers_alloc = na;
3264 diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
3265 index d57fb72fa..4dfcc3107 100644
3266 --- a/grub-core/normal/charset.c
3267 +++ b/grub-core/normal/charset.c
3269 #include <grub/unicode.h>
3270 #include <grub/term.h>
3271 #include <grub/normal.h>
3272 +#include <grub/safemath.h>
3274 #if HAVE_FONT_SOURCE
3275 #include "widthspec.h"
3276 @@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
3278 struct grub_unicode_combining *n;
3284 @@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
3285 n = out->combining_inline;
3286 else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
3288 - n = grub_realloc (out->combining_ptr,
3289 - sizeof (n[0]) * (out->ncomb + 1));
3290 + if (grub_add (out->ncomb, 1, &sz) ||
3291 + grub_mul (sz, sizeof (n[0]), &sz))
3294 + n = grub_realloc (out->combining_ptr, sz);
3298 grub_errno = GRUB_ERR_NONE;
3301 diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
3302 index c57242e2e..de03fe63b 100644
3303 --- a/grub-core/normal/cmdline.c
3304 +++ b/grub-core/normal/cmdline.c
3306 #include <grub/env.h>
3307 #include <grub/i18n.h>
3308 #include <grub/charset.h>
3309 +#include <grub/safemath.h>
3311 static grub_uint32_t *kill_buf;
3313 @@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
3314 if (len + (*llen) >= (*max_len))
3316 grub_uint32_t *nbuf;
3318 - nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
3321 + if (grub_mul (*max_len, 2, max_len) ||
3322 + grub_mul (*max_len, sizeof (grub_uint32_t), &sz))
3324 + grub_errno = GRUB_ERR_OUT_OF_RANGE;
3328 + nbuf = grub_realloc ((*buf), sz);
3334 grub_print_error ();
3335 grub_errno = GRUB_ERR_NONE;
3337 diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
3338 index 1993995be..50eef918c 100644
3339 --- a/grub-core/normal/menu_entry.c
3340 +++ b/grub-core/normal/menu_entry.c
3342 #include <grub/auth.h>
3343 #include <grub/i18n.h>
3344 #include <grub/charset.h>
3345 +#include <grub/safemath.h>
3349 @@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra)
3351 if (linep->max_len < linep->len + extra)
3353 - linep->max_len = 2 * (linep->len + extra);
3354 - linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
3355 + grub_size_t sz0, sz1;
3357 + if (grub_add (linep->len, extra, &sz0) ||
3358 + grub_mul (sz0, 2, &sz0) ||
3359 + grub_add (sz0, 1, &sz1) ||
3360 + grub_mul (sz1, sizeof (linep->buf[0]), &sz1))
3363 + linep->buf = grub_realloc (linep->buf, sz1);
3366 + linep->max_len = sz0;
3370 diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c
3371 index 217ec5d1e..5751fdd57 100644
3372 --- a/grub-core/script/argv.c
3373 +++ b/grub-core/script/argv.c
3375 #include <grub/mm.h>
3376 #include <grub/misc.h>
3377 #include <grub/script_sh.h>
3378 +#include <grub/safemath.h>
3380 /* Return nearest power of two that is >= v. */
3382 @@ -81,11 +82,16 @@ int
3383 grub_script_argv_next (struct grub_script_argv *argv)
3385 char **p = argv->args;
3388 if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
3391 - p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
3392 + if (grub_add (argv->argc, 2, &sz) ||
3393 + grub_mul (sz, sizeof (char *), &sz))
3396 + p = grub_realloc (p, round_up_exp (sz));
3400 @@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s,
3403 char *p = argv->args[argv->argc - 1];
3409 a = p ? grub_strlen (p) : 0;
3411 - p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char)));
3412 + if (grub_add (a, slen, &sz) ||
3413 + grub_add (sz, 1, &sz) ||
3414 + grub_mul (sz, sizeof (char), &sz))
3417 + p = grub_realloc (p, round_up_exp (sz));
3421 diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
3422 index c6bd3172f..5fb0cbd0b 100644
3423 --- a/grub-core/script/lexer.c
3424 +++ b/grub-core/script/lexer.c
3426 #include <grub/mm.h>
3427 #include <grub/script_sh.h>
3428 #include <grub/i18n.h>
3429 +#include <grub/safemath.h>
3431 #define yytext_ptr char *
3432 #include "grub_script.tab.h"
3433 @@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
3434 old = lexer->recording;
3435 if (lexer->recordlen < len)
3436 lexer->recordlen = len;
3437 - lexer->recordlen *= 2;
3439 + if (grub_mul (lexer->recordlen, 2, &lexer->recordlen))
3442 lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
3443 if (!lexer->recording)
3447 lexer->recordpos = 0;
3448 lexer->recordlen = 0;
3449 @@ -130,7 +135,7 @@ int
3450 grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
3453 - grub_size_t len = 0;
3454 + grub_size_t len = 0, sz;
3457 YY_BUFFER_STATE buffer;
3458 @@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
3460 else if (len && line[len - 1] != '\n')
3462 - p = grub_realloc (line, len + 2);
3463 + if (grub_add (len, 2, &sz))
3466 + grub_script_yyerror (parserstate, N_("overflow is detected"));
3470 + p = grub_realloc (line, sz);
3482 diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c
3483 index b2e031566..6256e209a 100644
3484 --- a/grub-core/video/bitmap.c
3485 +++ b/grub-core/video/bitmap.c
3487 #include <grub/mm.h>
3488 #include <grub/misc.h>
3489 #include <grub/i18n.h>
3490 +#include <grub/safemath.h>
3492 GRUB_MOD_LICENSE ("GPLv3+");
3494 @@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
3495 enum grub_video_blit_format blit_format)
3497 struct grub_video_mode_info *mode_info;
3498 - unsigned int size;
3502 return grub_error (GRUB_ERR_BUG, "invalid argument");
3503 @@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
3505 mode_info->pitch = width * mode_info->bytes_per_pixel;
3507 - /* Calculate size needed for the data. */
3508 - size = (width * mode_info->bytes_per_pixel) * height;
3509 + /* Calculate size needed for the data. */
3510 + if (grub_mul (width, mode_info->bytes_per_pixel, &size) ||
3511 + grub_mul (size, height, &size))
3513 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
3517 (*bitmap)->data = grub_zalloc (size);
3518 if (! (*bitmap)->data)
3520 - grub_free (*bitmap);
3523 - return grub_errno;
3527 return GRUB_ERR_NONE;
3530 + grub_free (*bitmap);
3533 + return grub_errno;
3536 /* Frees all resources allocated by bitmap. */
3537 diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
3538 index 61bd64537..0157ff742 100644
3539 --- a/grub-core/video/readers/png.c
3540 +++ b/grub-core/video/readers/png.c
3542 #include <grub/mm.h>
3543 #include <grub/misc.h>
3544 #include <grub/bufio.h>
3545 +#include <grub/safemath.h>
3547 GRUB_MOD_LICENSE ("GPLv3+");
3549 @@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data)
3552 data->color_bits = color_bits;
3553 - data->row_bytes = data->image_width * data->bpp;
3555 + if (grub_mul (data->image_width, data->bpp, &data->row_bytes))
3556 + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
3558 if (data->color_bits <= 4)
3559 - data->row_bytes = (data->image_width * data->color_bits + 7) / 8;
3561 + if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes))
3562 + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
3564 + data->row_bytes >>= 3;
3567 #ifndef GRUB_CPU_WORDS_BIGENDIAN
3568 if (data->is_16bit || data->is_gray || data->is_palette)
3570 From 99c176e216b7196ac8d2af2b9bc483070b1a170a Mon Sep 17 00:00:00 2001
3571 From: Peter Jones <pjones@redhat.com>
3572 Date: Sat, 4 Jul 2020 12:25:09 -0400
3573 Subject: iso9660: Don't leak memory on realloc() failures
3575 Signed-off-by: Peter Jones <pjones@redhat.com>
3576 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3578 grub-core/fs/iso9660.c | 24 ++++++++++++++++++++----
3579 1 file changed, 20 insertions(+), 4 deletions(-)
3581 diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
3582 index 7ba5b300b..5ec4433b8 100644
3583 --- a/grub-core/fs/iso9660.c
3584 +++ b/grub-core/fs/iso9660.c
3585 @@ -533,14 +533,20 @@ add_part (struct iterate_dir_ctx *ctx,
3587 int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
3591 if (grub_add (size, len2, &sz) ||
3592 grub_add (sz, 1, &sz))
3595 - ctx->symlink = grub_realloc (ctx->symlink, sz);
3596 - if (! ctx->symlink)
3598 + new = grub_realloc (ctx->symlink, sz);
3601 + grub_free (ctx->symlink);
3602 + ctx->symlink = NULL;
3605 + ctx->symlink = new;
3607 grub_memcpy (ctx->symlink + size, part, len2);
3608 ctx->symlink[size + len2] = 0;
3609 @@ -634,7 +640,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
3610 is the length. Both are part of the `Component
3612 if (ctx->symlink && !ctx->was_continue)
3613 - add_part (ctx, "/", 1);
3615 + add_part (ctx, "/", 1);
3617 + return grub_errno;
3620 add_part (ctx, (char *) &entry->data[pos + 2],
3621 entry->data[pos + 1]);
3622 ctx->was_continue = (entry->data[pos] & 1);
3623 @@ -653,6 +664,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
3624 add_part (ctx, "/", 1);
3628 + /* Check if grub_realloc() failed in add_part(). */
3630 + return grub_errno;
3632 /* In pos + 1 the length of the `Component Record' is
3634 pos += entry->data[pos + 1] + 2;
3636 From fcc11dc1e68192d50cfb914314fb5e2f0504c498 Mon Sep 17 00:00:00 2001
3637 From: Daniel Kiper <daniel.kiper@oracle.com>
3638 Date: Tue, 7 Jul 2020 15:36:26 +0200
3639 Subject: font: Do not load more than one NAME section
3641 The GRUB font file can have one NAME section only. Though if somebody
3642 crafts a broken font file with many NAME sections and loads it then the
3643 GRUB leaks memory. So, prevent against that by loading first NAME
3644 section and failing in controlled way on following one.
3646 Reported-by: Chris Coulson <chris.coulson@canonical.com>
3647 Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
3648 Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
3650 grub-core/font/font.c | 6 ++++++
3651 1 file changed, 6 insertions(+)
3653 diff --git a/grub-core/font/font.c b/grub-core/font/font.c
3654 index 5edb477ac..d09bb38d8 100644
3655 --- a/grub-core/font/font.c
3656 +++ b/grub-core/font/font.c
3657 @@ -532,6 +532,12 @@ grub_font_load (const char *filename)
3658 if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME,
3659 sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0)
3661 + if (font->name != NULL)
3663 + grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections");
3667 font->name = read_section_as_string (§ion);
3671 From e283bb250350e8c2f7edeb344a624c57c26b042f Mon Sep 17 00:00:00 2001
3672 From: Alexey Makhalov <amakhalov@vmware.com>
3673 Date: Wed, 8 Jul 2020 20:41:56 +0000
3674 Subject: gfxmenu: Fix double free in load_image()
3676 self->bitmap should be zeroed after free. Otherwise, there is a chance
3677 to double free (USE_AFTER_FREE) it later in rescale_image().
3681 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
3682 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3684 grub-core/gfxmenu/gui_image.c | 5 ++++-
3685 1 file changed, 4 insertions(+), 1 deletion(-)
3687 diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c
3688 index 29784ed2d..6b2e976f1 100644
3689 --- a/grub-core/gfxmenu/gui_image.c
3690 +++ b/grub-core/gfxmenu/gui_image.c
3691 @@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path)
3694 if (self->bitmap && (self->bitmap != self->raw_bitmap))
3695 - grub_video_bitmap_destroy (self->bitmap);
3697 + grub_video_bitmap_destroy (self->bitmap);
3700 if (self->raw_bitmap)
3701 grub_video_bitmap_destroy (self->raw_bitmap);
3704 From 387219ffbb751afd336ebd71f1a375d9923ba416 Mon Sep 17 00:00:00 2001
3705 From: Alexey Makhalov <amakhalov@vmware.com>
3706 Date: Wed, 8 Jul 2020 21:30:43 +0000
3707 Subject: xnu: Fix double free in grub_xnu_devprop_add_property()
3709 grub_xnu_devprop_add_property() should not free utf8 and utf16 as it get
3710 allocated and freed in the caller.
3712 Minor improvement: do prop fields initialization after memory allocations.
3714 Fixes: CID 292442, CID 292457, CID 292460, CID 292466
3716 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
3717 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3719 grub-core/loader/i386/xnu.c | 17 ++++++++---------
3720 1 file changed, 8 insertions(+), 9 deletions(-)
3722 diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
3723 index b7d176b5d..e9e119259 100644
3724 --- a/grub-core/loader/i386/xnu.c
3725 +++ b/grub-core/loader/i386/xnu.c
3726 @@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
3730 - prop->name = utf8;
3731 - prop->name16 = utf16;
3732 - prop->name16len = utf16len;
3734 - prop->length = datalen;
3735 - prop->data = grub_malloc (prop->length);
3736 + prop->data = grub_malloc (datalen);
3739 - grub_free (prop->name);
3740 - grub_free (prop->name16);
3744 - grub_memcpy (prop->data, data, prop->length);
3745 + grub_memcpy (prop->data, data, datalen);
3747 + prop->name = utf8;
3748 + prop->name16 = utf16;
3749 + prop->name16len = utf16len;
3750 + prop->length = datalen;
3752 grub_list_push (GRUB_AS_LIST_P (&dev->properties),
3753 GRUB_AS_LIST (prop));
3754 return GRUB_ERR_NONE;
3756 From 8b93dd5ba38c2d726a08b271b14a74e8f960d147 Mon Sep 17 00:00:00 2001
3757 From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3758 Date: Thu, 9 Jul 2020 03:05:23 +0000
3759 Subject: lzma: Make sure we don't dereference past array
3761 The two dimensional array p->posSlotEncoder[4][64] is being dereferenced
3762 using the GetLenToPosState() macro which checks if len is less than 5,
3763 and if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294.
3764 Obviously we don't want to dereference that far out so we check if the
3765 position found is greater or equal kNumLenToPosStates (4) and bail out.
3767 N.B.: Upstream LZMA 18.05 and later has this function completely rewritten
3768 without any history.
3772 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3773 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3775 grub-core/lib/LzmaEnc.c | 10 ++++++++--
3776 1 file changed, 8 insertions(+), 2 deletions(-)
3778 diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c
3779 index f2ec04a8c..753e56a95 100644
3780 --- a/grub-core/lib/LzmaEnc.c
3781 +++ b/grub-core/lib/LzmaEnc.c
3782 @@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
3787 + UInt32 posSlot, lenToPosState;
3788 RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
3789 p->state = kMatchNextStates[p->state];
3790 LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
3791 pos -= LZMA_NUM_REPS;
3792 GetPosSlot(pos, posSlot);
3793 - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
3794 + lenToPosState = GetLenToPosState(len);
3795 + if (lenToPosState >= kNumLenToPosStates)
3797 + p->result = SZ_ERROR_DATA;
3798 + return CheckErrors(p);
3800 + RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot);
3802 if (posSlot >= kStartPosModelIndex)
3805 From 2328abbe2caa2129084da04a3e19461ddc571549 Mon Sep 17 00:00:00 2001
3806 From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3807 Date: Tue, 7 Jul 2020 15:12:25 -0400
3808 Subject: term: Fix overflow on user inputs
3810 This requires a very weird input from the serial interface but can cause
3811 an overflow in input_buf (keys) overwriting the next variable (npending)
3812 with the user choice:
3816 struct grub_terminfo_input_state {
3817 int input_buf[6]; /* 0 24 */
3818 int npending; /* 24 4 */ <- CORRUPT
3821 The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
3822 npending with "q" (aka increase npending to 161). The simplest fix is to
3823 just to disallow overwrites input_buf, which exactly what this patch does.
3827 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3828 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3830 grub-core/term/terminfo.c | 9 ++++++---
3831 1 file changed, 6 insertions(+), 3 deletions(-)
3833 diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
3834 index 63892ad42..aa3a108ca 100644
3835 --- a/grub-core/term/terminfo.c
3836 +++ b/grub-core/term/terminfo.c
3837 @@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term)
3841 -grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
3842 +grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len,
3843 int (*readkey) (struct grub_term_input *term))
3846 @@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
3850 + if (*len >= max_len) \
3856 @@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi)
3860 - grub_terminfo_readkey (termi, data->input_buf,
3861 - &data->npending, data->readkey);
3862 + grub_terminfo_readkey (termi, data->input_buf, &data->npending,
3863 + GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey);
3865 #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
3866 if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC
3868 From ba1d97845644290f03754432bcb6bbd6fefe7003 Mon Sep 17 00:00:00 2001
3869 From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3870 Date: Tue, 7 Jul 2020 22:02:31 -0400
3871 Subject: udf: Fix memory leak
3875 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3876 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3877 Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
3879 grub-core/fs/udf.c | 17 +++++++++++++----
3880 1 file changed, 13 insertions(+), 4 deletions(-)
3882 diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
3883 index 21ac7f446..2ac5c1d00 100644
3884 --- a/grub-core/fs/udf.c
3885 +++ b/grub-core/fs/udf.c
3886 @@ -965,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
3889 if (grub_udf_read_icb (dir->data, &dirent.icb, child))
3893 + grub_free (child);
3896 if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
3898 /* This is the parent directory. */
3899 @@ -988,11 +990,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
3900 dirent.file_ident_length,
3902 != dirent.file_ident_length)
3905 + grub_free (child);
3909 filename = read_string (raw, dirent.file_ident_length, 0);
3911 - grub_print_error ();
3913 + /* As the hook won't get called. */
3914 + grub_free (child);
3915 + grub_print_error ();
3918 if (filename && hook (filename, type, child, hook_data))
3921 From 3b39c2023f3aa242b008385939a7394e5946e94b Mon Sep 17 00:00:00 2001
3922 From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3923 Date: Fri, 26 Jun 2020 10:51:43 -0400
3924 Subject: multiboot2: Fix memory leak if
3925 grub_create_loader_cmdline() fails
3929 Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
3930 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3932 grub-core/loader/multiboot_mbi2.c | 6 +++++-
3933 1 file changed, 5 insertions(+), 1 deletion(-)
3935 diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
3936 index 53da78615..0efc66062 100644
3937 --- a/grub-core/loader/multiboot_mbi2.c
3938 +++ b/grub-core/loader/multiboot_mbi2.c
3939 @@ -1070,7 +1070,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
3940 err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
3941 newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
3945 + grub_free (newmod->cmdline);
3946 + grub_free (newmod);
3951 modules_last->next = newmod;
3953 From 7726da0d972c3996b3ced02586204334eb03d472 Mon Sep 17 00:00:00 2001
3954 From: Alexey Makhalov <amakhalov@vmware.com>
3955 Date: Thu, 9 Jul 2020 08:10:40 +0000
3956 Subject: tftp: Do not use priority queue
3958 There is not need to reassemble the order of blocks. Per RFC 1350,
3959 server must wait for the ACK, before sending next block. Data packets
3960 can be served immediately without putting them to priority queue.
3962 Logic to handle incoming packet is this:
3963 - if packet block id equal to expected block id, then
3965 - if packet block id is less than expected - this is retransmit
3966 of old packet, then ACK it and drop the packet,
3967 - if packet block id is more than expected - that shouldn't
3968 happen, just drop the packet.
3970 It makes the tftp receive path code simpler, smaller and faster.
3971 As a benefit, this change fixes CID# 73624 and CID# 96690, caused
3972 by following while loop:
3974 while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
3976 where tftph pointer is not moving from one iteration to another, causing
3977 to serve same packet again. Luckily, double serving didn't happen due to
3978 data->block++ during the first iteration.
3980 Fixes: CID 73624, CID 96690
3982 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
3983 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
3985 grub-core/net/tftp.c | 168 ++++++++++++++-----------------------------
3986 1 file changed, 53 insertions(+), 115 deletions(-)
3988 diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
3989 index a0817a075..84229d03d 100644
3990 --- a/grub-core/net/tftp.c
3991 +++ b/grub-core/net/tftp.c
3993 #include <grub/mm.h>
3994 #include <grub/dl.h>
3995 #include <grub/file.h>
3996 -#include <grub/priority_queue.h>
3997 #include <grub/i18n.h>
3999 GRUB_MOD_LICENSE ("GPLv3+");
4000 @@ -106,31 +105,8 @@ typedef struct tftp_data
4002 struct grub_error_saved save_err;
4003 grub_net_udp_socket_t sock;
4004 - grub_priority_queue_t pq;
4008 -cmp_block (grub_uint16_t a, grub_uint16_t b)
4010 - grub_int16_t i = (grub_int16_t) (a - b);
4019 -cmp (const void *a__, const void *b__)
4021 - struct grub_net_buff *a_ = *(struct grub_net_buff **) a__;
4022 - struct grub_net_buff *b_ = *(struct grub_net_buff **) b__;
4023 - struct tftphdr *a = (struct tftphdr *) a_->data;
4024 - struct tftphdr *b = (struct tftphdr *) b_->data;
4025 - /* We want the first elements to be on top. */
4026 - return -cmp_block (grub_be_to_cpu16 (a->u.data.block), grub_be_to_cpu16 (b->u.data.block));
4030 ack (tftp_data_t data, grub_uint64_t block)
4032 @@ -207,73 +183,60 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
4033 return GRUB_ERR_NONE;
4036 - err = grub_priority_queue_push (data->pq, &nb);
4041 - struct grub_net_buff **nb_top_p, *nb_top;
4044 - nb_top_p = grub_priority_queue_top (data->pq);
4046 - return GRUB_ERR_NONE;
4047 - nb_top = *nb_top_p;
4048 - tftph = (struct tftphdr *) nb_top->data;
4049 - if (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) >= 0)
4051 - ack (data, grub_be_to_cpu16 (tftph->u.data.block));
4052 - grub_netbuff_free (nb_top);
4053 - grub_priority_queue_pop (data->pq);
4055 - while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
4059 - grub_priority_queue_pop (data->pq);
4061 - if (file->device->net->packs.count < 50)
4062 + /* Ack old/retransmitted block. */
4063 + if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1)
4064 + ack (data, grub_be_to_cpu16 (tftph->u.data.block));
4065 + /* Ignore unexpected block. */
4066 + else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1)
4067 + grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block);
4072 + if (file->device->net->packs.count < 50)
4074 err = ack (data, data->block + 1);
4077 - file->device->net->stall = 1;
4083 - err = grub_netbuff_pull (nb_top, sizeof (tftph->opcode) +
4084 - sizeof (tftph->u.data.block));
4087 - size = nb_top->tail - nb_top->data;
4090 - if (size < data->block_size)
4092 - if (data->ack_sent < data->block)
4093 - ack (data, data->block);
4094 - file->device->net->eof = 1;
4095 - file->device->net->stall = 1;
4096 - grub_net_udp_close (data->sock);
4097 - data->sock = NULL;
4099 - /* Prevent garbage in broken cards. Is it still necessary
4100 - given that IP implementation has been fixed?
4102 - if (size > data->block_size)
4104 - err = grub_netbuff_unput (nb_top, size - data->block_size);
4108 - /* If there is data, puts packet in socket list. */
4109 - if ((nb_top->tail - nb_top->data) > 0)
4110 - grub_net_put_packet (&file->device->net->packs, nb_top);
4112 - grub_netbuff_free (nb_top);
4119 + file->device->net->stall = 1;
4121 + err = grub_netbuff_pull (nb, sizeof (tftph->opcode) +
4122 + sizeof (tftph->u.data.block));
4125 + size = nb->tail - nb->data;
4128 + if (size < data->block_size)
4130 + if (data->ack_sent < data->block)
4131 + ack (data, data->block);
4132 + file->device->net->eof = 1;
4133 + file->device->net->stall = 1;
4134 + grub_net_udp_close (data->sock);
4135 + data->sock = NULL;
4138 + * Prevent garbage in broken cards. Is it still necessary
4139 + * given that IP implementation has been fixed?
4141 + if (size > data->block_size)
4143 + err = grub_netbuff_unput (nb, size - data->block_size);
4147 + /* If there is data, puts packet in socket list. */
4148 + if ((nb->tail - nb->data) > 0)
4150 + grub_net_put_packet (&file->device->net->packs, nb);
4151 + /* Do not free nb. */
4152 + return GRUB_ERR_NONE;
4155 + grub_netbuff_free (nb);
4156 return GRUB_ERR_NONE;
4158 data->have_oack = 1;
4159 @@ -287,19 +250,6 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
4164 -destroy_pq (tftp_data_t data)
4166 - struct grub_net_buff **nb_p;
4167 - while ((nb_p = grub_priority_queue_top (data->pq)))
4169 - grub_netbuff_free (*nb_p);
4170 - grub_priority_queue_pop (data->pq);
4173 - grub_priority_queue_destroy (data->pq);
4177 tftp_open (struct grub_file *file, const char *filename)
4179 @@ -322,17 +322,9 @@ tftp_open (struct grub_file *file, const char *filename)
4180 file->not_easily_seekable = 1;
4183 - data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp);
4187 - return grub_errno;
4190 err = grub_net_resolve_address (file->device->net->server, &addr);
4193 - destroy_pq (data);
4197 @@ -396,7 +338,6 @@ tftp_open (struct grub_file *file, const char *filename)
4201 - destroy_pq (data);
4205 @@ -410,7 +351,6 @@ tftp_open (struct grub_file *file, const char *filename)
4208 grub_net_udp_close (data->sock);
4209 - destroy_pq (data);
4213 @@ -427,7 +367,6 @@ tftp_open (struct grub_file *file, const char *filename)
4216 grub_net_udp_close (data->sock);
4217 - destroy_pq (data);
4221 @@ -470,7 +409,6 @@ tftp_close (struct grub_file *file)
4222 grub_print_error ();
4223 grub_net_udp_close (data->sock);
4225 - destroy_pq (data);
4227 return GRUB_ERR_NONE;
4230 From f1e2fd65877424ee8d8d2bdd78ce28b420dee4d8 Mon Sep 17 00:00:00 2001
4231 From: Alexey Makhalov <amakhalov@vmware.com>
4232 Date: Wed, 15 Jul 2020 06:42:37 +0000
4233 Subject: relocator: Protect grub_relocator_alloc_chunk_addr()
4234 input args against integer underflow/overflow
4236 Use arithmetic macros from safemath.h to accomplish it. In this commit,
4237 I didn't want to be too paranoid to check every possible math equation
4238 for overflow/underflow. Only obvious places (with non zero chance of
4239 overflow/underflow) were refactored.
4241 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
4242 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
4244 grub-core/loader/i386/linux.c | 9 +++++++--
4245 grub-core/loader/i386/pc/linux.c | 9 +++++++--
4246 grub-core/loader/i386/xen.c | 12 ++++++++++--
4247 grub-core/loader/xnu.c | 11 +++++++----
4248 4 files changed, 31 insertions(+), 10 deletions(-)
4250 diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
4251 index 2eab9bb10..58d76fc0a 100644
4252 --- a/grub-core/loader/i386/linux.c
4253 +++ b/grub-core/loader/i386/linux.c
4255 #include <grub/lib/cmdline.h>
4256 #include <grub/linux.h>
4257 #include <grub/machine/kernel.h>
4258 +#include <grub/safemath.h>
4260 GRUB_MOD_LICENSE ("GPLv3+");
4262 @@ -549,9 +550,13 @@ grub_linux_boot (void)
4265 grub_relocator_chunk_t ch;
4268 + if (grub_add (ctx.real_size, efi_mmap_size, &sz))
4269 + return GRUB_ERR_OUT_OF_RANGE;
4271 err = grub_relocator_alloc_chunk_addr (relocator, &ch,
4272 - ctx.real_mode_target,
4273 - (ctx.real_size + efi_mmap_size));
4274 + ctx.real_mode_target, sz);
4277 real_mode_mem = get_virtual_current_address (ch);
4278 diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
4279 index 47ea2945e..31f09922b 100644
4280 --- a/grub-core/loader/i386/pc/linux.c
4281 +++ b/grub-core/loader/i386/pc/linux.c
4283 #include <grub/i386/floppy.h>
4284 #include <grub/lib/cmdline.h>
4285 #include <grub/linux.h>
4286 +#include <grub/safemath.h>
4288 GRUB_MOD_LICENSE ("GPLv3+");
4290 @@ -218,8 +219,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
4291 setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
4293 real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
4294 - grub_linux16_prot_size = grub_file_size (file)
4295 - - real_size - GRUB_DISK_SECTOR_SIZE;
4296 + if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) ||
4297 + grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size))
4299 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
4303 if (! grub_linux_is_bzimage
4304 && GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size
4305 diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
4306 index 8f662c8ac..cd24874ca 100644
4307 --- a/grub-core/loader/i386/xen.c
4308 +++ b/grub-core/loader/i386/xen.c
4310 #include <grub/linux.h>
4311 #include <grub/i386/memory.h>
4312 #include <grub/verify.h>
4313 +#include <grub/safemath.h>
4315 GRUB_MOD_LICENSE ("GPLv3+");
4317 @@ -636,6 +637,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
4318 grub_relocator_chunk_t ch;
4319 grub_addr_t kern_start;
4320 grub_addr_t kern_end;
4324 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
4325 @@ -703,8 +705,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
4327 xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE);
4329 - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start,
4330 - kern_end - kern_start);
4332 + if (grub_sub (kern_end, kern_start, &sz))
4334 + err = GRUB_ERR_OUT_OF_RANGE;
4338 + err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, sz);
4341 kern_chunk_src = get_virtual_current_address (ch);
4342 diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
4343 index 77d7060e1..9ae4ceb35 100644
4344 --- a/grub-core/loader/xnu.c
4345 +++ b/grub-core/loader/xnu.c
4347 #include <grub/env.h>
4348 #include <grub/i18n.h>
4349 #include <grub/verify.h>
4350 +#include <grub/safemath.h>
4352 GRUB_MOD_LICENSE ("GPLv3+");
4354 @@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
4357 grub_relocator_chunk_t ch;
4360 + if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt))
4361 + return GRUB_ERR_OUT_OF_RANGE;
4363 - err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
4364 - grub_xnu_heap_target_start
4365 - + grub_xnu_heap_size, size);
4366 + err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size);
4370 *src = get_virtual_current_address (ch);
4371 - *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
4373 grub_xnu_heap_size += size;
4374 grub_dprintf ("xnu", "val=%p\n", *src);
4375 return GRUB_ERR_NONE;
4377 From e39786ab462b1e4770fb35c736927286381ec47d Mon Sep 17 00:00:00 2001
4378 From: Alexey Makhalov <amakhalov@vmware.com>
4379 Date: Wed, 8 Jul 2020 01:44:38 +0000
4380 Subject: relocator: Protect grub_relocator_alloc_chunk_align()
4381 max_addr against integer underflow
4383 This commit introduces integer underflow mitigation in max_addr calculation
4384 in grub_relocator_alloc_chunk_align() invocation.
4386 It consists of 2 fixes:
4387 1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform
4388 sanity check for min/max and size values, and to make safe invocation of
4389 grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all
4390 invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...)
4391 by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...).
4392 2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top
4393 address (0xffffffff - size + 1) or similar.
4395 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
4396 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
4398 grub-core/lib/i386/relocator.c | 28 ++++++++++----------------
4399 grub-core/lib/mips/relocator.c | 6 ++----
4400 grub-core/lib/powerpc/relocator.c | 6 ++----
4401 grub-core/lib/x86_64/efi/relocator.c | 7 +++----
4402 grub-core/loader/i386/linux.c | 5 ++---
4403 grub-core/loader/i386/multiboot_mbi.c | 7 +++----
4404 grub-core/loader/i386/pc/linux.c | 6 ++----
4405 grub-core/loader/mips/linux.c | 9 +++------
4406 grub-core/loader/multiboot.c | 2 +-
4407 grub-core/loader/multiboot_elfxx.c | 10 ++++-----
4408 grub-core/loader/multiboot_mbi2.c | 10 ++++-----
4409 grub-core/loader/xnu_resume.c | 2 +-
4410 include/grub/relocator.h | 29 +++++++++++++++++++++++++++
4411 13 files changed, 69 insertions(+), 58 deletions(-)
4413 diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
4414 index 71dd4f0ab..34cbe834f 100644
4415 --- a/grub-core/lib/i386/relocator.c
4416 +++ b/grub-core/lib/i386/relocator.c
4417 @@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel,
4418 /* Specific memory range due to Global Descriptor Table for use by payload
4419 that we will store in returned chunk. The address range and preference
4420 are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */
4421 - err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000,
4422 - 0x9a000 - RELOCATOR_SIZEOF (32),
4423 - RELOCATOR_SIZEOF (32), 16,
4424 - GRUB_RELOCATOR_PREFERENCE_LOW,
4425 - avoid_efi_bootservices);
4426 + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000,
4427 + RELOCATOR_SIZEOF (32), 16,
4428 + GRUB_RELOCATOR_PREFERENCE_LOW,
4429 + avoid_efi_bootservices);
4433 @@ -125,13 +124,10 @@ grub_relocator16_boot (struct grub_relocator *rel,
4434 grub_relocator_chunk_t ch;
4436 /* Put it higher than the byte it checks for A20 check. */
4437 - err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
4438 - 0xa0000 - RELOCATOR_SIZEOF (16)
4439 - - GRUB_RELOCATOR16_STACK_SIZE,
4440 - RELOCATOR_SIZEOF (16)
4441 - + GRUB_RELOCATOR16_STACK_SIZE, 16,
4442 - GRUB_RELOCATOR_PREFERENCE_NONE,
4444 + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000,
4445 + RELOCATOR_SIZEOF (16) +
4446 + GRUB_RELOCATOR16_STACK_SIZE, 16,
4447 + GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4451 @@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel,
4453 grub_relocator_chunk_t ch;
4455 - err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
4456 - max_addr - RELOCATOR_SIZEOF (64),
4457 - RELOCATOR_SIZEOF (64), 16,
4458 - GRUB_RELOCATOR_PREFERENCE_NONE,
4460 + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr,
4461 + RELOCATOR_SIZEOF (64), 16,
4462 + GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4466 diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c
4467 index 9d5f49cb9..743b213e6 100644
4468 --- a/grub-core/lib/mips/relocator.c
4469 +++ b/grub-core/lib/mips/relocator.c
4470 @@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
4472 grub_addr_t vtarget;
4474 - err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
4475 - (0xffffffff - stateset_size)
4476 - + 1, stateset_size,
4477 - sizeof (grub_uint32_t),
4478 + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
4479 + stateset_size, sizeof (grub_uint32_t),
4480 GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4483 diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c
4484 index bdf2b111b..8ffb8b686 100644
4485 --- a/grub-core/lib/powerpc/relocator.c
4486 +++ b/grub-core/lib/powerpc/relocator.c
4487 @@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
4489 grub_relocator_chunk_t ch;
4491 - err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
4492 - (0xffffffff - stateset_size)
4493 - + 1, stateset_size,
4494 - sizeof (grub_uint32_t),
4495 + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
4496 + stateset_size, sizeof (grub_uint32_t),
4497 GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4500 diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c
4501 index 3caef7a40..7d200a125 100644
4502 --- a/grub-core/lib/x86_64/efi/relocator.c
4503 +++ b/grub-core/lib/x86_64/efi/relocator.c
4504 @@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel,
4505 * 64-bit relocator code may live above 4 GiB quite well.
4506 * However, I do not want ask for problems. Just in case.
4508 - err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
4509 - 0x100000000 - RELOCATOR_SIZEOF (64_efi),
4510 - RELOCATOR_SIZEOF (64_efi), 16,
4511 - GRUB_RELOCATOR_PREFERENCE_NONE, 1);
4512 + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000,
4513 + RELOCATOR_SIZEOF (64_efi), 16,
4514 + GRUB_RELOCATOR_PREFERENCE_NONE, 1);
4518 diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
4519 index 58d76fc0a..c98fbbb37 100644
4520 --- a/grub-core/loader/i386/linux.c
4521 +++ b/grub-core/loader/i386/linux.c
4522 @@ -183,9 +183,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
4523 for (; err && *align + 1 > min_align; (*align)--)
4525 grub_errno = GRUB_ERR_NONE;
4526 - err = grub_relocator_alloc_chunk_align (relocator, &ch,
4528 - 0xffffffff & ~prot_size,
4529 + err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
4530 + UP_TO_TOP32 (prot_size),
4531 prot_size, 1 << *align,
4532 GRUB_RELOCATOR_PREFERENCE_LOW,
4534 diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
4535 index ad3cc292f..a67d9d0a8 100644
4536 --- a/grub-core/loader/i386/multiboot_mbi.c
4537 +++ b/grub-core/loader/i386/multiboot_mbi.c
4538 @@ -466,10 +466,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
4540 bufsize = grub_multiboot_get_mbi_size ();
4542 - err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
4543 - 0x10000, 0xa0000 - bufsize,
4545 - GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4546 + err = grub_relocator_alloc_chunk_align_safe (grub_multiboot_relocator, &ch,
4547 + 0x10000, 0xa0000, bufsize, 4,
4548 + GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4551 ptrorig = get_virtual_current_address (ch);
4552 diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
4553 index 31f09922b..5fed5ffdf 100644
4554 --- a/grub-core/loader/i386/pc/linux.c
4555 +++ b/grub-core/loader/i386/pc/linux.c
4556 @@ -453,10 +453,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
4559 grub_relocator_chunk_t ch;
4560 - err = grub_relocator_alloc_chunk_align (relocator, &ch,
4561 - addr_min, addr_max - size,
4563 - GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
4564 + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size,
4565 + 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
4568 initrd_chunk = get_virtual_current_address (ch);
4569 diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
4570 index 7b723bf18..e4ed95921 100644
4571 --- a/grub-core/loader/mips/linux.c
4572 +++ b/grub-core/loader/mips/linux.c
4573 @@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
4575 grub_relocator_chunk_t ch;
4577 - err = grub_relocator_alloc_chunk_align (relocator, &ch,
4578 - (target_addr & 0x1fffffff)
4579 - + linux_size + 0x10000,
4580 - (0x10000000 - size),
4582 - GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4583 + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) +
4584 + linux_size + 0x10000, 0x10000000, size,
4585 + 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4589 diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
4590 index 4a98d7082..facb13f3d 100644
4591 --- a/grub-core/loader/multiboot.c
4592 +++ b/grub-core/loader/multiboot.c
4593 @@ -403,7 +403,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
4595 grub_relocator_chunk_t ch;
4596 err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
4597 - lowest_addr, (0xffffffff - size) + 1,
4598 + lowest_addr, UP_TO_TOP32 (size),
4599 size, MULTIBOOT_MOD_ALIGN,
4600 GRUB_RELOCATOR_PREFERENCE_NONE, 1);
4602 diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
4603 index cc6853692..f2318e0d1 100644
4604 --- a/grub-core/loader/multiboot_elfxx.c
4605 +++ b/grub-core/loader/multiboot_elfxx.c
4606 @@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
4607 if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
4608 return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
4610 - err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
4611 - mld->min_addr, mld->max_addr - load_size,
4612 - load_size, mld->align ? mld->align : 1,
4613 - mld->preference, mld->avoid_efi_boot_services);
4614 + err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch,
4615 + mld->min_addr, mld->max_addr,
4616 + load_size, mld->align ? mld->align : 1,
4617 + mld->preference, mld->avoid_efi_boot_services);
4621 @@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
4624 err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0,
4625 - (0xffffffff - sh->sh_size) + 1,
4626 + UP_TO_TOP32 (sh->sh_size),
4627 sh->sh_size, sh->sh_addralign,
4628 GRUB_RELOCATOR_PREFERENCE_NONE,
4629 mld->avoid_efi_boot_services);
4630 diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
4631 index 0efc66062..03967839c 100644
4632 --- a/grub-core/loader/multiboot_mbi2.c
4633 +++ b/grub-core/loader/multiboot_mbi2.c
4634 @@ -295,10 +295,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename)
4635 return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
4638 - err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
4639 - mld.min_addr, mld.max_addr - code_size,
4640 - code_size, mld.align ? mld.align : 1,
4641 - mld.preference, keep_bs);
4642 + err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch,
4643 + mld.min_addr, mld.max_addr,
4644 + code_size, mld.align ? mld.align : 1,
4645 + mld.preference, keep_bs);
4648 err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator,
4649 @@ -708,7 +708,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
4650 COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
4652 err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
4653 - 0, 0xffffffff - bufsize,
4654 + 0, UP_TO_TOP32 (bufsize),
4655 bufsize, MULTIBOOT_TAG_ALIGN,
4656 GRUB_RELOCATOR_PREFERENCE_NONE, 1);
4658 diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
4659 index 8089804d4..d648ef0cd 100644
4660 --- a/grub-core/loader/xnu_resume.c
4661 +++ b/grub-core/loader/xnu_resume.c
4662 @@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename)
4664 grub_relocator_chunk_t ch;
4665 err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
4666 - (0xffffffff - hibhead.image_size) + 1,
4667 + UP_TO_TOP32 (hibhead.image_size),
4670 GRUB_RELOCATOR_PREFERENCE_NONE, 0);
4671 diff --git a/include/grub/relocator.h b/include/grub/relocator.h
4672 index 24d8672d2..1b3bdd92a 100644
4673 --- a/include/grub/relocator.h
4674 +++ b/include/grub/relocator.h
4675 @@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
4677 int avoid_efi_boot_services);
4680 + * Wrapper for grub_relocator_alloc_chunk_align() with purpose of
4681 + * protecting against integer underflow.
4683 + * Compare to its callee, max_addr has different meaning here.
4684 + * It covers entire chunk and not just start address of the chunk.
4686 +static inline grub_err_t
4687 +grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel,
4688 + grub_relocator_chunk_t *out,
4689 + grub_phys_addr_t min_addr,
4690 + grub_phys_addr_t max_addr,
4691 + grub_size_t size, grub_size_t align,
4693 + int avoid_efi_boot_services)
4695 + /* Sanity check and ensure following equation (max_addr - size) is safe. */
4696 + if (max_addr < size || (max_addr - size) < min_addr)
4697 + return GRUB_ERR_OUT_OF_RANGE;
4699 + return grub_relocator_alloc_chunk_align (rel, out, min_addr,
4701 + size, align, preference,
4702 + avoid_efi_boot_services);
4705 +/* Top 32-bit address minus s bytes and plus 1 byte. */
4706 +#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1)
4708 #define GRUB_RELOCATOR_PREFERENCE_NONE 0
4709 #define GRUB_RELOCATOR_PREFERENCE_LOW 1
4710 #define GRUB_RELOCATOR_PREFERENCE_HIGH 2
4712 From 7855b7e78de5f257fa686ec569bda27472c4f5da Mon Sep 17 00:00:00 2001
4713 From: Chris Coulson <chris.coulson@canonical.com>
4714 Date: Fri, 10 Jul 2020 11:21:14 +0100
4715 Subject: script: Remove unused fields from grub_script_function
4718 Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
4719 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
4721 include/grub/script_sh.h | 5 -----
4722 1 file changed, 5 deletions(-)
4724 diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
4725 index 360c2be1f..b382bcf09 100644
4726 --- a/include/grub/script_sh.h
4727 +++ b/include/grub/script_sh.h
4728 @@ -359,13 +359,8 @@ struct grub_script_function
4729 /* The script function. */
4730 struct grub_script *func;
4735 /* The next element. */
4736 struct grub_script_function *next;
4740 typedef struct grub_script_function *grub_script_function_t;
4743 From fdc80d2460e5d3b54f5cde8657f9e171b0b9a376 Mon Sep 17 00:00:00 2001
4744 From: Chris Coulson <chris.coulson@canonical.com>
4745 Date: Fri, 10 Jul 2020 14:41:45 +0100
4746 Subject: script: Avoid a use-after-free when redefining a
4747 function during execution
4749 Defining a new function with the same name as a previously defined
4750 function causes the grub_script and associated resources for the
4751 previous function to be freed. If the previous function is currently
4752 executing when a function with the same name is defined, this results
4753 in use-after-frees when processing subsequent commands in the original
4756 Instead, reject a new function definition if it has the same name as
4757 a previously defined function, and that function is currently being
4758 executed. Although a behavioural change, this should be backwards
4759 compatible with existing configurations because they can't be
4760 dependent on the current behaviour without being broken.
4762 Fixes: CVE-2020-15706
4764 Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
4765 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
4767 grub-core/script/execute.c | 2 ++
4768 grub-core/script/function.c | 16 +++++++++++++---
4769 grub-core/script/parser.y | 3 ++-
4770 include/grub/script_sh.h | 2 ++
4771 4 files changed, 19 insertions(+), 4 deletions(-)
4773 diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
4774 index c8d6806fe..7e028e135 100644
4775 --- a/grub-core/script/execute.c
4776 +++ b/grub-core/script/execute.c
4777 @@ -838,7 +838,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
4781 + func->executing++;
4782 ret = grub_script_execute (func->func);
4783 + func->executing--;
4785 function_return = 0;
4786 active_loops = loops;
4787 diff --git a/grub-core/script/function.c b/grub-core/script/function.c
4788 index d36655e51..3aad04bf9 100644
4789 --- a/grub-core/script/function.c
4790 +++ b/grub-core/script/function.c
4791 @@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
4792 func = (grub_script_function_t) grub_malloc (sizeof (*func));
4795 + func->executing = 0;
4797 func->name = grub_strdup (functionname_arg->str);
4799 @@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg,
4800 grub_script_function_t q;
4803 - grub_script_free (q->func);
4807 + if (q->executing > 0)
4809 + grub_error (GRUB_ERR_BAD_ARGUMENT,
4810 + N_("attempt to redefine a function being executed"));
4815 + grub_script_free (q->func);
4822 diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y
4823 index 4f0ab8319..f80b86b6f 100644
4824 --- a/grub-core/script/parser.y
4825 +++ b/grub-core/script/parser.y
4826 @@ -289,7 +289,8 @@ function: "function" "name"
4827 grub_script_mem_free (state->func_mem);
4829 script->children = state->scripts;
4830 - grub_script_function_create ($2, script);
4831 + if (!grub_script_function_create ($2, script))
4832 + grub_script_free (script);
4835 state->scripts = $<scripts>3;
4836 diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
4837 index b382bcf09..6c48e0751 100644
4838 --- a/include/grub/script_sh.h
4839 +++ b/include/grub/script_sh.h
4840 @@ -361,6 +361,8 @@ struct grub_script_function
4842 /* The next element. */
4843 struct grub_script_function *next;
4845 + unsigned executing;
4847 typedef struct grub_script_function *grub_script_function_t;
4850 From dcc097ac0531485f0785816469370bfcb1a29f60 Mon Sep 17 00:00:00 2001
4851 From: Alexey Makhalov <amakhalov@vmware.com>
4852 Date: Fri, 17 Jul 2020 05:17:26 +0000
4853 Subject: relocator: Fix grub_relocator_alloc_chunk_align() top
4856 Current implementation of grub_relocator_alloc_chunk_align()
4857 does not allow allocation of the top byte.
4859 Assuming input args are:
4860 max_addr = 0xfffff000;
4863 And this is valid. But following overflow protection will
4864 unnecessarily move max_addr one byte down (to 0xffffefff):
4865 if (max_addr > ~size)
4868 ~size + 1 will fix the situation. In addition, check size
4869 for non zero to do not zero max_addr.
4871 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
4872 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
4874 grub-core/lib/relocator.c | 4 ++--
4875 1 file changed, 2 insertions(+), 2 deletions(-)
4877 diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
4878 index 5847aac36..f2c1944c2 100644
4879 --- a/grub-core/lib/relocator.c
4880 +++ b/grub-core/lib/relocator.c
4881 @@ -1386,8 +1386,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
4883 grub_addr_t min_addr2 = 0, max_addr2;
4885 - if (max_addr > ~size)
4887 + if (size && (max_addr > ~size))
4888 + max_addr = ~size + 1;
4890 #ifdef GRUB_MACHINE_PCBIOS
4891 if (min_addr < 0x1000)
4893 From 2db482b906c425aa755fc78e8e8980659b92f5a1 Mon Sep 17 00:00:00 2001
4894 From: Peter Jones <pjones@redhat.com>
4895 Date: Sun, 19 Jul 2020 14:43:31 -0400
4896 Subject: hfsplus: fix two more overflows
4898 Both node->size and node->namelen come from the supplied filesystem,
4899 which may be user-supplied. We can't trust them for the math unless we
4900 know they don't overflow; making sure they go through calloc() first
4903 Signed-off-by: Peter Jones <pjones@redhat.com>
4904 Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
4906 grub-core/fs/hfsplus.c | 11 ++++++++---
4907 1 file changed, 8 insertions(+), 3 deletions(-)
4909 diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
4910 index dae43becc..9c4e4c88c 100644
4911 --- a/grub-core/fs/hfsplus.c
4912 +++ b/grub-core/fs/hfsplus.c
4914 #include <grub/hfs.h>
4915 #include <grub/charset.h>
4916 #include <grub/hfsplus.h>
4917 +#include <grub/safemath.h>
4919 GRUB_MOD_LICENSE ("GPLv3+");
4921 @@ -475,8 +476,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
4924 grub_ssize_t numread;
4925 + grub_size_t sz = node->size;
4927 - symlink = grub_malloc (node->size + 1);
4928 + if (grub_add (sz, 1, &sz))
4931 + symlink = grub_malloc (sz);
4935 @@ -715,8 +720,8 @@ list_nodes (void *record, void *hook_arg)
4936 if (type == GRUB_FSHELP_UNKNOWN)
4939 - filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
4940 - * GRUB_MAX_UTF8_PER_UTF16 + 1);
4941 + filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen),
4942 + GRUB_MAX_UTF8_PER_UTF16 + 1);
4947 From fc669c03dbffd20667f40a2375c30ef91cdc2707 Mon Sep 17 00:00:00 2001
4948 From: Peter Jones <pjones@redhat.com>
4949 Date: Sun, 19 Jul 2020 15:48:20 -0400
4950 Subject: lvm: fix two more potential data-dependent alloc
4953 It appears to be possible to make a (possibly invalid) lvm PV with a
4954 metadata size field that overflows our type when adding it to the
4955 address we've allocated. Even if it doesn't, it may be possible to do
4956 so with the math using the outcome of that as an operand. Check them
4959 Signed-off-by: Peter Jones <pjones@redhat.com>
4960 Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
4962 grub-core/disk/lvm.c | 47 ++++++++++++++++++++++++++++++++++++--------
4963 1 file changed, 39 insertions(+), 8 deletions(-)
4965 diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
4966 index d1df640b3..e1299a348 100644
4967 --- a/grub-core/disk/lvm.c
4968 +++ b/grub-core/disk/lvm.c
4970 #include <grub/lvm.h>
4971 #include <grub/partition.h>
4972 #include <grub/i18n.h>
4973 +#include <grub/safemath.h>
4976 #include <grub/emu/misc.h>
4977 @@ -102,10 +103,11 @@ grub_lvm_detect (grub_disk_t disk,
4980 grub_uint64_t mda_offset, mda_size;
4982 char buf[GRUB_LVM_LABEL_SIZE];
4983 char vg_id[GRUB_LVM_ID_STRLEN+1];
4984 char pv_id[GRUB_LVM_ID_STRLEN+1];
4985 - char *metadatabuf, *p, *q, *vgname;
4986 + char *metadatabuf, *p, *q, *mda_end, *vgname;
4987 struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
4988 struct grub_lvm_pv_header *pvh;
4989 struct grub_lvm_disk_locn *dlocn;
4990 @@ -205,19 +207,31 @@ grub_lvm_detect (grub_disk_t disk,
4991 grub_le_to_cpu64 (rlocn->size) -
4992 grub_le_to_cpu64 (mdah->size));
4994 - p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
4996 - while (*q != ' ' && q < metadatabuf + mda_size)
4999 - if (q == metadatabuf + mda_size)
5000 + if (grub_add ((grub_size_t)metadatabuf,
5001 + (grub_size_t)grub_le_to_cpu64 (rlocn->offset),
5004 +error_parsing_metadata:
5006 grub_util_info ("error parsing metadata");
5011 + p = q = (char *)ptr;
5013 + if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
5014 + goto error_parsing_metadata;
5016 + mda_end = (char *)ptr;
5018 + while (*q != ' ' && q < mda_end)
5022 + goto error_parsing_metadata;
5025 vgname = grub_malloc (vgname_len + 1);
5027 @@ -367,8 +381,25 @@ grub_lvm_detect (grub_disk_t disk,
5031 - lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
5034 + /* this is kind of hard to read with our safe (but rather
5035 + * baroque) math primatives, but it boils down to:
5037 + * sz0 = vgname_len * 2 + 1
5039 + * + sizeof ("lvm/") - 1;
5041 + grub_size_t sz0 = vgname_len, sz1 = s;
5043 + if (grub_mul (sz0, 2, &sz0) ||
5044 + grub_add (sz0, 1, &sz0) ||
5045 + grub_mul (sz1, 2, &sz1) ||
5046 + grub_add (sz1, 1, &sz1) ||
5047 + grub_add (sz0, sz1, &sz0) ||
5048 + grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
5051 + lv->fullname = grub_malloc (sz0);
5056 From c0a2098a2d47a752f9416a655a7010973298f66f Mon Sep 17 00:00:00 2001
5057 From: Peter Jones <pjones@redhat.com>
5058 Date: Sun, 19 Jul 2020 16:08:08 -0400
5059 Subject: emu: make grub_free(NULL) safe
5061 The grub_free() implementation in kern/mm.c safely handles NULL
5062 pointers, and code at many places depends on this. We don't know that
5063 the same is true on all host OSes, so we need to handle the same
5064 behavior in grub-emu's implementation.
5066 Signed-off-by: Peter Jones <pjones@redhat.com>
5067 Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
5069 grub-core/kern/emu/mm.c | 3 ++-
5070 1 file changed, 2 insertions(+), 1 deletion(-)
5072 diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
5073 index 145b01d37..4d1046a21 100644
5074 --- a/grub-core/kern/emu/mm.c
5075 +++ b/grub-core/kern/emu/mm.c
5076 @@ -60,7 +60,8 @@ grub_zalloc (grub_size_t size)
5078 grub_free (void *ptr)
5087 From 9735a4b2f52caf79e5804ca3e959f0f444a8716c Mon Sep 17 00:00:00 2001
5088 From: Peter Jones <pjones@redhat.com>
5089 Date: Sun, 19 Jul 2020 16:53:27 -0400
5090 Subject: efi: fix some malformed device path arithmetic errors.
5092 Several places we take the length of a device path and subtract 4 from
5093 it, without ever checking that it's >= 4. There are also cases where
5094 this kind of malformation will result in unpredictable iteration,
5095 including treating the length from one dp node as the type in the next
5096 node. These are all errors, no matter where the data comes from.
5098 This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
5099 can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
5100 return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
5101 the length is too small. Additionally, it makes several places in the
5102 code check for and return errors in these cases.
5104 Signed-off-by: Peter Jones <pjones@redhat.com>
5106 grub-core/kern/efi/efi.c | 67 +++++++++++++++++++++++++-----
5107 grub-core/loader/efi/chainloader.c | 19 ++++++++-
5108 grub-core/loader/i386/xnu.c | 9 ++--
5109 include/grub/efi/api.h | 14 ++++---
5110 4 files changed, 88 insertions(+), 21 deletions(-)
5112 diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
5113 index ad170c7ce..e12261fd5 100644
5114 --- a/grub-core/kern/efi/efi.c
5115 +++ b/grub-core/kern/efi/efi.c
5116 @@ -360,7 +360,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
5123 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
5124 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
5125 @@ -370,9 +370,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
5126 if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
5127 && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
5129 - grub_efi_uint16_t len;
5130 - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
5131 - / sizeof (grub_efi_char16_t));
5132 + grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
5136 + grub_error (GRUB_ERR_OUT_OF_RANGE,
5137 + "malformed EFI Device Path node has length=%d", len);
5140 + len = (len - 4) / sizeof (grub_efi_char16_t);
5141 filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
5144 @@ -388,7 +394,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
5151 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
5152 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
5153 @@ -404,8 +410,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
5157 - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
5158 - / sizeof (grub_efi_char16_t));
5159 + len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
5162 + grub_error (GRUB_ERR_OUT_OF_RANGE,
5163 + "malformed EFI Device Path node has length=%d", len);
5167 + len = (len - 4) / sizeof (grub_efi_char16_t);
5168 fp = (grub_efi_file_path_device_path_t *) dp;
5169 /* According to EFI spec Path Name is NULL terminated */
5170 while (len > 0 && fp->path_name[len - 1] == 0)
5171 @@ -480,7 +493,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
5173 p = GRUB_EFI_NEXT_DEVICE_PATH (p))
5175 - total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
5176 + grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p);
5179 + * In the event that we find a node that's completely garbage, for
5180 + * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size
5181 + * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and
5182 + * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue,
5183 + * and neither should our consumers, but there won't be any error raised
5184 + * even though the device path is junk.
5186 + * This keeps us from passing junk down back to our caller.
5190 + grub_error (GRUB_ERR_OUT_OF_RANGE,
5191 + "malformed EFI Device Path node has length=%d", len);
5195 + total_size += len;
5196 if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
5199 @@ -525,7 +557,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
5201 grub_efi_print_device_path (grub_efi_device_path_t *dp)
5204 + while (GRUB_EFI_DEVICE_PATH_VALID (dp))
5206 grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
5207 grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
5208 @@ -937,7 +969,11 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
5209 /* Return non-zero. */
5216 + while (GRUB_EFI_DEVICE_PATH_VALID (dp1)
5217 + && GRUB_EFI_DEVICE_PATH_VALID (dp2))
5219 grub_efi_uint8_t type1, type2;
5220 grub_efi_uint8_t subtype1, subtype2;
5221 @@ -973,5 +1009,16 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
5222 dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
5226 + * There's no "right" answer here, but we probably don't want to call a valid
5227 + * dp and an invalid dp equal, so pick one way or the other.
5229 + if (GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
5230 + !GRUB_EFI_DEVICE_PATH_VALID (dp2))
5232 + else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
5233 + GRUB_EFI_DEVICE_PATH_VALID (dp2))
5238 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
5239 index daf8c6b54..978fab002 100644
5240 --- a/grub-core/loader/efi/chainloader.c
5241 +++ b/grub-core/loader/efi/chainloader.c
5242 @@ -116,6 +116,12 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
5243 fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
5244 fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
5246 + if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
5248 + grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
5252 path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
5255 @@ -156,9 +162,18 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
5262 - size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
5263 + grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (d);
5267 + grub_error (GRUB_ERR_OUT_OF_RANGE,
5268 + "malformed EFI Device Path node has length=%d", len);
5273 if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
5275 d = GRUB_EFI_NEXT_DEVICE_PATH (d);
5276 diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
5277 index e9e119259..a70093607 100644
5278 --- a/grub-core/loader/i386/xnu.c
5279 +++ b/grub-core/loader/i386/xnu.c
5280 @@ -515,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
5285 + dp = dpstart = buf;
5288 + while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend)
5291 buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
5292 + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
5296 - while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
5298 dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
5299 - (char *) dpstart);
5300 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
5301 index 75befd10e..a3f4df91d 100644
5302 --- a/include/grub/efi/api.h
5303 +++ b/include/grub/efi/api.h
5304 @@ -635,6 +635,7 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
5305 #define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
5306 #define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
5307 #define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
5308 +#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4)
5310 /* The End of Device Path nodes. */
5311 #define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
5312 @@ -643,13 +644,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
5313 #define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
5315 #define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
5316 - (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
5317 - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
5318 - == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
5319 + (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \
5320 + (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
5321 + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
5322 + == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)))
5324 #define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
5325 - ((grub_efi_device_path_t *) ((char *) (dp) \
5326 - + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
5327 + (GRUB_EFI_DEVICE_PATH_VALID (dp) \
5328 + ? ((grub_efi_device_path_t *) \
5329 + ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \
5332 /* Hardware Device Path. */
5333 #define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
5335 From c5763039a630dee079f0afbd5ced9cd74efe0b71 Mon Sep 17 00:00:00 2001
5336 From: Chris Coulson <chris.coulson@canonical.com>
5337 Date: Wed, 22 Jul 2020 17:06:04 +0100
5338 Subject: Fix a regression caused by "efi: fix some malformed
5339 device path arithmetic errors"
5341 This commit introduced a bogus check inside copy_file_path to
5342 determine whether the destination grub_efi_file_path_device_path_t
5343 was valid before anything was copied to it. Depending on the
5344 contents of the heap buffer, this check could fail which would
5345 result in copy_file_path returning early.
5347 Without any error propagated to the caller, make_file_path would
5348 then try to advance the invalid device path node with
5349 GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL
5350 pointer that would subsequently be dereferenced.
5352 Remove the bogus check, and also propagate errors from copy_file_path.
5354 grub-core/loader/efi/chainloader.c | 25 +++++++++++++------------
5355 1 file changed, 13 insertions(+), 12 deletions(-)
5357 diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
5358 index 978fab002..e9b06242a 100644
5359 --- a/grub-core/loader/efi/chainloader.c
5360 +++ b/grub-core/loader/efi/chainloader.c
5361 @@ -106,7 +106,7 @@ grub_chainloader_boot (void)
5367 copy_file_path (grub_efi_file_path_device_path_t *fp,
5368 const char *str, grub_efi_uint16_t len)
5370 @@ -116,15 +116,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
5371 fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
5372 fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
5374 - if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
5376 - grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
5380 path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
5383 + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
5385 size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
5386 (const grub_uint8_t *) str, len, 0);
5387 @@ -137,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
5388 fp->path_name[size++] = '\0';
5389 fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
5390 grub_free (path_name);
5391 + return GRUB_ERR_NONE;
5394 static grub_efi_device_path_t *
5395 @@ -195,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
5396 d = (grub_efi_device_path_t *) ((char *) file_path
5397 + ((char *) d - (char *) dp));
5398 grub_efi_print_device_path (d);
5399 - copy_file_path ((grub_efi_file_path_device_path_t *) d,
5400 - dir_start, dir_end - dir_start);
5401 + if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
5402 + dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
5405 + grub_free (file_path);
5409 /* Fill the file path for the file. */
5410 d = GRUB_EFI_NEXT_DEVICE_PATH (d);
5411 - copy_file_path ((grub_efi_file_path_device_path_t *) d,
5412 - dir_end + 1, grub_strlen (dir_end + 1));
5413 + if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
5414 + dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
5417 /* Fill the end of device path nodes. */
5418 d = GRUB_EFI_NEXT_DEVICE_PATH (d);
5420 From 3e6aa687d9a2f8d172536a67d0d0f8bc7adb3108 Mon Sep 17 00:00:00 2001
5421 From: Alexander Burmashev <alexander.burmashev@oracle.com>
5422 Date: Wed, 22 Jul 2020 06:04:38 -0700
5423 Subject: update safemath with fallback code for gcc older than
5426 The code used in the header was taken from linux kernel commit
5427 f0907827a8a9152aedac2833ed1b674a7b2a44f2. Rasmus Villemoes
5428 <linux@rasmusvillemoes.dk>, the original author of the patch, was
5429 contacted directly, confirmed his authorship of the code, and gave his
5430 permission on treating that dual license as MIT and including into GRUB2
5433 Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com>
5435 include/grub/safemath.h | 119 +++++++++++++++++++++++++++++++++++++++-
5436 1 file changed, 118 insertions(+), 1 deletion(-)
5438 diff --git a/include/grub/safemath.h b/include/grub/safemath.h
5439 index c17b89bba..1ccac276b 100644
5440 --- a/include/grub/safemath.h
5441 +++ b/include/grub/safemath.h
5443 #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
5446 -#error gcc 5.1 or newer or clang 3.8 or newer is required
5448 + * Copyright 2020 Rasmus Villemoes
5450 + * Permission is hereby granted, free of charge, to any person obtaining a copy
5451 + * of this software and associated documentation files (the "Software"), to
5452 + * deal in the Software without restriction, including without limitation the
5453 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
5454 + * sell copies of the Software, and to permit persons to whom the Software is
5455 + * furnished to do so, subject to the following conditions:
5457 + * The above copyright notice and this permission notice shall be included in
5458 + * all copies or substantial portions of the Software.
5460 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5461 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5462 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5463 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5464 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
5465 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
5466 + * IN THE SOFTWARE.
5469 + * The code used in this header was taken from linux kernel commit
5470 + * f0907827a8a9152aedac2833ed1b674a7b2a44f2
5471 + * Rasmus Villemoes <linux@rasmusvillemoes.dk>, the original author of the
5472 + * patch, was contacted directly, confirmed his authorship of the code, and
5473 + * gave his permission on treating that dual license as MIT and including into
5477 +#include <grub/types.h>
5478 +#define is_signed_type(type) (((type)(-1)) < (type)1)
5479 +#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
5480 +#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
5481 +#define type_min(T) ((T)((T)-type_max(T)-(T)1))
5483 +#define __unsigned_add_overflow(a, b, d) ({ \
5484 + typeof(+(a)) __a = (a); \
5485 + typeof(+(b)) __b = (b); \
5486 + typeof(d) __d = (d); \
5487 + (void) (&__a == &__b); \
5488 + (void) (&__a == __d); \
5489 + *__d = __a + __b; \
5492 +#define __unsigned_sub_overflow(a, b, d) ({ \
5493 + typeof(+(a)) __a = (a); \
5494 + typeof(+(b)) __b = (b); \
5495 + typeof(d) __d = (d); \
5496 + (void) (&__a == &__b); \
5497 + (void) (&__a == __d); \
5498 + *__d = __a - __b; \
5501 +#define __unsigned_mul_overflow(a, b, d) ({ \
5502 + typeof(+(a)) __a = (a); \
5503 + typeof(+(b)) __b = (b); \
5504 + typeof(d) __d = (d); \
5505 + (void) (&__a == &__b); \
5506 + (void) (&__a == __d); \
5507 + *__d = __a * __b; \
5508 + __builtin_constant_p(__b) ? \
5509 + __b > 0 && __a > type_max(typeof(__a)) / __b :\
5510 + __a > 0 && __b > type_max(typeof(__b)) / __a; \
5513 +#define __signed_add_overflow(a, b, d) ({ \
5514 + typeof(+(a)) __a = (a); \
5515 + typeof(+(b)) __b = (b); \
5516 + typeof(d) __d = (d); \
5517 + (void) (&__a == &__b); \
5518 + (void) (&__a == __d); \
5519 + *__d = (grub_uint64_t)__a + (grub_uint64_t)__b; \
5520 + (((~(__a ^ __b)) & (*__d ^ __a)) \
5521 + & type_min(typeof(__a))) != 0; \
5524 +#define __signed_sub_overflow(a, b, d) ({ \
5525 + typeof(+(a)) __a = (a); \
5526 + typeof(+(b)) __b = (b); \
5527 + typeof(d) __d = (d); \
5528 + (void) (&__a == &__b); \
5529 + (void) (&__a == __d); \
5530 + *__d = (grub_uint64_t)__a - (grub_uint64_t)__b; \
5531 + ((((__a ^ __b)) & (*__d ^ __a)) \
5532 + & type_min(typeof(__a))) != 0; \
5535 +#define __signed_mul_overflow(a, b, d) ({ \
5536 + typeof(+(a)) __a = (a); \
5537 + typeof(+(b)) __b = (b); \
5538 + typeof(d) __d = (d); \
5539 + typeof(+(a)) __tmax = type_max(typeof(+(a))); \
5540 + typeof(+(a)) __tmin = type_min(typeof(+(a))); \
5541 + (void) (&__a == &__b); \
5542 + (void) (&__a == __d); \
5543 + *__d = (grub_uint64_t)__a * (grub_uint64_t)__b; \
5544 + (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) ||\
5545 + (__b < (typeof(__b))-1 && \
5546 + (__a > __tmin/__b || __a < __tmax/__b)) || \
5547 + (__b == (typeof(__b))-1 && __a == __tmin); \
5550 +#define grub_add(a, b, d) \
5551 + __builtin_choose_expr(is_signed_type(typeof(+(a))), \
5552 + __signed_add_overflow(a, b, d), \
5553 + __unsigned_add_overflow(a, b, d))
5555 +#define grub_sub(a, b, d) \
5556 + __builtin_choose_expr(is_signed_type(typeof(+(a))), \
5557 + __signed_sub_overflow(a, b, d), \
5558 + __unsigned_sub_overflow(a, b, d))
5560 +#define grub_mul(a, b, d) \
5561 + __builtin_choose_expr(is_signed_type(typeof(+(a))), \
5562 + __signed_mul_overflow(a, b, d), \
5563 + __unsigned_mul_overflow(a, b, d))
5567 #endif /* GRUB_SAFEMATH_H */
5569 From bb5fc65035e82509b0565bfe2994fbe6cc11016e Mon Sep 17 00:00:00 2001
5570 From: Alexey Makhalov <amakhalov@vmware.com>
5571 Date: Mon, 20 Jul 2020 23:03:05 +0000
5572 Subject: efi: Fix use-after-free in halt/reboot path
5574 commit 92bfc33db984 ("efi: Free malloc regions on exit")
5575 introduced memory freeing in grub_efi_fini(), which is
5576 used not only by exit path but by halt/reboot one as well.
5577 As result of memory freeing, code and data regions used by
5578 modules, such as halt, reboot, acpi (used by halt) also got
5579 freed. After return to module code, CPU executes, filled
5580 by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
5581 a code. Which leads to #UD exception later.
5584 !!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
5585 RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
5586 RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
5587 RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
5588 RSI - 00000000064DB768, RDI - 000000000832C5C3
5589 R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
5590 R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
5591 R14 - 0000000003E10D80, R15 - 00000000061E2F60
5592 DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
5593 GS - 0000000000000030, SS - 0000000000000030
5594 CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
5595 CR4 - 0000000000000668, CR8 - 0000000000000000
5596 DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
5597 DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
5598 GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
5599 IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
5600 FXSAVE_STATE - 0000000007F0F4C0
5602 Proposal here is to continue to free allocated memory for
5603 exit boot services path but keep it for halt/reboot path
5604 as it won't be much security concern here.
5605 Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
5606 loader flag to be used by efi halt/reboot path.
5608 Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
5609 Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
5611 grub-core/kern/arm/efi/init.c | 3 +++
5612 grub-core/kern/arm64/efi/init.c | 3 +++
5613 grub-core/kern/efi/efi.c | 3 ++-
5614 grub-core/kern/efi/init.c | 1 -
5615 grub-core/kern/i386/efi/init.c | 9 +++++++--
5616 grub-core/kern/ia64/efi/init.c | 9 +++++++--
5617 grub-core/kern/riscv/efi/init.c | 3 +++
5618 grub-core/lib/efi/halt.c | 3 ++-
5619 include/grub/loader.h | 1 +
5620 9 files changed, 28 insertions(+), 7 deletions(-)
5622 diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
5623 index 06df60e2f..40c3b467f 100644
5624 --- a/grub-core/kern/arm/efi/init.c
5625 +++ b/grub-core/kern/arm/efi/init.c
5626 @@ -71,4 +71,7 @@ grub_machine_fini (int flags)
5627 efi_call_1 (b->close_event, tmr_evt);
5631 + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
5632 + grub_efi_memory_fini ();
5634 diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c
5635 index 6224999ec..5010caefd 100644
5636 --- a/grub-core/kern/arm64/efi/init.c
5637 +++ b/grub-core/kern/arm64/efi/init.c
5638 @@ -57,4 +57,7 @@ grub_machine_fini (int flags)
5643 + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
5644 + grub_efi_memory_fini ();
5646 diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
5647 index e12261fd5..acb38d61f 100644
5648 --- a/grub-core/kern/efi/efi.c
5649 +++ b/grub-core/kern/efi/efi.c
5650 @@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
5654 - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
5655 + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
5656 + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
5657 efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
5658 GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
5660 diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
5661 index 3dfdf2d22..2c31847bf 100644
5662 --- a/grub-core/kern/efi/init.c
5663 +++ b/grub-core/kern/efi/init.c
5664 @@ -80,5 +80,4 @@ grub_efi_fini (void)
5666 grub_efidisk_fini ();
5667 grub_console_fini ();
5668 - grub_efi_memory_fini ();
5670 diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
5671 index da499aba0..deb2eacd8 100644
5672 --- a/grub-core/kern/i386/efi/init.c
5673 +++ b/grub-core/kern/i386/efi/init.c
5674 @@ -39,6 +39,11 @@ grub_machine_init (void)
5676 grub_machine_fini (int flags)
5678 - if (flags & GRUB_LOADER_FLAG_NORETURN)
5680 + if (!(flags & GRUB_LOADER_FLAG_NORETURN))
5685 + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
5686 + grub_efi_memory_fini ();
5688 diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c
5689 index b5ecbd091..f1965571b 100644
5690 --- a/grub-core/kern/ia64/efi/init.c
5691 +++ b/grub-core/kern/ia64/efi/init.c
5692 @@ -70,6 +70,11 @@ grub_machine_init (void)
5694 grub_machine_fini (int flags)
5696 - if (flags & GRUB_LOADER_FLAG_NORETURN)
5698 + if (!(flags & GRUB_LOADER_FLAG_NORETURN))
5703 + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
5704 + grub_efi_memory_fini ();
5706 diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
5707 index 7eb1969d0..38795fe67 100644
5708 --- a/grub-core/kern/riscv/efi/init.c
5709 +++ b/grub-core/kern/riscv/efi/init.c
5710 @@ -73,4 +73,7 @@ grub_machine_fini (int flags)
5715 + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
5716 + grub_efi_memory_fini ();
5718 diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
5719 index 5859f0498..29d413641 100644
5720 --- a/grub-core/lib/efi/halt.c
5721 +++ b/grub-core/lib/efi/halt.c
5726 - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
5727 + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
5728 + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
5729 #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \
5732 diff --git a/include/grub/loader.h b/include/grub/loader.h
5733 index 7f82a499f..b20864282 100644
5734 --- a/include/grub/loader.h
5735 +++ b/include/grub/loader.h
5736 @@ -33,6 +33,7 @@ enum
5738 GRUB_LOADER_FLAG_NORETURN = 1,
5739 GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2,
5740 + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4,
5743 void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
5745 From 6d438b80c4cfe75a67f619918706630ccc2252b6 Mon Sep 17 00:00:00 2001
5746 From: Peter Jones <pjones@redhat.com>
5747 Date: Fri, 24 Jul 2020 13:57:27 -0400
5748 Subject: linux loader: avoid overflow on initrd size calculation
5750 Signed-off-by: Peter Jones <pjones@redhat.com>
5752 grub-core/loader/linux.c | 4 ++--
5753 1 file changed, 2 insertions(+), 2 deletions(-)
5755 diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
5756 index 471b214d6..25624ebc1 100644
5757 --- a/grub-core/loader/linux.c
5758 +++ b/grub-core/loader/linux.c
5759 @@ -151,8 +151,8 @@ grub_initrd_init (int argc, char *argv[],
5760 initrd_ctx->nfiles = 0;
5761 initrd_ctx->components = 0;
5763 - initrd_ctx->components = grub_zalloc (argc
5764 - * sizeof (initrd_ctx->components[0]));
5765 + initrd_ctx->components = grub_calloc (argc,
5766 + sizeof (initrd_ctx->components[0]));
5767 if (!initrd_ctx->components)
5771 From 81fae35a346bef8f7b27ba8d186a18ae21281755 Mon Sep 17 00:00:00 2001
5772 From: Colin Watson <cjwatson@debian.org>
5773 Date: Sat, 25 Jul 2020 12:15:37 +0100
5774 Subject: linux: Fix integer overflows in initrd size handling
5776 These could be triggered by a crafted filesystem with very large files.
5778 Fixes: CVE-2020-15707
5780 Signed-off-by: Colin Watson <cjwatson@debian.org>
5781 Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
5783 grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++-----------
5784 1 file changed, 54 insertions(+), 20 deletions(-)
5786 diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
5787 index 25624ebc1..e9f819ee9 100644
5788 --- a/grub-core/loader/linux.c
5789 +++ b/grub-core/loader/linux.c
5791 #include <grub/misc.h>
5792 #include <grub/file.h>
5793 #include <grub/mm.h>
5794 +#include <grub/safemath.h>
5798 @@ -98,13 +99,13 @@ free_dir (struct dir *root)
5804 insert_dir (const char *name, struct dir **root,
5805 - grub_uint8_t *ptr)
5806 + grub_uint8_t *ptr, grub_size_t *size)
5808 struct dir *cur, **head = root;
5809 const char *cb, *ce = name;
5810 - grub_size_t size = 0;
5814 for (cb = ce; *cb == '/'; cb++);
5815 @@ -130,14 +131,22 @@ insert_dir (const char *name, struct dir **root,
5816 ptr = make_header (ptr, name, ce - name,
5819 - size += ALIGN_UP ((ce - (char *) name)
5820 - + sizeof (struct newc_head), 4);
5821 + if (grub_add (*size,
5822 + ALIGN_UP ((ce - (char *) name)
5823 + + sizeof (struct newc_head), 4),
5826 + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
5827 + grub_free (n->name);
5829 + return grub_errno;
5837 + return GRUB_ERR_NONE;
5841 @@ -173,26 +182,33 @@ grub_initrd_init (int argc, char *argv[],
5842 eptr = grub_strchr (ptr, ':');
5845 + grub_size_t dir_size, name_len;
5847 initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
5848 - if (!initrd_ctx->components[i].newc_name)
5849 + if (!initrd_ctx->components[i].newc_name ||
5850 + insert_dir (initrd_ctx->components[i].newc_name, &root, 0,
5853 grub_initrd_close (initrd_ctx);
5857 - += ALIGN_UP (sizeof (struct newc_head)
5858 - + grub_strlen (initrd_ctx->components[i].newc_name),
5860 - initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
5862 + name_len = grub_strlen (initrd_ctx->components[i].newc_name);
5863 + if (grub_add (initrd_ctx->size,
5864 + ALIGN_UP (sizeof (struct newc_head) + name_len, 4),
5865 + &initrd_ctx->size) ||
5866 + grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size))
5874 - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
5875 - + sizeof ("TRAILER!!!") - 1, 4);
5876 + if (grub_add (initrd_ctx->size,
5877 + ALIGN_UP (sizeof (struct newc_head)
5878 + + sizeof ("TRAILER!!!") - 1, 4),
5879 + &initrd_ctx->size))
5884 @@ -208,19 +224,29 @@ grub_initrd_init (int argc, char *argv[],
5885 initrd_ctx->nfiles++;
5886 initrd_ctx->components[i].size
5887 = grub_file_size (initrd_ctx->components[i].file);
5888 - initrd_ctx->size += initrd_ctx->components[i].size;
5889 + if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size,
5890 + &initrd_ctx->size))
5896 initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
5897 - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
5898 - + sizeof ("TRAILER!!!") - 1, 4);
5899 + if (grub_add (initrd_ctx->size,
5900 + ALIGN_UP (sizeof (struct newc_head)
5901 + + sizeof ("TRAILER!!!") - 1, 4),
5902 + &initrd_ctx->size))
5908 return GRUB_ERR_NONE;
5912 + grub_initrd_close (initrd_ctx);
5913 + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
5917 @@ -261,8 +287,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
5919 if (initrd_ctx->components[i].newc_name)
5921 - ptr += insert_dir (initrd_ctx->components[i].newc_name,
5923 + grub_size_t dir_size;
5925 + if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr,
5929 + grub_initrd_close (initrd_ctx);
5930 + return grub_errno;
5933 ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
5934 grub_strlen (initrd_ctx->components[i].newc_name),