From 16be6529beb0c53199f9c724ce21769d2919a2a3b4b6cbfef5608420012686fc Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Fri, 31 Jul 2020 13:54:21 +0000 Subject: [PATCH] Accepting request 823470 from Base:System OBS-URL: https://build.opensuse.org/request/show/823470 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=223 --- ...d-support-for-UEFI-network-protocols.patch | 143 +- ...lexer-fatal-errors-actually-be-fatal.patch | 67 + ...e-arithmetic-primitives-that-check-f.patch | 123 ++ 0003-bootp-New-net_bootp6-command.patch | 25 +- ...-we-always-have-an-overflow-checking.patch | 239 +++ 0004-calloc-Use-calloc-at-most-places.patch | 1825 +++++++++++++++++ ...low-checking-primitives-where-we-do-.patch | 1319 ++++++++++++ ...on-t-leak-memory-on-realloc-failures.patch | 67 + ...-not-load-more-than-one-NAME-section.patch | 35 + ...used-fields-from-grub_script_functio.patch | 33 + ...se-after-free-when-redefining-a-func.patch | 107 + ...er-overflows-in-initrd-size-handling.patch | 164 ++ ...-add-ability-to-boot-from-subvolumes.patch | 52 +- grub2-btrfs-09-get-default-subvolume.patch | 33 +- ...-support-scrolling-menu-entry-s-text.patch | 94 +- grub2-grubenv-in-btrfs-header.patch | 33 +- grub2.changes | 28 + grub2.spec | 28 + 18 files changed, 4272 insertions(+), 143 deletions(-) create mode 100644 0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch create mode 100644 0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch create mode 100644 0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch create mode 100644 0004-calloc-Use-calloc-at-most-places.patch create mode 100644 0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch create mode 100644 0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch create mode 100644 0007-font-Do-not-load-more-than-one-NAME-section.patch create mode 100644 0008-script-Remove-unused-fields-from-grub_script_functio.patch create mode 100644 0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch create mode 100644 0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch diff --git a/0001-add-support-for-UEFI-network-protocols.patch b/0001-add-support-for-UEFI-network-protocols.patch index 7e3344a..546333e 100644 --- a/0001-add-support-for-UEFI-network-protocols.patch +++ b/0001-add-support-for-UEFI-network-protocols.patch @@ -23,10 +23,16 @@ V3: * Finish HTTP transaction in one go * Fix bsc#1076132 -V4 +V4: * Add fs_ prefix with upstream commit ad4bfeec5 Change fs functions to add fs_ prefix +V5: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data + * Use grub_calloc for overflow check and return NULL when it would + occur. + --- grub-core/Makefile.core.def | 18 + grub-core/io/bufio.c | 2 +- @@ -57,10 +63,10 @@ V4 create mode 100644 include/grub/efi/http.h create mode 100644 include/grub/net/efi.h -Index: grub-2.04~rc1/grub-core/Makefile.core.def +Index: grub-2.04/grub-core/Makefile.core.def =================================================================== ---- grub-2.04~rc1.orig/grub-core/Makefile.core.def -+++ grub-2.04~rc1/grub-core/Makefile.core.def +--- grub-2.04.orig/grub-core/Makefile.core.def ++++ grub-2.04/grub-core/Makefile.core.def @@ -1854,7 +1854,6 @@ module = { module = { name = linuxefi; @@ -82,10 +88,10 @@ Index: grub-2.04~rc1/grub-core/Makefile.core.def }; module = { -Index: grub-2.04~rc1/grub-core/io/bufio.c +Index: grub-2.04/grub-core/io/bufio.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/io/bufio.c -+++ grub-2.04~rc1/grub-core/io/bufio.c +--- grub-2.04.orig/grub-core/io/bufio.c ++++ grub-2.04/grub-core/io/bufio.c @@ -139,7 +139,7 @@ grub_bufio_read (grub_file_t file, char return res; @@ -95,10 +101,10 @@ Index: grub-2.04~rc1/grub-core/io/bufio.c /* Now read between file->offset + res and bufio->buffer_at. */ if (file->offset + res < next_buf) { -Index: grub-2.04~rc1/grub-core/kern/efi/efi.c +Index: grub-2.04/grub-core/kern/efi/efi.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/kern/efi/efi.c -+++ grub-2.04~rc1/grub-core/kern/efi/efi.c +--- grub-2.04.orig/grub-core/kern/efi/efi.c ++++ grub-2.04/grub-core/kern/efi/efi.c @@ -722,7 +722,7 @@ grub_efi_print_device_path (grub_efi_dev { grub_efi_ipv4_device_path_t *ipv4 @@ -226,10 +232,10 @@ Index: grub-2.04~rc1/grub-core/kern/efi/efi.c default: grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype); break; -Index: grub-2.04~rc1/grub-core/net/drivers/efi/efinet.c +Index: grub-2.04/grub-core/net/drivers/efi/efinet.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/net/drivers/efi/efinet.c -+++ grub-2.04~rc1/grub-core/net/drivers/efi/efinet.c +--- grub-2.04.orig/grub-core/net/drivers/efi/efinet.c ++++ grub-2.04/grub-core/net/drivers/efi/efinet.c @@ -24,6 +24,7 @@ #include #include @@ -298,11 +304,11 @@ Index: grub-2.04~rc1/grub-core/net/drivers/efi/efinet.c + grub_efi_net_config = NULL; } -Index: grub-2.04~rc1/grub-core/net/efi/dhcp.c +Index: grub-2.04/grub-core/net/efi/dhcp.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/dhcp.c -@@ -0,0 +1,397 @@ ++++ grub-2.04/grub-core/net/efi/dhcp.c +@@ -0,0 +1,399 @@ +#include +#include +#include @@ -385,7 +391,7 @@ Index: grub-2.04~rc1/grub-core/net/efi/dhcp.c + if (status != GRUB_EFI_BUFFER_TOO_SMALL) + return NULL; + -+ option_list = grub_malloc (option_count * sizeof(*option_list)); ++ option_list = grub_calloc (option_count, sizeof(*option_list)); + if (!option_list) + return NULL; + @@ -665,7 +671,9 @@ Index: grub-2.04~rc1/grub-core/net/efi/dhcp.c + + if (status == GRUB_EFI_BUFFER_TOO_SMALL && count) + { -+ options = grub_malloc (count * sizeof(*options)); ++ options = grub_calloc (count, sizeof(*options)); ++ if (!options) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); + } + @@ -700,17 +708,18 @@ Index: grub-2.04~rc1/grub-core/net/efi/dhcp.c + +grub_command_func_t grub_efi_net_bootp = grub_cmd_efi_bootp; +grub_command_func_t grub_efi_net_bootp6 = grub_cmd_efi_bootp6; -Index: grub-2.04~rc1/grub-core/net/efi/http.c +Index: grub-2.04/grub-core/net/efi/http.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/http.c -@@ -0,0 +1,419 @@ ++++ grub-2.04/grub-core/net/efi/http.c +@@ -0,0 +1,424 @@ + +#include +#include +#include +#include +#include ++#include + +static void +http_configure (struct grub_efi_net_device *dev, int prefer_ip6) @@ -835,6 +844,7 @@ Index: grub-2.04~rc1/grub-core/net/efi/http.c + grub_efi_char16_t *ucs2_url; + grub_size_t url_len, ucs2_url_len; + const char *protocol = (use_https == 1) ? "https" : "http"; ++ grub_size_t sz; + + if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0) + url = grub_xasprintf ("%s://[%s]%s", protocol, server, name); @@ -847,8 +857,11 @@ Index: grub-2.04~rc1/grub-core/net/efi/http.c + } + + url_len = grub_strlen (url); -+ ucs2_url_len = url_len * GRUB_MAX_UTF16_PER_UTF8; -+ ucs2_url = grub_malloc ((ucs2_url_len + 1) * sizeof (ucs2_url[0])); ++ if (grub_mul (url_len, GRUB_MAX_UTF16_PER_UTF8, &ucs2_url_len) || ++ grub_add (ucs2_url_len, 1, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ ucs2_url = grub_calloc (sz, sizeof (ucs2_url[0])); + + if (!ucs2_url) + { @@ -1124,26 +1137,30 @@ Index: grub-2.04~rc1/grub-core/net/efi/http.c + .read = grub_efihttp_read, + .close = grub_efihttp_close + }; -Index: grub-2.04~rc1/grub-core/net/efi/ip4_config.c +Index: grub-2.04/grub-core/net/efi/ip4_config.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/ip4_config.c -@@ -0,0 +1,398 @@ ++++ grub-2.04/grub-core/net/efi/ip4_config.c +@@ -0,0 +1,409 @@ + +#include +#include +#include +#include +#include ++#include + +char * +grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address) +{ + char *hw_addr, *p; -+ int sz, s; ++ int s; + int i; ++ grub_size_t sz; + -+ sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1; ++ if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) || ++ grub_add (sz, 1, &sz)) ++ return NULL; + + hw_addr = grub_malloc (sz); + if (!hw_addr) @@ -1359,12 +1376,19 @@ Index: grub-2.04~rc1/grub-core/net/efi/ip4_config.c + grub_efi_ip4_config2_interface_info_t *interface_info; + char **ret; + int i, id; ++ grub_size_t sz; + + interface_info = efi_ip4_config_interface_info (dev->ip4_config); + if (!interface_info) + return NULL; + -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1)); ++ if (grub_add (interface_info->route_table_size, 1, &sz)) ++ { ++ grub_free (interface_info); ++ return NULL; ++ } ++ ++ ret = grub_calloc (sz, sizeof (*ret)); + + if (!ret) + { @@ -1527,16 +1551,17 @@ Index: grub-2.04~rc1/grub-core/net/efi/ip4_config.c + .set_gateway = grub_efi_ip4_interface_set_gateway, + .set_dns = grub_efi_ip4_interface_set_dns + }; -Index: grub-2.04~rc1/grub-core/net/efi/ip6_config.c +Index: grub-2.04/grub-core/net/efi/ip6_config.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/ip6_config.c -@@ -0,0 +1,422 @@ ++++ grub-2.04/grub-core/net/efi/ip6_config.c +@@ -0,0 +1,430 @@ +#include +#include +#include +#include +#include ++#include + +char * +grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address) @@ -1763,12 +1788,19 @@ Index: grub-2.04~rc1/grub-core/net/efi/ip6_config.c + grub_efi_ip6_config_interface_info_t *interface_info; + char **ret; + int i, id; ++ grub_size_t sz; + + interface_info = efi_ip6_config_interface_info (dev->ip6_config); + if (!interface_info) + return NULL; + -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1)); ++ if (grub_add (interface_info->route_count, 1, &sz)) ++ { ++ grub_free (interface_info); ++ return NULL; ++ } ++ ++ ret = grub_calloc (sz, sizeof (*ret)); + + if (!ret) + { @@ -1954,11 +1986,11 @@ Index: grub-2.04~rc1/grub-core/net/efi/ip6_config.c + .set_gateway = grub_efi_ip6_interface_set_gateway, + .set_dns = grub_efi_ip6_interface_set_dns + }; -Index: grub-2.04~rc1/grub-core/net/efi/net.c +Index: grub-2.04/grub-core/net/efi/net.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/net.c -@@ -0,0 +1,1428 @@ ++++ grub-2.04/grub-core/net/efi/net.c +@@ -0,0 +1,1437 @@ +#include +#include +#include @@ -1973,6 +2005,7 @@ Index: grub-2.04~rc1/grub-core/net/efi/net.c +#include +#include +#include ++#include + +GRUB_MOD_LICENSE ("GPLv3+"); + @@ -2198,7 +2231,15 @@ Index: grub-2.04~rc1/grub-core/net/efi/net.c + + if (code == GRUB_NET_DHCP6_OPTION_BOOTFILE_URL) + { -+ char *url = grub_malloc (len + 1); ++ char *url; ++ grub_size_t sz; ++ ++ if (grub_add (len, 1, &sz)) ++ return; ++ ++ url = grub_malloc (sz); ++ if (!url) ++ return; + + grub_memcpy (url, dhcp_opt->data, len); + url[len] = 0; @@ -3387,10 +3428,10 @@ Index: grub-2.04~rc1/grub-core/net/efi/net.c + grub_net_open = NULL; + grub_fs_unregister (&grub_efi_netfs); +} -Index: grub-2.04~rc1/grub-core/net/efi/pxe.c +Index: grub-2.04/grub-core/net/efi/pxe.c =================================================================== --- /dev/null -+++ grub-2.04~rc1/grub-core/net/efi/pxe.c ++++ grub-2.04/grub-core/net/efi/pxe.c @@ -0,0 +1,424 @@ + +#include @@ -3816,10 +3857,10 @@ Index: grub-2.04~rc1/grub-core/net/efi/pxe.c + .close = pxe_close + }; + -Index: grub-2.04~rc1/grub-core/net/net.c +Index: grub-2.04/grub-core/net/net.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/net/net.c -+++ grub-2.04~rc1/grub-core/net/net.c +--- grub-2.04.orig/grub-core/net/net.c ++++ grub-2.04/grub-core/net/net.c @@ -32,6 +32,9 @@ #include #include @@ -3926,10 +3967,10 @@ Index: grub-2.04~rc1/grub-core/net/net.c + init_mode = INIT_MODE_NONE; +#endif } -Index: grub-2.04~rc1/include/grub/efi/api.h +Index: grub-2.04/include/grub/efi/api.h =================================================================== ---- grub-2.04~rc1.orig/include/grub/efi/api.h -+++ grub-2.04~rc1/include/grub/efi/api.h +--- grub-2.04.orig/include/grub/efi/api.h ++++ grub-2.04/include/grub/efi/api.h @@ -588,6 +588,23 @@ typedef grub_uint16_t grub_efi_ipv6_addr typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); typedef grub_efi_uint64_t grub_efi_physical_address_t; @@ -4177,10 +4218,10 @@ Index: grub-2.04~rc1/include/grub/efi/api.h #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ || defined(__riscv) -Index: grub-2.04~rc1/include/grub/efi/dhcp.h +Index: grub-2.04/include/grub/efi/dhcp.h =================================================================== --- /dev/null -+++ grub-2.04~rc1/include/grub/efi/dhcp.h ++++ grub-2.04/include/grub/efi/dhcp.h @@ -0,0 +1,343 @@ +#ifndef GRUB_EFI_DHCP_HEADER +#define GRUB_EFI_DHCP_HEADER 1 @@ -4525,10 +4566,10 @@ Index: grub-2.04~rc1/include/grub/efi/dhcp.h +}; + +#endif /* ! GRUB_EFI_DHCP_HEADER */ -Index: grub-2.04~rc1/include/grub/efi/http.h +Index: grub-2.04/include/grub/efi/http.h =================================================================== --- /dev/null -+++ grub-2.04~rc1/include/grub/efi/http.h ++++ grub-2.04/include/grub/efi/http.h @@ -0,0 +1,215 @@ +/* + * GRUB -- GRand Unified Bootloader @@ -4745,10 +4786,10 @@ Index: grub-2.04~rc1/include/grub/efi/http.h +typedef struct grub_efi_http grub_efi_http_t; + +#endif /* !GRUB_EFI_HTTP_HEADER */ -Index: grub-2.04~rc1/include/grub/net/efi.h +Index: grub-2.04/include/grub/net/efi.h =================================================================== --- /dev/null -+++ grub-2.04~rc1/include/grub/net/efi.h ++++ grub-2.04/include/grub/net/efi.h @@ -0,0 +1,144 @@ +#ifndef GRUB_NET_EFI_HEADER +#define GRUB_NET_EFI_HEADER 1 diff --git a/0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch b/0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch new file mode 100644 index 0000000..655a4ef --- /dev/null +++ b/0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch @@ -0,0 +1,67 @@ +From a948ac01744f3490fa5af4b38039f7dade68bb3e Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 15 Apr 2020 15:45:02 -0400 +Subject: [PATCH EMBARGOED CVE-2020-10713] yylex: Make lexer fatal errors + actually be fatal + +When presented with a command that can't be tokenized to anything +smaller than YYLMAX characters, the parser calls YY_FATAL_ERROR(errmsg), +expecting that will stop further processing, as such: + + #define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + if ( yyleng >= YYLMAX ) \ + YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ + yy_flex_strncpy( yytext, yyg->yytext_ptr, yyleng + 1 , yyscanner); \ + yyg->yy_c_buf_p = yy_cp; + +The code flex generates expects that YY_FATAL_ERROR() will either return +for it or do some form of longjmp(), or handle the error in some way at +least, and so the strncpy() call isn't in an "else" clause, and thus if +YY_FATAL_ERROR() is *not* actually fatal, it does the call with the +questionable limit, and predictable results ensue. + +Unfortunately, our implementation of YY_FATAL_ERROR() is: + + #define YY_FATAL_ERROR(msg) \ + do { \ + grub_printf (_("fatal error: %s\n"), _(msg)); \ + } while (0) + +The same pattern exists in yyless(), and similar problems exist in users +of YY_INPUT(), several places in the main parsing loop, +yy_get_next_buffer(), yy_load_buffer_state(), yyensure_buffer_stack, +yy_scan_buffer(), etc. + +All of these callers expect YY_FATAL_ERROR() to actually be fatal, and +the things they do if it returns after calling it are wildly unsafe. + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + grub-core/script/yylex.l | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l +index 7b44c37b7..b7203c823 100644 +--- a/grub-core/script/yylex.l ++++ b/grub-core/script/yylex.l +@@ -37,11 +37,11 @@ + + /* + * As we don't have access to yyscanner, we cannot do much except to +- * print the fatal error. ++ * print the fatal error and exit. + */ + #define YY_FATAL_ERROR(msg) \ + do { \ +- grub_printf (_("fatal error: %s\n"), _(msg)); \ ++ grub_fatal (_("fatal error: %s\n"), _(msg));\ + } while (0) + + #define COPY(str, hint) \ +-- +2.11.0 diff --git a/0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch b/0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch new file mode 100644 index 0000000..f33e367 --- /dev/null +++ b/0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch @@ -0,0 +1,123 @@ +From de1c315841aa6f37357c72e196810484013291d6 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Jun 2020 10:58:42 -0400 +Subject: [PATCH 2/7] safemath: Add some arithmetic primitives that check for + overflow + +This adds a new header, include/grub/safemath.h, that includes easy to +use wrappers for __builtin_{add,sub,mul}_overflow() declared like: + + bool OP(a, b, res) + +where OP is grub_add, grub_sub or grub_mul. OP() returns true in the +case where the operation would overflow and res is not modified. +Otherwise, false is returned and the operation is executed. + +These arithmetic primitives require newer compiler versions. So, bump +these requirements in the INSTALL file too. + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + INSTALL | 22 ++-------------------- + include/grub/compiler.h | 8 ++++++++ + include/grub/safemath.h | 37 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 47 insertions(+), 20 deletions(-) + create mode 100644 include/grub/safemath.h + +diff --git a/INSTALL b/INSTALL +index dedf236a8..79a0af7d9 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -11,27 +11,9 @@ GRUB depends on some software packages installed into your system. If + you don't have any of them, please obtain and install them before + configuring the GRUB. + +-* GCC 4.1.3 or later +- Note: older versions may work but support is limited +- +- Experimental support for clang 3.3 or later (results in much bigger binaries) ++* GCC 5.1.0 or later ++ Experimental support for clang 3.8.0 or later (results in much bigger binaries) + for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64 +- Note: clang 3.2 or later works for i386 and x86_64 targets but results in +- much bigger binaries. +- earlier versions not tested +- Note: clang 3.2 or later works for arm +- earlier versions not tested +- Note: clang on arm64 is not supported due to +- https://llvm.org/bugs/show_bug.cgi?id=26030 +- Note: clang 3.3 or later works for mips(el) +- earlier versions fail to generate .reginfo and hence gprel relocations +- fail. +- Note: clang 3.2 or later works for powerpc +- earlier versions not tested +- Note: clang 3.5 or later works for sparc64 +- earlier versions return "error: unable to interface with target machine" +- Note: clang has no support for ia64 and hence you can't compile GRUB +- for ia64 with clang + * GNU Make + * GNU Bison 2.3 or later + * GNU gettext 0.17 or later +diff --git a/include/grub/compiler.h b/include/grub/compiler.h +index c9e1d7a73..8f3be3ae7 100644 +--- a/include/grub/compiler.h ++++ b/include/grub/compiler.h +@@ -48,4 +48,12 @@ + # define WARN_UNUSED_RESULT + #endif + ++#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) ++# define CLANG_PREREQ(maj,min) \ ++ ((__clang_major__ > (maj)) || \ ++ (__clang_major__ == (maj) && __clang_minor__ >= (min))) ++#else ++# define CLANG_PREREQ(maj,min) 0 ++#endif ++ + #endif /* ! GRUB_COMPILER_HEADER */ +diff --git a/include/grub/safemath.h b/include/grub/safemath.h +new file mode 100644 +index 000000000..c17b89bba +--- /dev/null ++++ b/include/grub/safemath.h +@@ -0,0 +1,37 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * Arithmetic operations that protect against overflow. ++ */ ++ ++#ifndef GRUB_SAFEMATH_H ++#define GRUB_SAFEMATH_H 1 ++ ++#include ++ ++/* These appear in gcc 5.1 and clang 3.8. */ ++#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8) ++ ++#define grub_add(a, b, res) __builtin_add_overflow(a, b, res) ++#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) ++#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) ++ ++#else ++#error gcc 5.1 or newer or clang 3.8 or newer is required ++#endif ++ ++#endif /* GRUB_SAFEMATH_H */ +-- +2.27.0 diff --git a/0003-bootp-New-net_bootp6-command.patch b/0003-bootp-New-net_bootp6-command.patch index 35cede2..965719f 100644 --- a/0003-bootp-New-net_bootp6-command.patch +++ b/0003-bootp-New-net_bootp6-command.patch @@ -8,16 +8,21 @@ DHCPv6 protocol (RFC3315). Signed-off-by: Michael Chang Signed-off-by: Ken Lin + +V1: + * Use grub_calloc for overflow check and return NULL when it would + occur. + --- grub-core/net/bootp.c | 908 +++++++++++++++++++++++++++++++++++++++++++++++++- grub-core/net/ip.c | 39 +++ include/grub/net.h | 72 ++++ 3 files changed, 1018 insertions(+), 1 deletion(-) -Index: grub-2.04~rc1/grub-core/net/bootp.c +Index: grub-2.04/grub-core/net/bootp.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/net/bootp.c -+++ grub-2.04~rc1/grub-core/net/bootp.c +--- grub-2.04.orig/grub-core/net/bootp.c ++++ grub-2.04/grub-core/net/bootp.c @@ -24,6 +24,98 @@ #include #include @@ -265,7 +270,7 @@ Index: grub-2.04~rc1/grub-core/net/bootp.c + break; + } + dhcp6->num_dns_server = ln = len >> 4; -+ dhcp6->dns_server_addrs = la = grub_zalloc (ln * sizeof (*la)); ++ dhcp6->dns_server_addrs = la = grub_calloc (ln, sizeof (*la)); + + for (po = opt->data; ln > 0; po += 0x10, la++, ln--) + { @@ -966,10 +971,10 @@ Index: grub-2.04~rc1/grub-core/net/bootp.c grub_unregister_command (cmd_dhcp); + grub_unregister_command (cmd_bootp6); } -Index: grub-2.04~rc1/grub-core/net/ip.c +Index: grub-2.04/grub-core/net/ip.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/net/ip.c -+++ grub-2.04~rc1/grub-core/net/ip.c +--- grub-2.04.orig/grub-core/net/ip.c ++++ grub-2.04/grub-core/net/ip.c @@ -239,6 +239,45 @@ handle_dgram (struct grub_net_buff *nb, { struct udphdr *udph; @@ -1016,10 +1021,10 @@ Index: grub-2.04~rc1/grub-core/net/ip.c if (proto == GRUB_NET_IP_UDP && grub_be_to_cpu16 (udph->dst) == 68) { const struct grub_net_bootp_packet *bootp; -Index: grub-2.04~rc1/include/grub/net.h +Index: grub-2.04/include/grub/net.h =================================================================== ---- grub-2.04~rc1.orig/include/grub/net.h -+++ grub-2.04~rc1/include/grub/net.h +--- grub-2.04.orig/include/grub/net.h ++++ grub-2.04/include/grub/net.h @@ -448,6 +448,66 @@ struct grub_net_bootp_packet grub_uint8_t vendor[0]; } GRUB_PACKED; diff --git a/0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch b/0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch new file mode 100644 index 0000000..5c3be53 --- /dev/null +++ b/0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch @@ -0,0 +1,239 @@ +From 79e51ab7a9a56f60a14f89ef047fd669977b99d1 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Jun 2020 12:15:29 -0400 +Subject: [PATCH 3/7] calloc: Make sure we always have an overflow-checking + calloc() available + +This tries to make sure that everywhere in this source tree, we always have +an appropriate version of calloc() (i.e. grub_calloc(), xcalloc(), etc.) +available, and that they all safely check for overflow and return NULL when +it would occur. + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + grub-core/kern/emu/misc.c | 12 +++++++++ + grub-core/kern/emu/mm.c | 10 ++++++++ + grub-core/kern/mm.c | 40 ++++++++++++++++++++++++++++++ + grub-core/lib/libgcrypt_wrap/mem.c | 11 ++++++-- + grub-core/lib/posix_wrap/stdlib.h | 8 +++++- + include/grub/emu/misc.h | 1 + + include/grub/mm.h | 6 +++++ + 7 files changed, 85 insertions(+), 3 deletions(-) + +Index: grub-2.04/grub-core/kern/emu/misc.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/emu/misc.c ++++ grub-2.04/grub-core/kern/emu/misc.c +@@ -87,6 +87,18 @@ grub_util_error (const char *fmt, ...) + } + + void * ++xcalloc (grub_size_t nmemb, grub_size_t size) ++{ ++ void *p; ++ ++ p = calloc (nmemb, size); ++ if (!p) ++ grub_util_error ("%s", _("out of memory")); ++ ++ return p; ++} ++ ++void * + xmalloc (grub_size_t size) + { + void *p; +Index: grub-2.04/grub-core/kern/emu/mm.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/emu/mm.c ++++ grub-2.04/grub-core/kern/emu/mm.c +@@ -26,6 +26,16 @@ + #include + + void * ++grub_calloc (grub_size_t nmemb, grub_size_t size) ++{ ++ void *ret; ++ ret = calloc (nmemb, size); ++ if (!ret) ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ return ret; ++} ++ ++void * + grub_malloc (grub_size_t size) + { + void *ret; +Index: grub-2.04/grub-core/kern/mm.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/mm.c ++++ grub-2.04/grub-core/kern/mm.c +@@ -67,8 +67,10 @@ + #include + #include + #include ++#include + + #ifdef MM_DEBUG ++# undef grub_calloc + # undef grub_malloc + # undef grub_zalloc + # undef grub_realloc +@@ -375,6 +377,30 @@ grub_memalign (grub_size_t align, grub_s + return 0; + } + ++/* ++ * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on ++ * integer overflow. ++ */ ++void * ++grub_calloc (grub_size_t nmemb, grub_size_t size) ++{ ++ void *ret; ++ grub_size_t sz = 0; ++ ++ if (grub_mul (nmemb, size, &sz)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ ++ ret = grub_memalign (0, sz); ++ if (!ret) ++ return NULL; ++ ++ grub_memset (ret, 0, sz); ++ return ret; ++} ++ + /* Allocate SIZE bytes and return the pointer. */ + void * + grub_malloc (grub_size_t size) +@@ -562,6 +588,20 @@ grub_mm_dump (unsigned lineno) + } + + void * ++grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t size) ++{ ++ void *ptr; ++ ++ if (grub_mm_debug) ++ grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", ++ file, line, size); ++ ptr = grub_calloc (nmemb, size); ++ if (grub_mm_debug) ++ grub_printf ("%p\n", ptr); ++ return ptr; ++} ++ ++void * + grub_debug_malloc (const char *file, int line, grub_size_t size) + { + void *ptr; +Index: grub-2.04/grub-core/lib/libgcrypt_wrap/mem.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/libgcrypt_wrap/mem.c ++++ grub-2.04/grub-core/lib/libgcrypt_wrap/mem.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -36,7 +37,10 @@ void * + gcry_xcalloc (size_t n, size_t m) + { + void *ret; +- ret = grub_zalloc (n * m); ++ size_t sz; ++ if (grub_mul (n, m, &sz)) ++ grub_fatal ("gcry_xcalloc would overflow"); ++ ret = grub_zalloc (sz); + if (!ret) + grub_fatal ("gcry_xcalloc failed"); + return ret; +@@ -56,7 +60,10 @@ void * + gcry_xcalloc_secure (size_t n, size_t m) + { + void *ret; +- ret = grub_zalloc (n * m); ++ size_t sz; ++ if (grub_mul (n, m, &sz)) ++ grub_fatal ("gcry_xcalloc would overflow"); ++ ret = grub_zalloc (sz); + if (!ret) + grub_fatal ("gcry_xcalloc failed"); + return ret; +Index: grub-2.04/grub-core/lib/posix_wrap/stdlib.h +=================================================================== +--- grub-2.04.orig/grub-core/lib/posix_wrap/stdlib.h ++++ grub-2.04/grub-core/lib/posix_wrap/stdlib.h +@@ -21,6 +21,7 @@ + + #include + #include ++#include + + static inline void + free (void *ptr) +@@ -37,7 +38,12 @@ malloc (grub_size_t size) + static inline void * + calloc (grub_size_t size, grub_size_t nelem) + { +- return grub_zalloc (size * nelem); ++ grub_size_t sz; ++ ++ if (grub_mul (size, nelem, &sz)) ++ return NULL; ++ ++ return grub_zalloc (sz); + } + + static inline void * +Index: grub-2.04/include/grub/emu/misc.h +=================================================================== +--- grub-2.04.orig/include/grub/emu/misc.h ++++ grub-2.04/include/grub/emu/misc.h +@@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char * + #define GRUB_HOST_PRIuLONG_LONG "llu" + #define GRUB_HOST_PRIxLONG_LONG "llx" + ++void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT; + void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT; + void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT; + char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT; +Index: grub-2.04/include/grub/mm.h +=================================================================== +--- grub-2.04.orig/include/grub/mm.h ++++ grub-2.04/include/grub/mm.h +@@ -29,6 +29,7 @@ + #endif + + void grub_mm_init_region (void *addr, grub_size_t size); ++void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size); + void *EXPORT_FUNC(grub_malloc) (grub_size_t size); + void *EXPORT_FUNC(grub_zalloc) (grub_size_t size); + void EXPORT_FUNC(grub_free) (void *ptr); +@@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug); + void grub_mm_dump_free (void); + void grub_mm_dump (unsigned lineno); + ++#define grub_calloc(nmemb, size) \ ++ grub_debug_calloc (GRUB_FILE, __LINE__, nmemb, size) ++ + #define grub_malloc(size) \ + grub_debug_malloc (GRUB_FILE, __LINE__, size) + +@@ -63,6 +67,8 @@ void grub_mm_dump (unsigned lineno); + #define grub_free(ptr) \ + grub_debug_free (GRUB_FILE, __LINE__, ptr) + ++void *EXPORT_FUNC(grub_debug_calloc) (const char *file, int line, ++ grub_size_t nmemb, grub_size_t size); + void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line, + grub_size_t size); + void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line, diff --git a/0004-calloc-Use-calloc-at-most-places.patch b/0004-calloc-Use-calloc-at-most-places.patch new file mode 100644 index 0000000..b60d61c --- /dev/null +++ b/0004-calloc-Use-calloc-at-most-places.patch @@ -0,0 +1,1825 @@ +From 48eeedf1e4bd2a38acb44943e02a8e8ffab2060e Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Jun 2020 12:26:01 -0400 +Subject: [PATCH 4/7] calloc: Use calloc() at most places + +This modifies most of the places we do some form of: + + X = malloc(Y * Z); + +to use calloc(Y, Z) instead. + +Among other issues, this fixes: + - allocation of integer overflow in grub_png_decode_image_header() + reported by Chris Coulson, + - allocation of integer overflow in luks_recover_key() + reported by Chris Coulson, + - allocation of integer overflow in grub_lvm_detect() + reported by Chris Coulson. + +Fixes: CVE-2020-14308 + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + grub-core/bus/usb/usbhub.c | 8 ++++---- + grub-core/commands/efi/lsefisystab.c | 3 ++- + grub-core/commands/legacycfg.c | 6 +++--- + grub-core/commands/menuentry.c | 2 +- + grub-core/commands/nativedisk.c | 2 +- + grub-core/commands/parttool.c | 12 +++++++++--- + grub-core/commands/regexp.c | 2 +- + grub-core/commands/search_wrap.c | 2 +- + grub-core/disk/diskfilter.c | 4 ++-- + grub-core/disk/ieee1275/ofdisk.c | 2 +- + grub-core/disk/ldm.c | 14 +++++++------- + grub-core/disk/luks.c | 2 +- + grub-core/disk/lvm.c | 12 ++++++------ + grub-core/disk/xen/xendisk.c | 2 +- + grub-core/efiemu/loadcore.c | 2 +- + grub-core/efiemu/mm.c | 6 +++--- + grub-core/font/font.c | 3 +-- + grub-core/fs/affs.c | 6 +++--- + grub-core/fs/btrfs.c | 6 +++--- + grub-core/fs/hfs.c | 2 +- + grub-core/fs/hfsplus.c | 6 +++--- + grub-core/fs/iso9660.c | 2 +- + grub-core/fs/ntfs.c | 4 ++-- + grub-core/fs/sfs.c | 2 +- + grub-core/fs/tar.c | 2 +- + grub-core/fs/udf.c | 4 ++-- + grub-core/fs/zfs/zfs.c | 4 ++-- + grub-core/gfxmenu/gui_string_util.c | 2 +- + grub-core/gfxmenu/widget-box.c | 4 ++-- + grub-core/io/gzio.c | 2 +- + grub-core/kern/efi/efi.c | 6 +++--- + grub-core/kern/emu/hostdisk.c | 2 +- + grub-core/kern/fs.c | 2 +- + grub-core/kern/misc.c | 2 +- + grub-core/kern/parser.c | 2 +- + grub-core/kern/uboot/uboot.c | 2 +- + grub-core/lib/json/json.c | 2 +- + grub-core/lib/libgcrypt/cipher/ac.c | 8 ++++---- + grub-core/lib/libgcrypt/cipher/primegen.c | 4 ++-- + grub-core/lib/libgcrypt/cipher/pubkey.c | 4 ++-- + grub-core/lib/priority_queue.c | 2 +- + grub-core/lib/reed_solomon.c | 7 +++---- + grub-core/lib/relocator.c | 10 +++++----- + grub-core/lib/zstd/fse_decompress.c | 2 +- + grub-core/loader/arm/linux.c | 2 +- + grub-core/loader/efi/chainloader.c | 2 +- + grub-core/loader/i386/bsdXX.c | 2 +- + grub-core/loader/i386/xnu.c | 4 ++-- + grub-core/loader/macho.c | 2 +- + grub-core/loader/multiboot_elfxx.c | 2 +- + grub-core/loader/xnu.c | 2 +- + grub-core/mmap/mmap.c | 4 ++-- + grub-core/net/bootp.c | 2 +- + grub-core/net/dns.c | 10 +++++----- + grub-core/net/net.c | 4 ++-- + grub-core/normal/charset.c | 10 +++++----- + grub-core/normal/cmdline.c | 14 +++++++------- + grub-core/normal/menu_entry.c | 14 +++++++------- + grub-core/normal/menu_text.c | 4 ++-- + grub-core/normal/term.c | 4 ++-- + grub-core/osdep/linux/getroot.c | 6 +++--- + grub-core/osdep/unix/config.c | 2 +- + grub-core/osdep/windows/getroot.c | 2 +- + grub-core/osdep/windows/hostdisk.c | 4 ++-- + grub-core/osdep/windows/init.c | 2 +- + grub-core/osdep/windows/platform.c | 4 ++-- + grub-core/osdep/windows/relpath.c | 2 +- + grub-core/partmap/gpt.c | 2 +- + grub-core/partmap/msdos.c | 2 +- + grub-core/script/execute.c | 2 +- + grub-core/tests/fake_input.c | 2 +- + grub-core/tests/video_checksum.c | 6 +++--- + grub-core/video/capture.c | 2 +- + grub-core/video/emu/sdl.c | 2 +- + grub-core/video/i386/pc/vga.c | 2 +- + grub-core/video/readers/png.c | 2 +- + include/grub/unicode.h | 4 ++-- + util/getroot.c | 2 +- + util/grub-file.c | 2 +- + util/grub-fstest.c | 4 ++-- + util/grub-install-common.c | 2 +- + util/grub-install.c | 4 ++-- + util/grub-mkimagexx.c | 6 ++---- + util/grub-mkrescue.c | 4 ++-- + util/grub-mkstandalone.c | 2 +- + util/grub-pe2elf.c | 12 +++++------- + util/grub-probe.c | 4 ++-- + 87 files changed, 179 insertions(+), 178 deletions(-) + +Index: grub-2.04/grub-core/bus/usb/usbhub.c +=================================================================== +--- grub-2.04.orig/grub-core/bus/usb/usbhub.c ++++ grub-2.04/grub-core/bus/usb/usbhub.c +@@ -149,8 +149,8 @@ grub_usb_add_hub (grub_usb_device_t dev) + grub_usb_set_configuration (dev, 1); + + dev->nports = hubdesc.portcnt; +- dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); +- dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0])); ++ dev->children = grub_calloc (hubdesc.portcnt, sizeof (dev->children[0])); ++ dev->ports = grub_calloc (dev->nports, sizeof (dev->ports[0])); + if (!dev->children || !dev->ports) + { + grub_free (dev->children); +@@ -268,8 +268,8 @@ grub_usb_controller_dev_register_iter (g + + /* Query the number of ports the root Hub has. */ + hub->nports = controller->dev->hubports (controller); +- hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports); +- hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports); ++ hub->devices = grub_calloc (hub->nports, sizeof (hub->devices[0])); ++ hub->ports = grub_calloc (hub->nports, sizeof (hub->ports[0])); + if (!hub->devices || !hub->ports) + { + grub_free (hub->devices); +Index: grub-2.04/grub-core/commands/efi/lsefisystab.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/efi/lsefisystab.c ++++ grub-2.04/grub-core/commands/efi/lsefisystab.c +@@ -71,7 +71,8 @@ grub_cmd_lsefisystab (struct grub_comman + grub_printf ("Vendor: "); + + for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++); +- vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1); ++ /* Allocate extra 3 bytes to simplify math. */ ++ vendor = grub_calloc (4, vendor_utf16 - st->firmware_vendor + 1); + if (!vendor) + return grub_errno; + *grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor, +Index: grub-2.04/grub-core/commands/legacycfg.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/legacycfg.c ++++ grub-2.04/grub-core/commands/legacycfg.c +@@ -314,7 +314,7 @@ grub_cmd_legacy_kernel (struct grub_comm + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + +- cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); ++ cutargs = grub_calloc (argc - 1, sizeof (cutargs[0])); + if (!cutargs) + return grub_errno; + cutargc = argc - 1; +@@ -436,7 +436,7 @@ grub_cmd_legacy_kernel (struct grub_comm + { + char rbuf[3] = "-r"; + bsdargc = cutargc + 2; +- bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); ++ bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0])); + if (!bsdargs) + { + err = grub_errno; +@@ -559,7 +559,7 @@ grub_cmd_legacy_initrdnounzip (struct gr + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "module"); + +- newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); ++ newargs = grub_calloc (argc + 1, sizeof (newargs[0])); + if (!newargs) + return grub_errno; + grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); +Index: grub-2.04/grub-core/commands/menuentry.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/menuentry.c ++++ grub-2.04/grub-core/commands/menuentry.c +@@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, co + goto fail; + + /* Save argc, args to pass as parameters to block arg later. */ +- menu_args = grub_malloc (sizeof (char*) * (argc + 1)); ++ menu_args = grub_calloc (argc + 1, sizeof (char *)); + if (! menu_args) + goto fail; + +Index: grub-2.04/grub-core/commands/nativedisk.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/nativedisk.c ++++ grub-2.04/grub-core/commands/nativedisk.c +@@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd + else + path_prefix = prefix; + +- mods = grub_malloc (argc * sizeof (mods[0])); ++ mods = grub_calloc (argc, sizeof (mods[0])); + if (!mods) + return grub_errno; + +Index: grub-2.04/grub-core/commands/parttool.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/parttool.c ++++ grub-2.04/grub-core/commands/parttool.c +@@ -59,7 +59,13 @@ grub_parttool_register(const char *part_ + for (nargs = 0; args[nargs].name != 0; nargs++); + cur->nargs = nargs; + cur->args = (struct grub_parttool_argdesc *) +- grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); ++ grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc)); ++ if (!cur->args) ++ { ++ grub_free (cur); ++ curhandle--; ++ return -1; ++ } + grub_memcpy (cur->args, args, + (nargs + 1) * sizeof (struct grub_parttool_argdesc)); + +@@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __ + return err; + } + +- parsed = (int *) grub_zalloc (argc * sizeof (int)); ++ parsed = (int *) grub_calloc (argc, sizeof (int)); + + for (i = 1; i < argc; i++) + if (! parsed[i]) +@@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __ + } + ptool = cur; + pargs = (struct grub_parttool_args *) +- grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args)); ++ grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args)); + for (j = i; j < argc; j++) + if (! parsed[j]) + { +Index: grub-2.04/grub-core/commands/regexp.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/regexp.c ++++ grub-2.04/grub-core/commands/regexp.c +@@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t c + if (ret) + goto fail; + +- matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1)); ++ matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches)); + if (! matches) + goto fail; + +Index: grub-2.04/grub-core/commands/search_wrap.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/search_wrap.c ++++ grub-2.04/grub-core/commands/search_wrap.c +@@ -122,7 +122,7 @@ grub_cmd_search (grub_extcmd_context_t c + for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++) + nhints++; + +- hints = grub_malloc (sizeof (hints[0]) * nhints); ++ hints = grub_calloc (nhints, sizeof (hints[0])); + if (!hints) + return grub_errno; + j = 0; +Index: grub-2.04/grub-core/disk/diskfilter.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/diskfilter.c ++++ grub-2.04/grub-core/disk/diskfilter.c +@@ -1230,7 +1230,7 @@ grub_diskfilter_make_raid (grub_size_t u + array->lvs->segments->node_count = nmemb; + array->lvs->segments->raid_member_size = disk_size; + array->lvs->segments->nodes +- = grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0])); ++ = grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0])); + array->lvs->segments->stripe_size = stripe_size; + for (i = 0; i < nmemb; i++) + { +@@ -1322,7 +1322,7 @@ insert_array (grub_disk_t disk, const st + grub_partition_t p; + for (p = disk->partition; p; p = p->parent) + s++; +- pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0])); ++ pv->partmaps = xcalloc (s, sizeof (pv->partmaps[0])); + s = 0; + for (p = disk->partition; p; p = p->parent) + pv->partmaps[s++] = xstrdup (p->partmap->name); +Index: grub-2.04/grub-core/disk/ieee1275/ofdisk.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/ieee1275/ofdisk.c ++++ grub-2.04/grub-core/disk/ieee1275/ofdisk.c +@@ -297,7 +297,7 @@ dev_iterate (const struct grub_ieee1275_ + /* Power machines documentation specify 672 as maximum SAS disks in + one system. Using a slightly larger value to be safe. */ + table_size = 768; +- table = grub_malloc (table_size * sizeof (grub_uint64_t)); ++ table = grub_calloc (table_size, sizeof (grub_uint64_t)); + + if (!table) + { +Index: grub-2.04/grub-core/disk/ldm.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/ldm.c ++++ grub-2.04/grub-core/disk/ldm.c +@@ -323,8 +323,8 @@ make_vg (grub_disk_t disk, + lv->segments->type = GRUB_DISKFILTER_MIRROR; + lv->segments->node_count = 0; + lv->segments->node_alloc = 8; +- lv->segments->nodes = grub_zalloc (sizeof (*lv->segments->nodes) +- * lv->segments->node_alloc); ++ lv->segments->nodes = grub_calloc (lv->segments->node_alloc, ++ sizeof (*lv->segments->nodes)); + if (!lv->segments->nodes) + goto fail2; + ptr = vblk[i].dynamic; +@@ -543,8 +543,8 @@ make_vg (grub_disk_t disk, + { + comp->segment_alloc = 8; + comp->segment_count = 0; +- comp->segments = grub_malloc (sizeof (*comp->segments) +- * comp->segment_alloc); ++ comp->segments = grub_calloc (comp->segment_alloc, ++ sizeof (*comp->segments)); + if (!comp->segments) + goto fail2; + } +@@ -590,8 +590,8 @@ make_vg (grub_disk_t disk, + } + comp->segments->node_count = read_int (ptr + 1, *ptr); + comp->segments->node_alloc = comp->segments->node_count; +- comp->segments->nodes = grub_zalloc (sizeof (*comp->segments->nodes) +- * comp->segments->node_alloc); ++ comp->segments->nodes = grub_calloc (comp->segments->node_alloc, ++ sizeof (*comp->segments->nodes)); + if (!lv->segments->nodes) + goto fail2; + } +@@ -1017,7 +1017,7 @@ grub_util_ldm_embed (struct grub_disk *d + *nsectors = lv->size; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +- *sectors = grub_malloc (*nsectors * sizeof (**sectors)); ++ *sectors = grub_calloc (*nsectors, sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +Index: grub-2.04/grub-core/disk/luks.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/luks.c ++++ grub-2.04/grub-core/disk/luks.c +@@ -336,7 +336,7 @@ luks_recover_key (grub_disk_t source, + && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) + max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); + +- split_key = grub_malloc (keysize * max_stripes); ++ split_key = grub_calloc (keysize, max_stripes); + if (!split_key) + return grub_errno; + +Index: grub-2.04/grub-core/disk/lvm.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/lvm.c ++++ grub-2.04/grub-core/disk/lvm.c +@@ -456,7 +456,7 @@ grub_lvm_detect (grub_disk_t disk, + #endif + goto lvs_fail; + } +- lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count); ++ lv->segments = grub_calloc (lv->segment_count, sizeof (*seg)); + seg = lv->segments; + + for (i = 0; i < lv->segment_count; i++) +@@ -513,8 +513,8 @@ grub_lvm_detect (grub_disk_t disk, + if (seg->node_count != 1) + seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); + +- seg->nodes = grub_zalloc (sizeof (*stripe) +- * seg->node_count); ++ seg->nodes = grub_calloc (seg->node_count, ++ sizeof (*stripe)); + stripe = seg->nodes; + + p = grub_strstr (p, "stripes = ["); +Index: grub-2.04/grub-core/disk/xen/xendisk.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/xen/xendisk.c ++++ grub-2.04/grub-core/disk/xen/xendisk.c +@@ -426,7 +426,7 @@ grub_xendisk_init (void) + if (!ctr) + return; + +- virtdisks = grub_malloc (ctr * sizeof (virtdisks[0])); ++ virtdisks = grub_calloc (ctr, sizeof (virtdisks[0])); + if (!virtdisks) + return; + if (grub_xenstore_dir ("device/vbd", fill, &ctr)) +Index: grub-2.04/grub-core/efiemu/loadcore.c +=================================================================== +--- grub-2.04.orig/grub-core/efiemu/loadcore.c ++++ grub-2.04/grub-core/efiemu/loadcore.c +@@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehd + + grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize; + grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *) +- grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms); ++ grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym)); + + /* Relocators */ + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); +Index: grub-2.04/grub-core/efiemu/mm.c +=================================================================== +--- grub-2.04.orig/grub-core/efiemu/mm.c ++++ grub-2.04/grub-core/efiemu/mm.c +@@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void) + /* Initialize variables*/ + grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE); + scanline_events = (struct grub_efiemu_mmap_scan *) +- grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num); ++ grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2); + + /* Number of chunks can't increase more than by factor of 2 */ + result = (grub_efi_memory_descriptor_t *) +- grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num); ++ grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2); + if (!result || !scanline_events) + { + grub_free (result); +@@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void) + + /* Preallocate mmap */ + efiemu_mmap = (grub_efi_memory_descriptor_t *) +- grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t)); ++ grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t)); + if (!efiemu_mmap) + { + grub_efiemu_unload (); +Index: grub-2.04/grub-core/font/font.c +=================================================================== +--- grub-2.04.orig/grub-core/font/font.c ++++ grub-2.04/grub-core/font/font.c +@@ -293,8 +293,7 @@ load_font_index (grub_file_t file, grub_ + font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE; + + /* Allocate the character index array. */ +- font->char_index = grub_malloc (font->num_chars +- * sizeof (struct char_index_entry)); ++ font->char_index = grub_calloc (font->num_chars, sizeof (struct char_index_entry)); + if (!font->char_index) + return 1; + font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); +Index: grub-2.04/grub-core/fs/affs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/affs.c ++++ grub-2.04/grub-core/fs/affs.c +@@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node + return 0; + } + latin1[symlink_size] = 0; +- utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1); ++ utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size); + if (!utf8) + { + grub_free (latin1); +@@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_ + return 1; + } + +- hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); ++ hashtable = grub_calloc (data->htsize, sizeof (*hashtable)); + if (!hashtable) + return 1; + +@@ -628,7 +628,7 @@ grub_affs_label (grub_device_t device, c + len = file.namelen; + if (len > sizeof (file.name)) + len = sizeof (file.name); +- *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); ++ *label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len); + if (*label) + *grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0'; + } +Index: grub-2.04/grub-core/fs/btrfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/btrfs.c ++++ grub-2.04/grub-core/fs/btrfs.c +@@ -450,7 +450,7 @@ lower_bound (struct grub_btrfs_data *dat + { + desc->allocated = 16; + desc->depth = 0; +- desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); ++ desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0])); + if (!desc->data) + return grub_errno; + } +@@ -789,7 +789,7 @@ raid56_read_retry (struct grub_btrfs_dat + grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; + grub_uint64_t i, failed_devices; + +- buffers = grub_zalloc (sizeof(*buffers) * nstripes); ++ buffers = grub_calloc (nstripes, sizeof (*buffers)); + if (!buffers) + goto cleanup; + +@@ -2495,7 +2495,7 @@ grub_btrfs_embed (grub_device_t device _ + *nsectors = 64 * 2 - 1; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +- *sectors = grub_malloc (*nsectors * sizeof (**sectors)); ++ *sectors = grub_calloc (*nsectors, sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +Index: grub-2.04/grub-core/fs/hfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/hfs.c ++++ grub-2.04/grub-core/fs/hfs.c +@@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, ch + grub_size_t len = data->sblock.volname[0]; + if (len > sizeof (data->sblock.volname) - 1) + len = sizeof (data->sblock.volname) - 1; +- *label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1); ++ *label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len); + if (*label) + macroman_to_utf8 (*label, data->sblock.volname + 1, + len + 1, 0); +Index: grub-2.04/grub-core/fs/hfsplus.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/hfsplus.c ++++ grub-2.04/grub-core/fs/hfsplus.c +@@ -720,7 +720,7 @@ list_nodes (void *record, void *hook_arg + if (! filename) + return 0; + +- keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname)); ++ keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); + if (!keyname) + { + grub_free (filename); +@@ -1007,7 +1007,7 @@ grub_hfsplus_label (grub_device_t device + grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); + + label_len = grub_be_to_cpu16 (catkey->namelen); +- label_name = grub_malloc (label_len * sizeof (*label_name)); ++ label_name = grub_calloc (label_len, sizeof (*label_name)); + if (!label_name) + { + grub_free (node); +@@ -1029,7 +1029,7 @@ grub_hfsplus_label (grub_device_t device + } + } + +- *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); ++ *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! *label) + { + grub_free (label_name); +Index: grub-2.04/grub-core/fs/iso9660.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/iso9660.c ++++ grub-2.04/grub-core/fs/iso9660.c +@@ -331,7 +331,7 @@ grub_iso9660_convert_string (grub_uint8_ + int i; + grub_uint16_t t[MAX_NAMELEN / 2 + 1]; + +- p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); ++ p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! p) + return NULL; + +Index: grub-2.04/grub-core/fs/ntfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/ntfs.c ++++ grub-2.04/grub-core/fs/ntfs.c +@@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t + grub_uint16_t *tmp; + grub_size_t i; + +- buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); +- tmp = grub_malloc (len * sizeof (tmp[0])); ++ buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); ++ tmp = grub_calloc (len, sizeof (tmp[0])); + if (!buf || !tmp) + { + grub_free (buf); +Index: grub-2.04/grub-core/fs/sfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/sfs.c ++++ grub-2.04/grub-core/fs/sfs.c +@@ -266,7 +266,7 @@ grub_sfs_read_block (grub_fshelp_node_t + node->next_extent = node->block; + node->cache_size = 0; + +- node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size); ++ node->cache = grub_calloc (cache_size, sizeof (node->cache[0])); + if (!node->cache) + { + grub_errno = 0; +Index: grub-2.04/grub-core/fs/tar.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/tar.c ++++ grub-2.04/grub-core/fs/tar.c +@@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp + if (data->linkname_alloc < linksize + 1) + { + char *n; +- n = grub_malloc (2 * (linksize + 1)); ++ n = grub_calloc (2, linksize + 1); + if (!n) + return grub_errno; + grub_free (data->linkname); +Index: grub-2.04/grub-core/fs/udf.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/udf.c ++++ grub-2.04/grub-core/fs/udf.c +@@ -873,7 +873,7 @@ read_string (const grub_uint8_t *raw, gr + { + unsigned i; + utf16len = sz - 1; +- utf16 = grub_malloc (utf16len * sizeof (utf16[0])); ++ utf16 = grub_calloc (utf16len, sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) +@@ -883,7 +883,7 @@ read_string (const grub_uint8_t *raw, gr + { + unsigned i; + utf16len = (sz - 1) / 2; +- utf16 = grub_malloc (utf16len * sizeof (utf16[0])); ++ utf16 = grub_calloc (utf16len, sizeof (utf16[0])); + if (!utf16) + return NULL; + for (i = 0; i < utf16len; i++) +Index: grub-2.04/grub-core/fs/zfs/zfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/zfs/zfs.c ++++ grub-2.04/grub-core/fs/zfs/zfs.c +@@ -3328,7 +3328,7 @@ dnode_get_fullpath (const char *fullpath + } + subvol->nkeys = 0; + zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data); +- subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); ++ subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0])); + if (!subvol->keyring) + { + grub_free (fsname); +@@ -4339,7 +4339,7 @@ grub_zfs_embed (grub_device_t device __a + *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +- *sectors = grub_malloc (*nsectors * sizeof (**sectors)); ++ *sectors = grub_calloc (*nsectors, sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +Index: grub-2.04/grub-core/gfxmenu/gui_string_util.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/gui_string_util.c ++++ grub-2.04/grub-core/gfxmenu/gui_string_util.c +@@ -55,7 +55,7 @@ canonicalize_path (const char *path) + if (*p == '/') + components++; + +- char **path_array = grub_malloc (components * sizeof (*path_array)); ++ char **path_array = grub_calloc (components, sizeof (*path_array)); + if (! path_array) + return 0; + +Index: grub-2.04/grub-core/gfxmenu/widget-box.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/widget-box.c ++++ grub-2.04/grub-core/gfxmenu/widget-box.c +@@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pix + box->content_height = 0; + box->raw_pixmaps = + (struct grub_video_bitmap **) +- grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); ++ grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); + box->scaled_pixmaps = + (struct grub_video_bitmap **) +- grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); ++ grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); + + /* Initialize all pixmap pointers to NULL so that proper destruction can + be performed if an error is encountered partway through construction. */ +Index: grub-2.04/grub-core/io/gzio.c +=================================================================== +--- grub-2.04.orig/grub-core/io/gzio.c ++++ grub-2.04/grub-core/io/gzio.c +@@ -554,7 +554,7 @@ huft_build (unsigned *b, /* code lengths + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ +- q = (struct huft *) grub_zalloc ((z + 1) * sizeof (struct huft)); ++ q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft)); + if (! q) + { + if (h) +Index: grub-2.04/grub-core/kern/efi/efi.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/efi/efi.c ++++ grub-2.04/grub-core/kern/efi/efi.c +@@ -202,7 +202,7 @@ grub_efi_set_variable(const char *var, c + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; +- var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); ++ var16 = grub_calloc (len16 + 1, sizeof (var16[0])); + if (!var16) + return grub_errno; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); +@@ -237,7 +237,7 @@ grub_efi_get_variable (const char *var, + + len = grub_strlen (var); + len16 = len * GRUB_MAX_UTF16_PER_UTF8; +- var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); ++ var16 = grub_calloc (len16 + 1, sizeof (var16[0])); + if (!var16) + return NULL; + len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); +@@ -411,7 +411,7 @@ grub_efi_get_filename (grub_efi_device_p + while (len > 0 && fp->path_name[len - 1] == 0) + len--; + +- dup_name = grub_malloc (len * sizeof (*dup_name)); ++ dup_name = grub_calloc (len, sizeof (*dup_name)); + if (!dup_name) + { + grub_free (name); +Index: grub-2.04/grub-core/kern/emu/hostdisk.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/emu/hostdisk.c ++++ grub-2.04/grub-core/kern/emu/hostdisk.c +@@ -615,7 +615,7 @@ static char * + grub_util_path_concat_real (size_t n, int ext, va_list ap) + { + size_t totlen = 0; +- char **l = xmalloc ((n + ext) * sizeof (l[0])); ++ char **l = xcalloc (n + ext, sizeof (l[0])); + char *r, *p, *pi; + size_t i; + int first = 1; +Index: grub-2.04/grub-core/kern/fs.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/fs.c ++++ grub-2.04/grub-core/kern/fs.c +@@ -152,7 +152,7 @@ grub_fs_blocklist_open (grub_file_t file + while (p); + + /* Allocate a block list. */ +- blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1)); ++ blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block)); + if (! blocks) + return 0; + +Index: grub-2.04/grub-core/kern/misc.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/misc.c ++++ grub-2.04/grub-core/kern/misc.c +@@ -691,7 +691,7 @@ parse_printf_args (const char *fmt0, str + args->ptr = args->prealloc; + else + { +- args->ptr = grub_malloc (args->count * sizeof (args->ptr[0])); ++ args->ptr = grub_calloc (args->count, sizeof (args->ptr[0])); + if (!args->ptr) + { + grub_errno = GRUB_ERR_NONE; +Index: grub-2.04/grub-core/kern/parser.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/parser.c ++++ grub-2.04/grub-core/kern/parser.c +@@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *c + return grub_errno; + grub_memcpy (args, buffer, bp - buffer); + +- *argv = grub_malloc (sizeof (char *) * (*argc + 1)); ++ *argv = grub_calloc (*argc + 1, sizeof (char *)); + if (!*argv) + { + grub_free (args); +Index: grub-2.04/grub-core/kern/uboot/uboot.c +=================================================================== +--- grub-2.04.orig/grub-core/kern/uboot/uboot.c ++++ grub-2.04/grub-core/kern/uboot/uboot.c +@@ -133,7 +133,7 @@ grub_uboot_dev_enum (void) + return num_devices; + + max_devices = 2; +- enum_devices = grub_malloc (sizeof(struct device_info) * max_devices); ++ enum_devices = grub_calloc (max_devices, sizeof(struct device_info)); + if (!enum_devices) + return 0; + +Index: grub-2.04/grub-core/lib/libgcrypt/cipher/ac.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/libgcrypt/cipher/ac.c ++++ grub-2.04/grub-core/lib/libgcrypt/cipher/ac.c +@@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mp + gcry_mpi_t mpi; + char *label; + +- data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n); ++ data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new)); + if (! data_mpis_new) + { + err = gcry_error_from_errno (errno); +@@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t da + } + + /* Add MPI list. */ +- arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); ++ arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list)); + if (! arg_list) + { + err = gcry_error_from_errno (errno); +@@ -1283,7 +1283,7 @@ ac_data_construct (const char *identifie + /* We build a list of arguments to pass to + gcry_sexp_build_array(). */ + data_length = _gcry_ac_data_length (data); +- arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2)); ++ arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2); + if (! arg_list) + { + err = gcry_error_from_errno (errno); +@@ -1593,7 +1593,7 @@ _gcry_ac_key_pair_generate (gcry_ac_hand + arg_list_n += 2; + + /* Allocate list. */ +- arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n); ++ arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list)); + if (! arg_list) + { + err = gcry_error_from_errno (errno); +Index: grub-2.04/grub-core/lib/libgcrypt/cipher/primegen.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/libgcrypt/cipher/primegen.c ++++ grub-2.04/grub-core/lib/libgcrypt/cipher/primegen.c +@@ -383,7 +383,7 @@ prime_generate_internal (int need_q_fact + } + + /* Allocate an array to track pool usage. */ +- pool_in_use = gcry_malloc (n * sizeof *pool_in_use); ++ pool_in_use = gcry_calloc (n, sizeof *pool_in_use); + if (!pool_in_use) + { + err = gpg_err_code_from_errno (errno); +@@ -765,7 +765,7 @@ gen_prime (unsigned int nbits, int secre + if (nbits < 16) + log_fatal ("can't generate a prime with less than %d bits\n", 16); + +- mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods ); ++ mods = gcry_xcalloc( no_of_small_prime_numbers, sizeof *mods); + /* Make nbits fit into gcry_mpi_t implementation. */ + val_2 = mpi_alloc_set_ui( 2 ); + val_3 = mpi_alloc_set_ui( 3); +Index: grub-2.04/grub-core/lib/libgcrypt/cipher/pubkey.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/libgcrypt/cipher/pubkey.c ++++ grub-2.04/grub-core/lib/libgcrypt/cipher/pubkey.c +@@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gc + * array to a format string, so we have to do it this way :-(. */ + /* FIXME: There is now such a format specifier, so we can + change the code to be more clear. */ +- arg_list = malloc (nelem * sizeof *arg_list); ++ arg_list = calloc (nelem, sizeof *arg_list); + if (!arg_list) + { + rc = gpg_err_code_from_syserror (); +@@ -3233,7 +3233,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_s + } + strcpy (p, "))"); + +- arg_list = malloc (nelem * sizeof *arg_list); ++ arg_list = calloc (nelem, sizeof *arg_list); + if (!arg_list) + { + rc = gpg_err_code_from_syserror (); +Index: grub-2.04/grub-core/lib/priority_queue.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/priority_queue.c ++++ grub-2.04/grub-core/lib/priority_queue.c +@@ -92,7 +92,7 @@ grub_priority_queue_new (grub_size_t els + { + struct grub_priority_queue *ret; + void *els; +- els = grub_malloc (elsize * 8); ++ els = grub_calloc (8, elsize); + if (!els) + return 0; + ret = (struct grub_priority_queue *) grub_malloc (sizeof (*ret)); +Index: grub-2.04/grub-core/lib/reed_solomon.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/reed_solomon.c ++++ grub-2.04/grub-core/lib/reed_solomon.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#define xcalloc calloc + #define xmalloc malloc + #define grub_memset memset + #define grub_memcpy memcpy +@@ -158,11 +159,9 @@ rs_encode (gf_single_t *data, grub_size_ + gf_single_t *rs_polynomial; + int i, j; + gf_single_t *m; +- m = xmalloc ((s + rs) * sizeof (gf_single_t)); ++ m = xcalloc (s + rs, sizeof (gf_single_t)); + grub_memcpy (m, data, s * sizeof (gf_single_t)); +- grub_memset (m + s, 0, rs * sizeof (gf_single_t)); +- rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t)); +- grub_memset (rs_polynomial, 0, (rs + 1) * sizeof (gf_single_t)); ++ rs_polynomial = xcalloc (rs + 1, sizeof (gf_single_t)); + rs_polynomial[rs] = 1; + /* Multiply with X - a^r */ + for (j = 0; j < rs; j++) +Index: grub-2.04/grub-core/lib/relocator.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/relocator.c ++++ grub-2.04/grub-core/lib/relocator.c +@@ -495,9 +495,9 @@ malloc_in_range (struct grub_relocator * + } + #endif + +- eventt = grub_malloc (maxevents * sizeof (events[0])); ++ eventt = grub_calloc (maxevents, sizeof (events[0])); + counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); +- events = grub_malloc (maxevents * sizeof (events[0])); ++ events = grub_calloc (maxevents, sizeof (events[0])); + if (!events || !eventt || !counter) + { + grub_dprintf ("relocator", "events or counter allocation failed %d\n", +@@ -963,7 +963,7 @@ malloc_in_range (struct grub_relocator * + #endif + unsigned cural = 0; + int oom = 0; +- res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs); ++ res->subchunks = grub_calloc (nallocs, sizeof (res->subchunks[0])); + if (!res->subchunks) + oom = 1; + res->nsubchunks = nallocs; +@@ -1562,8 +1562,8 @@ grub_relocator_prepare_relocs (struct gr + count[(chunk->src & 0xff) + 1]++; + } + } +- from = grub_malloc (nchunks * sizeof (sorted[0])); +- to = grub_malloc (nchunks * sizeof (sorted[0])); ++ from = grub_calloc (nchunks, sizeof (sorted[0])); ++ to = grub_calloc (nchunks, sizeof (sorted[0])); + if (!from || !to) + { + grub_free (from); +Index: grub-2.04/grub-core/lib/zstd/fse_decompress.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/zstd/fse_decompress.c ++++ grub-2.04/grub-core/lib/zstd/fse_decompress.c +@@ -82,7 +82,7 @@ + FSE_DTable* FSE_createDTable (unsigned tableLog) + { + if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; +- return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); ++ return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); + } + + void FSE_freeDTable (FSE_DTable* dt) +Index: grub-2.04/grub-core/loader/arm/linux.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/arm/linux.c ++++ grub-2.04/grub-core/loader/arm/linux.c +@@ -78,7 +78,7 @@ linux_prepare_atag (void *target_atag) + + /* some place for cmdline, initrd and terminator. */ + tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4; +- tmp_atag = grub_malloc (tmp_size * sizeof (grub_uint32_t)); ++ tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t)); + if (!tmp_atag) + return grub_errno; + +Index: grub-2.04/grub-core/loader/efi/chainloader.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/efi/chainloader.c ++++ grub-2.04/grub-core/loader/efi/chainloader.c +@@ -133,7 +133,7 @@ copy_file_path (grub_efi_file_path_devic + fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; + fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; + +- path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); ++ path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); + if (!path_name) + return; + +Index: grub-2.04/grub-core/loader/i386/bsdXX.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/i386/bsdXX.c ++++ grub-2.04/grub-core/loader/i386/bsdXX.c +@@ -48,7 +48,7 @@ read_headers (grub_file_t file, const ch + if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS)) + return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); + +- *shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize); ++ *shdr = grub_calloc (e->e_shnum, e->e_shentsize); + if (! *shdr) + return grub_errno; + +Index: grub-2.04/grub-core/loader/i386/xnu.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/i386/xnu.c ++++ grub-2.04/grub-core/loader/i386/xnu.c +@@ -295,7 +295,7 @@ grub_xnu_devprop_add_property_utf8 (stru + return grub_errno; + + len = grub_strlen (name); +- utf16 = grub_malloc (sizeof (grub_uint16_t) * len); ++ utf16 = grub_calloc (len, sizeof (grub_uint16_t)); + if (!utf16) + { + grub_free (utf8); +@@ -331,7 +331,7 @@ grub_xnu_devprop_add_property_utf16 (str + grub_uint16_t *utf16; + grub_err_t err; + +- utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); ++ utf16 = grub_calloc (namelen, sizeof (grub_uint16_t)); + if (!utf16) + return grub_errno; + grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); +Index: grub-2.04/grub-core/loader/macho.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/macho.c ++++ grub-2.04/grub-core/loader/macho.c +@@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const + if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header)) + == (grub_off_t) -1) + goto fail; +- archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); ++ archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); + if (!archs) + goto fail; + if (grub_file_read (macho->file, archs, +Index: grub-2.04/grub-core/loader/multiboot_elfxx.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/multiboot_elfxx.c ++++ grub-2.04/grub-core/loader/multiboot_elfxx.c +@@ -217,7 +217,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi + { + grub_uint8_t *shdr, *shdrptr; + +- shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize); ++ shdr = grub_calloc (ehdr->e_shnum, ehdr->e_shentsize); + if (!shdr) + return grub_errno; + +Index: grub-2.04/grub-core/loader/xnu.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/xnu.c ++++ grub-2.04/grub-core/loader/xnu.c +@@ -800,7 +800,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd _ + if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC) + { + narchs = grub_be_to_cpu32 (head.nfat_arch); +- archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); ++ archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); + if (! archs) + { + grub_file_close (file); +Index: grub-2.04/grub-core/mmap/mmap.c +=================================================================== +--- grub-2.04.orig/grub-core/mmap/mmap.c ++++ grub-2.04/grub-core/mmap/mmap.c +@@ -143,9 +143,9 @@ grub_mmap_iterate (grub_memory_hook_t ho + + /* Initialize variables. */ + ctx.scanline_events = (struct grub_mmap_scan *) +- grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num); ++ grub_calloc (mmap_num, sizeof (struct grub_mmap_scan) * 2); + +- present = grub_zalloc (sizeof (present[0]) * current_priority); ++ present = grub_calloc (current_priority, sizeof (present[0])); + + if (! ctx.scanline_events || !present) + { +Index: grub-2.04/grub-core/net/bootp.c +=================================================================== +--- grub-2.04.orig/grub-core/net/bootp.c ++++ grub-2.04/grub-core/net/bootp.c +@@ -1550,7 +1550,7 @@ grub_cmd_bootp (struct grub_command *cmd + if (ncards == 0) + return grub_error (GRUB_ERR_NET_NO_CARD, N_("no network card found")); + +- ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); ++ ifaces = grub_calloc (ncards, sizeof (ifaces[0])); + if (!ifaces) + return grub_errno; + +Index: grub-2.04/grub-core/net/dns.c +=================================================================== +--- grub-2.04.orig/grub-core/net/dns.c ++++ grub-2.04/grub-core/net/dns.c +@@ -285,8 +285,8 @@ recv_hook (grub_net_udp_socket_t sock __ + ptr++; + ptr += 4; + } +- *data->addresses = grub_malloc (sizeof ((*data->addresses)[0]) +- * grub_be_to_cpu16 (head->ancount)); ++ *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount), ++ sizeof ((*data->addresses)[0])); + if (!*data->addresses) + { + grub_errno = GRUB_ERR_NONE; +@@ -406,8 +406,8 @@ recv_hook (grub_net_udp_socket_t sock __ + dns_cache[h].addresses = 0; + dns_cache[h].name = grub_strdup (data->oname); + dns_cache[h].naddresses = *data->naddresses; +- dns_cache[h].addresses = grub_malloc (*data->naddresses +- * sizeof (dns_cache[h].addresses[0])); ++ dns_cache[h].addresses = grub_calloc (*data->naddresses, ++ sizeof (dns_cache[h].addresses[0])); + dns_cache[h].limit_time = grub_get_time_ms () + 1000 * ttl_all; + if (!dns_cache[h].addresses || !dns_cache[h].name) + { +@@ -479,7 +479,7 @@ grub_net_dns_lookup (const char *name, + } + } + +- sockets = grub_malloc (sizeof (sockets[0]) * n_servers); ++ sockets = grub_calloc (n_servers, sizeof (sockets[0])); + if (!sockets) + return grub_errno; + +Index: grub-2.04/grub-core/net/net.c +=================================================================== +--- grub-2.04.orig/grub-core/net/net.c ++++ grub-2.04/grub-core/net/net.c +@@ -336,8 +336,8 @@ grub_cmd_ipv6_autoconf (struct grub_comm + ncards++; + } + +- ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); +- slaacs = grub_zalloc (ncards * sizeof (slaacs[0])); ++ ifaces = grub_calloc (ncards, sizeof (ifaces[0])); ++ slaacs = grub_calloc (ncards, sizeof (slaacs[0])); + if (!ifaces || !slaacs) + { + grub_free (ifaces); +Index: grub-2.04/grub-core/normal/charset.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/charset.c ++++ grub-2.04/grub-core/normal/charset.c +@@ -203,7 +203,7 @@ grub_utf8_to_ucs4_alloc (const char *msg + { + grub_size_t msg_len = grub_strlen (msg); + +- *unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); ++ *unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); + + if (!*unicode_msg) + return -1; +@@ -488,7 +488,7 @@ grub_unicode_aglomerate_comb (const grub + } + else + { +- n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1)); ++ n = grub_calloc (out->ncomb + 1, sizeof (n[0])); + if (!n) + { + grub_errno = GRUB_ERR_NONE; +@@ -842,7 +842,7 @@ grub_bidi_line_logical_to_visual (const + } \ + } + +- visual = grub_malloc (sizeof (visual[0]) * logical_len); ++ visual = grub_calloc (logical_len, sizeof (visual[0])); + if (!visual) + return -1; + +@@ -1165,8 +1165,8 @@ grub_bidi_logical_to_visual (const grub_ + { + const grub_uint32_t *line_start = logical, *ptr; + struct grub_unicode_glyph *visual_ptr; +- *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) +- * (logical_len + 2)); ++ *visual_out = visual_ptr = grub_calloc (logical_len + 2, ++ 3 * sizeof (visual_ptr[0])); + if (!visual_ptr) + return -1; + for (ptr = logical; ptr <= logical + logical_len; ptr++) +Index: grub-2.04/grub-core/normal/cmdline.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/cmdline.c ++++ grub-2.04/grub-core/normal/cmdline.c +@@ -41,7 +41,7 @@ grub_err_t + grub_set_history (int newsize) + { + grub_uint32_t **old_hist_lines = hist_lines; +- hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize); ++ hist_lines = grub_calloc (newsize, sizeof (grub_uint32_t *)); + + /* Copy the old lines into the new buffer. */ + if (old_hist_lines) +@@ -114,7 +114,7 @@ static void + grub_history_set (int pos, grub_uint32_t *s, grub_size_t len) + { + grub_free (hist_lines[pos]); +- hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t)); ++ hist_lines[pos] = grub_calloc (len + 1, sizeof (grub_uint32_t)); + if (!hist_lines[pos]) + { + grub_print_error (); +@@ -349,7 +349,7 @@ grub_cmdline_get (const char *prompt_tra + char *ret; + unsigned nterms; + +- buf = grub_malloc (max_len * sizeof (grub_uint32_t)); ++ buf = grub_calloc (max_len, sizeof (grub_uint32_t)); + if (!buf) + return 0; + +@@ -377,7 +377,7 @@ grub_cmdline_get (const char *prompt_tra + FOR_ACTIVE_TERM_OUTPUTS(cur) + nterms++; + +- cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms); ++ cl_terms = grub_calloc (nterms, sizeof (cl_terms[0])); + if (!cl_terms) + { + grub_free (buf); +@@ -385,7 +385,7 @@ grub_cmdline_get (const char *prompt_tra + } + cl_term_cur = cl_terms; + +- unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); ++ unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); + if (!unicode_msg) + { + grub_free (buf); +@@ -495,7 +495,7 @@ grub_cmdline_get (const char *prompt_tra + grub_uint32_t *insert; + + insertlen = grub_strlen (insertu8); +- insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t)); ++ insert = grub_calloc (insertlen + 1, sizeof (grub_uint32_t)); + if (!insert) + { + grub_free (insertu8); +@@ -602,7 +602,7 @@ grub_cmdline_get (const char *prompt_tra + + grub_free (kill_buf); + +- kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t)); ++ kill_buf = grub_calloc (n + 1, sizeof (grub_uint32_t)); + if (grub_errno) + { + grub_print_error (); +Index: grub-2.04/grub-core/normal/menu_entry.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/menu_entry.c ++++ grub-2.04/grub-core/normal/menu_entry.c +@@ -95,8 +95,8 @@ init_line (struct screen *screen, struct + { + linep->len = 0; + linep->max_len = 80; +- linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0])); +- linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0])); ++ linep->buf = grub_calloc (linep->max_len + 1, sizeof (linep->buf[0])); ++ linep->pos = grub_calloc (screen->nterms, sizeof (linep->pos[0])); + if (! linep->buf || !linep->pos) + { + grub_free (linep->buf); +@@ -287,7 +287,7 @@ update_screen (struct screen *screen, st + pos = linep->pos + (term_screen - screen->terms); + + if (!*pos) +- *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos)); ++ *pos = grub_calloc (linep->len + 1, sizeof (**pos)); + + if (i == region_start || linep == screen->lines + screen->line + || (i > region_start && mode == ALL_LINES)) +@@ -471,7 +471,7 @@ insert_string (struct screen *screen, co + + /* Insert the string. */ + current_linep = screen->lines + screen->line; +- unicode_msg = grub_malloc ((p - s) * sizeof (grub_uint32_t)); ++ unicode_msg = grub_calloc (p - s, sizeof (grub_uint32_t)); + + if (!unicode_msg) + return 0; +@@ -1023,7 +1023,7 @@ complete (struct screen *screen, int con + if (completion_buffer.buf) + { + buflen = grub_strlen (completion_buffer.buf); +- ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1)); ++ ucs4 = grub_calloc (buflen + 1, sizeof (grub_uint32_t)); + + if (!ucs4) + { +@@ -1268,7 +1268,7 @@ grub_menu_entry_run (grub_menu_entry_t e + for (i = 0; i < (unsigned) screen->num_lines; i++) + { + grub_free (screen->lines[i].pos); +- screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0])); ++ screen->lines[i].pos = grub_calloc (screen->nterms, sizeof (screen->lines[i].pos[0])); + if (! screen->lines[i].pos) + { + grub_print_error (); +@@ -1278,7 +1278,7 @@ grub_menu_entry_run (grub_menu_entry_t e + } + } + +- screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0])); ++ screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0])); + if (!screen->terms) + { + grub_print_error (); +Index: grub-2.04/grub-core/normal/menu_text.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/menu_text.c ++++ grub-2.04/grub-core/normal/menu_text.c +@@ -78,7 +78,7 @@ grub_print_message_indented_real (const + grub_size_t msg_len = grub_strlen (msg) + 2; + int ret = 0; + +- unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); ++ unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); + + if (!unicode_msg) + return 0; +@@ -231,7 +231,7 @@ print_entry (int y, int highlight, grub_ + if ((data->term->flags & GRUB_TERM_DUMB) && title[0] == '\0') + return; + +- unicode_title = grub_malloc (title_len * sizeof (*unicode_title)); ++ unicode_title = grub_calloc (title_len, sizeof (*unicode_title)); + if (! unicode_title) + /* XXX How to show this error? */ + return; +Index: grub-2.04/grub-core/normal/term.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/term.c ++++ grub-2.04/grub-core/normal/term.c +@@ -264,7 +264,7 @@ grub_term_save_pos (void) + FOR_ACTIVE_TERM_OUTPUTS(cur) + cnt++; + +- ret = grub_malloc (cnt * sizeof (ret[0])); ++ ret = grub_calloc (cnt, sizeof (ret[0])); + if (!ret) + return NULL; + +@@ -1013,7 +1013,7 @@ grub_xnputs (const char *str, grub_size_ + + grub_error_push (); + +- unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t)); ++ unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t)); + + grub_error_pop (); + +Index: grub-2.04/grub-core/osdep/linux/getroot.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/linux/getroot.c ++++ grub-2.04/grub-core/osdep/linux/getroot.c +@@ -176,7 +176,7 @@ grub_util_raid_getmembers (const char *n + if (ret != 0) + grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); + +- devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); ++ devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); + + for (i = 0, j = 0; j < info.nr_disks; i++) + { +@@ -249,7 +249,7 @@ grub_find_root_devices_from_btrfs (const + return NULL; + } + +- ret = xmalloc ((fsi.num_devices + 1) * sizeof (ret[0])); ++ ret = xcalloc (fsi.num_devices + 1, sizeof (ret[0])); + + for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++) + { +@@ -508,7 +508,7 @@ grub_find_root_devices_from_mountinfo (c + if (relroot) + *relroot = NULL; + +- entries = xmalloc (entry_max * sizeof (*entries)); ++ entries = xcalloc (entry_max, sizeof (*entries)); + + again: + fp = grub_util_fopen ("/proc/self/mountinfo", "r"); +Index: grub-2.04/grub-core/osdep/unix/config.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/unix/config.c ++++ grub-2.04/grub-core/osdep/unix/config.c +@@ -239,7 +239,7 @@ grub_util_load_config (struct grub_util_ + argv[0] = "sh"; + argv[1] = "-c"; + +- script = xmalloc (4 * strlen (cfgfile) + 300); ++ script = xcalloc (4, strlen (cfgfile) + 300); + + ptr = script; + memcpy (ptr, ". '", 3); +Index: grub-2.04/grub-core/osdep/windows/getroot.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/windows/getroot.c ++++ grub-2.04/grub-core/osdep/windows/getroot.c +@@ -59,7 +59,7 @@ grub_get_mount_point (const TCHAR *path) + + for (ptr = path; *ptr; ptr++); + allocsize = (ptr - path + 10) * 2; +- out = xmalloc (allocsize * sizeof (out[0])); ++ out = xcalloc (allocsize, sizeof (out[0])); + + /* When pointing to EFI system partition GetVolumePathName fails + for ESP root and returns abberant information for everything +Index: grub-2.04/grub-core/osdep/windows/hostdisk.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/windows/hostdisk.c ++++ grub-2.04/grub-core/osdep/windows/hostdisk.c +@@ -111,7 +111,7 @@ grub_util_get_windows_path_real (const c + + while (1) + { +- fpa = xmalloc (alloc * sizeof (fpa[0])); ++ fpa = xcalloc (alloc, sizeof (fpa[0])); + + len = GetFullPathName (tpath, alloc, fpa, NULL); + if (len >= alloc) +@@ -399,7 +399,7 @@ grub_util_fd_opendir (const char *name) + for (l = 0; name_windows[l]; l++); + for (l--; l >= 0 && (name_windows[l] == '\\' || name_windows[l] == '/'); l--); + l++; +- pattern = xmalloc ((l + 3) * sizeof (pattern[0])); ++ pattern = xcalloc (l + 3, sizeof (pattern[0])); + memcpy (pattern, name_windows, l * sizeof (pattern[0])); + pattern[l] = '\\'; + pattern[l + 1] = '*'; +Index: grub-2.04/grub-core/osdep/windows/init.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/windows/init.c ++++ grub-2.04/grub-core/osdep/windows/init.c +@@ -161,7 +161,7 @@ grub_util_host_init (int *argc __attribu + LPWSTR *targv; + + targv = CommandLineToArgvW (tcmdline, argc); +- *argv = xmalloc ((*argc + 1) * sizeof (argv[0])); ++ *argv = xcalloc (*argc + 1, sizeof (argv[0])); + + for (i = 0; i < *argc; i++) + (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]); +Index: grub-2.04/grub-core/osdep/windows/platform.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/windows/platform.c ++++ grub-2.04/grub-core/osdep/windows/platform.c +@@ -225,8 +225,8 @@ grub_install_register_efi (grub_device_t + grub_util_error ("%s", _("no EFI routines are available when running in BIOS mode")); + + distrib8_len = grub_strlen (efi_distributor); +- distributor16 = xmalloc ((distrib8_len + 1) * GRUB_MAX_UTF16_PER_UTF8 +- * sizeof (grub_uint16_t)); ++ distributor16 = xcalloc (distrib8_len + 1, ++ GRUB_MAX_UTF16_PER_UTF8 * sizeof (grub_uint16_t)); + distrib16_len = grub_utf8_to_utf16 (distributor16, distrib8_len * GRUB_MAX_UTF16_PER_UTF8, + (const grub_uint8_t *) efi_distributor, + distrib8_len, 0); +Index: grub-2.04/grub-core/osdep/windows/relpath.c +=================================================================== +--- grub-2.04.orig/grub-core/osdep/windows/relpath.c ++++ grub-2.04/grub-core/osdep/windows/relpath.c +@@ -72,7 +72,7 @@ grub_make_system_path_relative_to_its_ro + if (dirwindows[0] && dirwindows[1] == ':') + offset = 2; + } +- ret = xmalloc (sizeof (ret[0]) * (flen - offset + 2)); ++ ret = xcalloc (flen - offset + 2, sizeof (ret[0])); + if (dirwindows[offset] != '\\' + && dirwindows[offset] != '/' + && dirwindows[offset]) +Index: grub-2.04/grub-core/partmap/gpt.c +=================================================================== +--- grub-2.04.orig/grub-core/partmap/gpt.c ++++ grub-2.04/grub-core/partmap/gpt.c +@@ -199,7 +199,7 @@ gpt_partition_map_embed (struct grub_dis + *nsectors = ctx.len; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +- *sectors = grub_malloc (*nsectors * sizeof (**sectors)); ++ *sectors = grub_calloc (*nsectors, sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +Index: grub-2.04/grub-core/partmap/msdos.c +=================================================================== +--- grub-2.04.orig/grub-core/partmap/msdos.c ++++ grub-2.04/grub-core/partmap/msdos.c +@@ -344,7 +344,7 @@ pc_partition_map_embed (struct grub_disk + avail_nsectors = *nsectors; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +- *sectors = grub_malloc (*nsectors * sizeof (**sectors)); ++ *sectors = grub_calloc (*nsectors, sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +Index: grub-2.04/grub-core/script/execute.c +=================================================================== +--- grub-2.04.orig/grub-core/script/execute.c ++++ grub-2.04/grub-core/script/execute.c +@@ -556,7 +556,7 @@ gettext_append (struct grub_script_argv + for (iptr = orig_str; *iptr; iptr++) + if (*iptr == '$') + dollar_cnt++; +- ctx.allowed_strings = grub_malloc (sizeof (ctx.allowed_strings[0]) * dollar_cnt); ++ ctx.allowed_strings = grub_calloc (dollar_cnt, sizeof (ctx.allowed_strings[0])); + + if (parse_string (orig_str, gettext_save_allow, &ctx, 0)) + goto fail; +Index: grub-2.04/grub-core/tests/fake_input.c +=================================================================== +--- grub-2.04.orig/grub-core/tests/fake_input.c ++++ grub-2.04/grub-core/tests/fake_input.c +@@ -49,7 +49,7 @@ grub_terminal_input_fake_sequence (int * + saved = grub_term_inputs; + if (seq) + grub_free (seq); +- seq = grub_malloc (nseq_in * sizeof (seq[0])); ++ seq = grub_calloc (nseq_in, sizeof (seq[0])); + if (!seq) + return; + +Index: grub-2.04/grub-core/tests/video_checksum.c +=================================================================== +--- grub-2.04.orig/grub-core/tests/video_checksum.c ++++ grub-2.04/grub-core/tests/video_checksum.c +@@ -336,7 +336,7 @@ grub_video_capture_write_bmp (const char + { + case 4: + { +- grub_uint8_t *buffer = xmalloc (mode_info->width * 3); ++ grub_uint8_t *buffer = xcalloc (3, mode_info->width); + grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); +@@ -367,7 +367,7 @@ grub_video_capture_write_bmp (const char + } + case 3: + { +- grub_uint8_t *buffer = xmalloc (mode_info->width * 3); ++ grub_uint8_t *buffer = xcalloc (3, mode_info->width); + grub_uint32_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint32_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint32_t bmask = ((1 << mode_info->blue_mask_size) - 1); +@@ -407,7 +407,7 @@ grub_video_capture_write_bmp (const char + } + case 2: + { +- grub_uint8_t *buffer = xmalloc (mode_info->width * 3); ++ grub_uint8_t *buffer = xcalloc (3, mode_info->width); + grub_uint16_t rmask = ((1 << mode_info->red_mask_size) - 1); + grub_uint16_t gmask = ((1 << mode_info->green_mask_size) - 1); + grub_uint16_t bmask = ((1 << mode_info->blue_mask_size) - 1); +Index: grub-2.04/grub-core/video/capture.c +=================================================================== +--- grub-2.04.orig/grub-core/video/capture.c ++++ grub-2.04/grub-core/video/capture.c +@@ -89,7 +89,7 @@ grub_video_capture_start (const struct g + framebuffer.mode_info = *mode_info; + framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + +- framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch); ++ framebuffer.ptr = grub_calloc (framebuffer.mode_info.height, framebuffer.mode_info.pitch); + if (!framebuffer.ptr) + return grub_errno; + +Index: grub-2.04/grub-core/video/emu/sdl.c +=================================================================== +--- grub-2.04.orig/grub-core/video/emu/sdl.c ++++ grub-2.04/grub-core/video/emu/sdl.c +@@ -172,7 +172,7 @@ grub_video_sdl_set_palette (unsigned int + if (start + count > mode_info.number_of_colors) + count = mode_info.number_of_colors - start; + +- tmp = grub_malloc (count * sizeof (tmp[0])); ++ tmp = grub_calloc (count, sizeof (tmp[0])); + for (i = 0; i < count; i++) + { + tmp[i].r = palette_data[i].r; +Index: grub-2.04/grub-core/video/i386/pc/vga.c +=================================================================== +--- grub-2.04.orig/grub-core/video/i386/pc/vga.c ++++ grub-2.04/grub-core/video/i386/pc/vga.c +@@ -127,7 +127,7 @@ grub_video_vga_setup (unsigned int width + + vga_height = height ? : 480; + +- framebuffer.temporary_buffer = grub_malloc (vga_height * VGA_WIDTH); ++ framebuffer.temporary_buffer = grub_calloc (vga_height, VGA_WIDTH); + framebuffer.front_page = 0; + framebuffer.back_page = 0; + if (!framebuffer.temporary_buffer) +Index: grub-2.04/grub-core/video/readers/png.c +=================================================================== +--- grub-2.04.orig/grub-core/video/readers/png.c ++++ grub-2.04/grub-core/video/readers/png.c +@@ -309,7 +309,7 @@ grub_png_decode_image_header (struct gru + if (data->is_16bit || data->is_gray || data->is_palette) + #endif + { +- data->image_data = grub_malloc (data->image_height * data->row_bytes); ++ data->image_data = grub_calloc (data->image_height, data->row_bytes); + if (grub_errno) + return grub_errno; + +Index: grub-2.04/include/grub/unicode.h +=================================================================== +--- grub-2.04.orig/include/grub/unicode.h ++++ grub-2.04/include/grub/unicode.h +@@ -293,7 +293,7 @@ grub_unicode_glyph_dup (const struct gru + grub_memcpy (out, in, sizeof (*in)); + if (in->ncomb > ARRAY_SIZE (out->combining_inline)) + { +- out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); ++ out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); + if (!out->combining_ptr) + { + grub_free (out); +@@ -315,7 +315,7 @@ grub_unicode_set_glyph (struct grub_unic + grub_memcpy (out, in, sizeof (*in)); + if (in->ncomb > ARRAY_SIZE (out->combining_inline)) + { +- out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); ++ out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); + if (!out->combining_ptr) + return; + grub_memcpy (out->combining_ptr, in->combining_ptr, +Index: grub-2.04/util/getroot.c +=================================================================== +--- grub-2.04.orig/util/getroot.c ++++ grub-2.04/util/getroot.c +@@ -200,7 +200,7 @@ make_device_name (const char *drive) + char *ret, *ptr; + const char *iptr; + +- ret = xmalloc (strlen (drive) * 2); ++ ret = xcalloc (2, strlen (drive)); + ptr = ret; + for (iptr = drive; *iptr; iptr++) + { +Index: grub-2.04/util/grub-file.c +=================================================================== +--- grub-2.04.orig/util/grub-file.c ++++ grub-2.04/util/grub-file.c +@@ -54,7 +54,7 @@ main (int argc, char *argv[]) + + grub_util_host_init (&argc, &argv); + +- argv2 = xmalloc (argc * sizeof (argv2[0])); ++ argv2 = xcalloc (argc, sizeof (argv2[0])); + + if (argc == 2 && strcmp (argv[1], "--version") == 0) + { +Index: grub-2.04/util/grub-fstest.c +=================================================================== +--- grub-2.04.orig/util/grub-fstest.c ++++ grub-2.04/util/grub-fstest.c +@@ -650,7 +650,7 @@ argp_parser (int key, char *arg, struct + if (args_count < num_disks) + { + if (args_count == 0) +- images = xmalloc (num_disks * sizeof (images[0])); ++ images = xcalloc (num_disks, sizeof (images[0])); + images[args_count] = grub_canonicalize_file_name (arg); + args_count++; + return 0; +@@ -734,7 +734,7 @@ main (int argc, char *argv[]) + + grub_util_host_init (&argc, &argv); + +- args = xmalloc (argc * sizeof (args[0])); ++ args = xcalloc (argc, sizeof (args[0])); + + argp_parse (&argp, argc, argv, 0, 0, 0); + +Index: grub-2.04/util/grub-install-common.c +=================================================================== +--- grub-2.04.orig/util/grub-install-common.c ++++ grub-2.04/util/grub-install-common.c +@@ -286,7 +286,7 @@ handle_install_list (struct install_list + il->n_entries++; + } + il->n_alloc = il->n_entries + 1; +- il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); ++ il->entries = xcalloc (il->n_alloc, sizeof (il->entries[0])); + ptr = val; + for (ce = il->entries; ; ce++) + { +Index: grub-2.04/util/grub-install.c +=================================================================== +--- grub-2.04.orig/util/grub-install.c ++++ grub-2.04/util/grub-install.c +@@ -695,7 +695,7 @@ device_map_check_duplicates (const char + if (! fp) + return; + +- d = xmalloc (alloced * sizeof (d[0])); ++ d = xcalloc (alloced, sizeof (d[0])); + + while (fgets (buf, sizeof (buf), fp)) + { +@@ -1322,7 +1322,7 @@ main (int argc, char *argv[]) + ndev++; + } + +- grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); ++ grub_drives = xcalloc (ndev + 1, sizeof (grub_drives[0])); + + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) +Index: grub-2.04/util/grub-mkimagexx.c +=================================================================== +--- grub-2.04.orig/util/grub-mkimagexx.c ++++ grub-2.04/util/grub-mkimagexx.c +@@ -2294,10 +2294,8 @@ SUFFIX (grub_mkimage_load_image) (const + + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); + smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); + +- smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); +- memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); +- smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); +- memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); ++ smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs)); ++ smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs)); + + SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); + +Index: grub-2.04/util/grub-mkrescue.c +=================================================================== +--- grub-2.04.orig/util/grub-mkrescue.c ++++ grub-2.04/util/grub-mkrescue.c +@@ -441,8 +441,8 @@ main (int argc, char *argv[]) + xorriso = xstrdup ("xorriso"); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + +- argp_argv = xmalloc (sizeof (argp_argv[0]) * argc); +- xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc); ++ argp_argv = xcalloc (argc, sizeof (argp_argv[0])); ++ xorriso_tail_argv = xcalloc (argc, sizeof (argp_argv[0])); + + xorriso_tail_argc = 0; + /* Program name */ +Index: grub-2.04/util/grub-mkstandalone.c +=================================================================== +--- grub-2.04.orig/util/grub-mkstandalone.c ++++ grub-2.04/util/grub-mkstandalone.c +@@ -296,7 +296,7 @@ main (int argc, char *argv[]) + grub_util_host_init (&argc, &argv); + grub_util_disable_fd_syncs (); + +- files = xmalloc ((argc + 1) * sizeof (files[0])); ++ files = xcalloc (argc + 1, sizeof (files[0])); + + argp_parse (&argp, argc, argv, 0, 0, 0); + +Index: grub-2.04/util/grub-pe2elf.c +=================================================================== +--- grub-2.04.orig/util/grub-pe2elf.c ++++ grub-2.04/util/grub-pe2elf.c +@@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char + char *pe_strtab = (image + pe_chdr->symtab_offset + + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol)); + +- section_map = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (int)); ++ section_map = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (int)); + section_map[0] = 0; +- shdr = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (shdr[0])); ++ shdr = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (shdr[0])); + idx = 1; + idx_reloc = pe_chdr->num_sections + 1; + +@@ -233,7 +233,7 @@ write_reloc_section (FILE* fp, const cha + + pe_sec = pe_shdr + shdr[i].sh_link; + pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset); +- rel = (elf_reloc_t *) xmalloc (pe_sec->num_relocations * sizeof (elf_reloc_t)); ++ rel = (elf_reloc_t *) xcalloc (pe_sec->num_relocations, sizeof (elf_reloc_t)); + num_rels = 0; + modified = 0; + +@@ -365,12 +365,10 @@ write_symbol_table (FILE* fp, const char + pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset); + pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols); + +- symtab = (Elf_Sym *) xmalloc ((pe_chdr->num_symbols + 1) * +- sizeof (Elf_Sym)); +- memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf_Sym)); ++ symtab = (Elf_Sym *) xcalloc (pe_chdr->num_symbols + 1, sizeof (Elf_Sym)); + num_syms = 1; + +- symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int)); ++ symtab_map = (int *) xcalloc (pe_chdr->num_symbols, sizeof (int)); + + for (i = 0; i < (int) pe_chdr->num_symbols; + i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1) +Index: grub-2.04/util/grub-probe.c +=================================================================== +--- grub-2.04.orig/util/grub-probe.c ++++ grub-2.04/util/grub-probe.c +@@ -361,8 +361,8 @@ probe (const char *path, char **device_n + grub_util_pull_device (*curdev); + ndev++; + } +- +- drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); ++ ++ drives_names = xcalloc (ndev + 1, sizeof (drives_names[0])); + + for (curdev = device_names, curdrive = drives_names; *curdev; curdev++, + curdrive++) diff --git a/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch b/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch new file mode 100644 index 0000000..910536d --- /dev/null +++ b/0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch @@ -0,0 +1,1319 @@ +From 790790798e8f0862d5ee64440acd424716030c86 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Jun 2020 12:28:27 -0400 +Subject: [PATCH 5/7] malloc: Use overflow checking primitives where we do + complex allocations + +This attempts to fix the places where we do the following where +arithmetic_expr may include unvalidated data: + + X = grub_malloc(arithmetic_expr); + +It accomplishes this by doing the arithmetic ahead of time using grub_add(), +grub_sub(), grub_mul() and testing for overflow before proceeding. + +Among other issues, this fixes: + - allocation of integer overflow in grub_video_bitmap_create() + reported by Chris Coulson, + - allocation of integer overflow in grub_png_decode_image_header() + reported by Chris Coulson, + - allocation of integer overflow in grub_squash_read_symlink() + reported by Chris Coulson, + - allocation of integer overflow in grub_ext2_read_symlink() + reported by Chris Coulson, + - allocation of integer overflow in read_section_as_string() + reported by Chris Coulson. + +Fixes: CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + grub-core/commands/legacycfg.c | 29 +++++++++++++++---- + grub-core/commands/wildcard.c | 36 ++++++++++++++++++++---- + grub-core/disk/ldm.c | 32 +++++++++++++++------ + grub-core/font/font.c | 7 ++++- + grub-core/fs/btrfs.c | 28 +++++++++++++------ + grub-core/fs/ext2.c | 10 ++++++- + grub-core/fs/iso9660.c | 51 ++++++++++++++++++++++++---------- + grub-core/fs/sfs.c | 27 ++++++++++++++---- + grub-core/fs/squash4.c | 45 ++++++++++++++++++++++-------- + grub-core/fs/udf.c | 41 +++++++++++++++++---------- + grub-core/fs/xfs.c | 11 +++++--- + grub-core/fs/zfs/zfs.c | 22 ++++++++++----- + grub-core/fs/zfs/zfscrypt.c | 7 ++++- + grub-core/lib/arg.c | 20 +++++++++++-- + grub-core/loader/i386/bsd.c | 8 +++++- + grub-core/net/dns.c | 9 +++++- + grub-core/normal/charset.c | 10 +++++-- + grub-core/normal/cmdline.c | 14 ++++++++-- + grub-core/normal/menu_entry.c | 13 +++++++-- + grub-core/script/argv.c | 16 +++++++++-- + grub-core/script/lexer.c | 21 ++++++++++++-- + grub-core/video/bitmap.c | 25 +++++++++++------ + grub-core/video/readers/png.c | 13 +++++++-- + 23 files changed, 382 insertions(+), 113 deletions(-) + +Index: grub-2.04/grub-core/commands/legacycfg.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/legacycfg.c ++++ grub-2.04/grub-core/commands/legacycfg.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -104,13 +105,22 @@ legacy_file (const char *filename) + if (newsuffix) + { + char *t; +- ++ grub_size_t sz; ++ ++ if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) || ++ grub_add (sz, 1, &sz)) ++ { ++ grub_errno = GRUB_ERR_OUT_OF_RANGE; ++ goto fail_0; ++ } ++ + t = suffix; +- suffix = grub_realloc (suffix, grub_strlen (suffix) +- + grub_strlen (newsuffix) + 1); ++ suffix = grub_realloc (suffix, sz); + if (!suffix) + { + grub_free (t); ++ ++ fail_0: + grub_free (entrysrc); + grub_free (parsed); + grub_free (newsuffix); +@@ -154,13 +164,22 @@ legacy_file (const char *filename) + else + { + char *t; ++ grub_size_t sz; ++ ++ if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) || ++ grub_add (sz, 1, &sz)) ++ { ++ grub_errno = GRUB_ERR_OUT_OF_RANGE; ++ goto fail_1; ++ } + + t = entrysrc; +- entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) +- + grub_strlen (parsed) + 1); ++ entrysrc = grub_realloc (entrysrc, sz); + if (!entrysrc) + { + grub_free (t); ++ ++ fail_1: + grub_free (parsed); + grub_free (suffix); + return grub_errno; +Index: grub-2.04/grub-core/commands/wildcard.c +=================================================================== +--- grub-2.04.orig/grub-core/commands/wildcard.c ++++ grub-2.04/grub-core/commands/wildcard.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include + +@@ -48,6 +49,7 @@ merge (char **dest, char **ps) + int i; + int j; + char **p; ++ grub_size_t sz; + + if (! dest) + return ps; +@@ -60,7 +62,12 @@ merge (char **dest, char **ps) + for (j = 0; ps[j]; j++) + ; + +- p = grub_realloc (dest, sizeof (char*) * (i + j + 1)); ++ if (grub_add (i, j, &sz) || ++ grub_add (sz, 1, &sz) || ++ grub_mul (sz, sizeof (char *), &sz)) ++ return dest; ++ ++ p = grub_realloc (dest, sz); + if (! p) + { + grub_free (dest); +@@ -115,8 +122,15 @@ make_regex (const char *start, const cha + char ch; + int i = 0; + unsigned len = end - start; +- char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */ ++ char *buffer; ++ grub_size_t sz; + ++ /* Worst case size is (len * 2 + 2 + 1). */ ++ if (grub_mul (len, 2, &sz) || ++ grub_add (sz, 3, &sz)) ++ return 1; ++ ++ buffer = grub_malloc (sz); + if (! buffer) + return 1; + +@@ -226,6 +240,7 @@ match_devices_iter (const char *name, vo + struct match_devices_ctx *ctx = data; + char **t; + char *buffer; ++ grub_size_t sz; + + /* skip partitions if asked to. */ + if (ctx->noparts && grub_strchr (name, ',')) +@@ -239,11 +254,16 @@ match_devices_iter (const char *name, vo + if (regexec (ctx->regexp, buffer, 0, 0, 0)) + { + grub_dprintf ("expand", "not matched\n"); ++ fail: + grub_free (buffer); + return 0; + } + +- t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); ++ if (grub_add (ctx->ndev, 2, &sz) || ++ grub_mul (sz, sizeof (char *), &sz)) ++ goto fail; ++ ++ t = grub_realloc (ctx->devs, sz); + if (! t) + { + grub_free (buffer); +@@ -300,6 +320,7 @@ match_files_iter (const char *name, + struct match_files_ctx *ctx = data; + char **t; + char *buffer; ++ grub_size_t sz; + + /* skip . and .. names */ + if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) +@@ -315,9 +336,14 @@ match_files_iter (const char *name, + if (! buffer) + return 1; + +- t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2)); +- if (! t) ++ if (grub_add (ctx->nfile, 2, &sz) || ++ grub_mul (sz, sizeof (char *), &sz)) ++ goto fail; ++ ++ t = grub_realloc (ctx->files, sz); ++ if (!t) + { ++ fail: + grub_free (buffer); + return 1; + } +Index: grub-2.04/grub-core/disk/ldm.c +=================================================================== +--- grub-2.04.orig/grub-core/disk/ldm.c ++++ grub-2.04/grub-core/disk/ldm.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #ifdef GRUB_UTIL + #include +@@ -289,6 +290,7 @@ make_vg (grub_disk_t disk, + struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE + / sizeof (struct grub_ldm_vblk)]; + unsigned i; ++ grub_size_t sz; + err = grub_disk_read (disk, cursec, 0, + sizeof(vblk), &vblk); + if (err) +@@ -350,7 +352,13 @@ make_vg (grub_disk_t disk, + grub_free (lv); + goto fail2; + } +- lv->name = grub_malloc (*ptr + 1); ++ if (grub_add (*ptr, 1, &sz)) ++ { ++ grub_free (lv->internal_id); ++ grub_free (lv); ++ goto fail2; ++ } ++ lv->name = grub_malloc (sz); + if (!lv->name) + { + grub_free (lv->internal_id); +@@ -599,10 +607,13 @@ make_vg (grub_disk_t disk, + if (lv->segments->node_alloc == lv->segments->node_count) + { + void *t; +- lv->segments->node_alloc *= 2; +- t = grub_realloc (lv->segments->nodes, +- sizeof (*lv->segments->nodes) +- * lv->segments->node_alloc); ++ grub_size_t sz; ++ ++ if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || ++ grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) ++ goto fail2; ++ ++ t = grub_realloc (lv->segments->nodes, sz); + if (!t) + goto fail2; + lv->segments->nodes = t; +@@ -723,10 +734,13 @@ make_vg (grub_disk_t disk, + if (comp->segment_alloc == comp->segment_count) + { + void *t; +- comp->segment_alloc *= 2; +- t = grub_realloc (comp->segments, +- comp->segment_alloc +- * sizeof (*comp->segments)); ++ grub_size_t sz; ++ ++ if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) || ++ grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz)) ++ goto fail2; ++ ++ t = grub_realloc (comp->segments, sz); + if (!t) + goto fail2; + comp->segments = t; +Index: grub-2.04/grub-core/font/font.c +=================================================================== +--- grub-2.04.orig/grub-core/font/font.c ++++ grub-2.04/grub-core/font/font.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -360,9 +361,13 @@ static char * + read_section_as_string (struct font_file_section *section) + { + char *str; ++ grub_size_t sz; + grub_ssize_t ret; + +- str = grub_malloc (section->length + 1); ++ if (grub_add (section->length, 1, &sz)) ++ return NULL; ++ ++ str = grub_malloc (sz); + if (!str) + return 0; + +Index: grub-2.04/grub-core/fs/btrfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/btrfs.c ++++ grub-2.04/grub-core/fs/btrfs.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -366,9 +367,13 @@ save_ref (struct grub_btrfs_leaf_descrip + if (desc->allocated < desc->depth) + { + void *newdata; +- desc->allocated *= 2; +- newdata = grub_realloc (desc->data, sizeof (desc->data[0]) +- * desc->allocated); ++ grub_size_t sz; ++ ++ if (grub_mul (desc->allocated, 2, &desc->allocated) || ++ grub_mul (desc->allocated, sizeof (desc->data[0]), &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ newdata = grub_realloc (desc->data, sz); + if (!newdata) + return grub_errno; + desc->data = newdata; +@@ -659,16 +664,21 @@ find_device (struct grub_btrfs_data *dat + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; +- data->n_devices_allocated = 2 * data->n_devices_attached + 1; +- data->devices_attached +- = grub_realloc (tmp = data->devices_attached, +- data->n_devices_allocated +- * sizeof (data->devices_attached[0])); ++ grub_size_t sz; ++ ++ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || ++ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || ++ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) ++ goto fail; ++ ++ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); + if (!data->devices_attached) + { ++ data->devices_attached = tmp; ++ ++ fail: + if (ctx.dev_found) + grub_device_close (ctx.dev_found); +- data->devices_attached = tmp; + return NULL; + } + } +Index: grub-2.04/grub-core/fs/ext2.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/ext2.c ++++ grub-2.04/grub-core/fs/ext2.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node + { + char *symlink; + struct grub_fshelp_node *diro = node; ++ grub_size_t sz; + + if (! diro->inode_read) + { +@@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node + } + } + +- symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); ++ if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ ++ symlink = grub_malloc (sz); + if (! symlink) + return 0; + +Index: grub-2.04/grub-core/fs/iso9660.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/iso9660.c ++++ grub-2.04/grub-core/fs/iso9660.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx, + int len2) + { + int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; ++ grub_size_t sz; + +- ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); ++ if (grub_add (size, len2, &sz) || ++ grub_add (sz, 1, &sz)) ++ return; ++ ++ ctx->symlink = grub_realloc (ctx->symlink, sz); + if (! ctx->symlink) + return; + +@@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_su + { + grub_size_t off = 0, csize = 1; + char *old; ++ grub_size_t sz; ++ + csize = entry->len - 5; + old = ctx->filename; + if (ctx->filename_alloc) + { + off = grub_strlen (ctx->filename); +- ctx->filename = grub_realloc (ctx->filename, csize + off + 1); ++ if (grub_add (csize, off, &sz) || ++ grub_add (sz, 1, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ctx->filename = grub_realloc (ctx->filename, sz); + } + else + { + off = 0; +- ctx->filename = grub_zalloc (csize + 1); ++ if (grub_add (csize, 1, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ctx->filename = grub_zalloc (sz); + } + if (!ctx->filename) + { +@@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_no + if (node->have_dirents >= node->alloc_dirents) + { + struct grub_fshelp_node *new_node; +- node->alloc_dirents *= 2; +- new_node = grub_realloc (node, +- sizeof (struct grub_fshelp_node) +- + ((node->alloc_dirents +- - ARRAY_SIZE (node->dirents)) +- * sizeof (node->dirents[0]))); ++ grub_size_t sz; ++ ++ if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) || ++ grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || ++ grub_mul (sz, sizeof (node->dirents[0]), &sz) || ++ grub_add (sz, sizeof (struct grub_fshelp_node), &sz)) ++ goto fail_0; ++ ++ new_node = grub_realloc (node, sz); + if (!new_node) + { ++ fail_0: + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); +@@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_no + * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) + { + struct grub_fshelp_node *new_node; +- new_node = grub_realloc (node, +- sizeof (struct grub_fshelp_node) +- + ((node->alloc_dirents +- - ARRAY_SIZE (node->dirents)) +- * sizeof (node->dirents[0])) +- + grub_strlen (ctx.symlink) + 1); ++ grub_size_t sz; ++ ++ if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) || ++ grub_mul (sz, sizeof (node->dirents[0]), &sz) || ++ grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) || ++ grub_add (sz, grub_strlen (ctx.symlink), &sz)) ++ goto fail_1; ++ ++ new_node = grub_realloc (node, sz); + if (!new_node) + { ++ fail_1: + if (ctx.filename_alloc) + grub_free (ctx.filename); + grub_free (node); +Index: grub-2.04/grub-core/fs/sfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/sfs.c ++++ grub-2.04/grub-core/fs/sfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t + if (node->cache && node->cache_size >= node->cache_allocated) + { + struct cache_entry *e = node->cache; +- e = grub_realloc (node->cache,node->cache_allocated * 2 +- * sizeof (e[0])); ++ grub_size_t sz; ++ ++ if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz)) ++ goto fail; ++ ++ e = grub_realloc (node->cache, sz); + if (!e) + { ++ fail: + grub_errno = 0; + grub_free (node->cache); + node->cache = 0; +@@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp + grub_size_t len = grub_strlen (name); + grub_uint8_t *name_u8; + int ret; ++ grub_size_t sz; ++ ++ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || ++ grub_add (sz, 1, &sz)) ++ return 1; ++ + *node = grub_malloc (sizeof (**node)); + if (!*node) + return 1; +- name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); ++ name_u8 = grub_malloc (sz); + if (!name_u8) + { + grub_free (*node); +@@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, ch + data = grub_sfs_mount (disk); + if (data) + { +- grub_size_t len = grub_strlen (data->label); +- *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); ++ grub_size_t sz, len = grub_strlen (data->label); ++ ++ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) || ++ grub_add (sz, 1, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ *label = grub_malloc (sz); + if (*label) + *grub_latin1_to_utf8 ((grub_uint8_t *) *label, + (const grub_uint8_t *) data->label, +Index: grub-2.04/grub-core/fs/squash4.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/squash4.c ++++ grub-2.04/grub-core/fs/squash4.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + #include "xz.h" +@@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_no + { + char *ret; + grub_err_t err; +- ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); ++ grub_size_t sz; ++ ++ if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ ++ ret = grub_malloc (sz); ++ if (!ret) ++ return NULL; + + err = read_chunk (node->data, ret, + grub_le_to_cpu32 (node->ino.symlink.namelen), +@@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_nod + + { + grub_fshelp_node_t node; +- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); ++ grub_size_t sz; ++ ++ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || ++ grub_add (sz, sizeof (*node), &sz)) ++ return 0; ++ ++ node = grub_malloc (sz); + if (!node) + return 0; +- grub_memcpy (node, dir, +- sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); ++ grub_memcpy (node, dir, sz); + if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + +@@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_nod + { + grub_err_t err; + +- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); ++ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) || ++ grub_add (sz, sizeof (*node), &sz)) ++ return 0; ++ ++ node = grub_malloc (sz); + if (!node) + return 0; + +- grub_memcpy (node, dir, +- sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); ++ grub_memcpy (node, dir, sz); + + node->stsize--; + err = read_chunk (dir->data, &node->ino, sizeof (node->ino), +@@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_nod + enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG; + struct grub_squash_dirent di; + struct grub_squash_inode ino; ++ grub_size_t sz; + + err = read_chunk (dir->data, &di, sizeof (di), + grub_le_to_cpu64 (dir->data->sb.diroffset) +@@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_nod + if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) + filetype = GRUB_FSHELP_SYMLINK; + +- node = grub_malloc (sizeof (*node) +- + (dir->stsize + 1) * sizeof (dir->stack[0])); ++ if (grub_add (dir->stsize, 1, &sz) || ++ grub_mul (sz, sizeof (dir->stack[0]), &sz) || ++ grub_add (sz, sizeof (*node), &sz)) ++ return 0; ++ ++ node = grub_malloc (sz); + if (! node) + return 0; + +- grub_memcpy (node, dir, +- sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); ++ grub_memcpy (node, dir, sz - sizeof(dir->stack[0])); + + node->ino = ino; + node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); +Index: grub-2.04/grub-core/fs/udf.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/udf.c ++++ grub-2.04/grub-core/fs/udf.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, gr + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + if (!outbuf) +- outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); ++ { ++ grub_size_t size; ++ ++ if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) || ++ grub_add (size, 1, &size)) ++ goto fail; ++ ++ outbuf = grub_malloc (size); ++ } + if (outbuf) + *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; ++ ++ fail: + grub_free (utf16); + return outbuf; + } +@@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_ + grub_size_t sz = U64 (node->block.fe.file_size); + grub_uint8_t *raw; + const grub_uint8_t *ptr; +- char *out, *optr; ++ char *out = NULL, *optr; + + if (sz < 4) + return NULL; +@@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_ + if (!raw) + return NULL; + if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) +- { +- grub_free (raw); +- return NULL; +- } ++ goto fail_1; + +- out = grub_malloc (sz * 2 + 1); ++ if (grub_mul (sz, 2, &sz) || ++ grub_add (sz, 1, &sz)) ++ goto fail_0; ++ ++ out = grub_malloc (sz); + if (!out) + { ++ fail_0: + grub_free (raw); + return NULL; + } +@@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_ + { + grub_size_t s; + if ((grub_size_t) (ptr - raw + 4) > sz) +- goto fail; ++ goto fail_1; + if (!(ptr[2] == 0 && ptr[3] == 0)) +- goto fail; ++ goto fail_1; + s = 4 + ptr[1]; + if ((grub_size_t) (ptr - raw + s) > sz) +- goto fail; ++ goto fail_1; + switch (*ptr) + { + case 1: + if (ptr[1]) +- goto fail; ++ goto fail_1; + /* Fallthrough. */ + case 2: + /* in 4 bytes. out: 1 byte. */ +@@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_ + if (optr != out) + *optr++ = '/'; + if (!read_string (ptr + 4, s - 4, optr)) +- goto fail; ++ goto fail_1; + optr += grub_strlen (optr); + break; + default: +- goto fail; ++ goto fail_1; + } + ptr += s; + } +@@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_ + grub_free (raw); + return out; + +- fail: ++ fail_1: + grub_free (raw); + grub_free (out); + grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); +Index: grub-2.04/grub-core/fs/xfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/xfs.c ++++ grub-2.04/grub-core/fs/xfs.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -899,6 +900,7 @@ static struct grub_xfs_data * + grub_xfs_mount (grub_disk_t disk) + { + struct grub_xfs_data *data = 0; ++ grub_size_t sz; + + data = grub_zalloc (sizeof (struct grub_xfs_data)); + if (!data) +@@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk) + if (!grub_xfs_sb_valid(data)) + goto fail; + +- data = grub_realloc (data, +- sizeof (struct grub_xfs_data) +- - sizeof (struct grub_xfs_inode) +- + grub_xfs_inode_size(data) + 1); ++ if (grub_add (grub_xfs_inode_size (data), ++ sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz)) ++ goto fail; ++ ++ data = grub_realloc (data, sz); + + if (! data) + goto fail; +Index: grub-2.04/grub-core/fs/zfs/zfs.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/zfs/zfs.c ++++ grub-2.04/grub-core/fs/zfs/zfs.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -776,11 +777,14 @@ fill_vdev_info (struct grub_zfs_data *da + if (data->n_devices_attached > data->n_devices_allocated) + { + void *tmp; +- data->n_devices_allocated = 2 * data->n_devices_attached + 1; +- data->devices_attached +- = grub_realloc (tmp = data->devices_attached, +- data->n_devices_allocated +- * sizeof (data->devices_attached[0])); ++ grub_size_t sz; ++ ++ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || ++ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || ++ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); + if (!data->devices_attached) + { + data->devices_attached = tmp; +@@ -3471,14 +3475,18 @@ grub_zfs_nvlist_lookup_nvlist (const cha + { + char *nvpair; + char *ret; +- grub_size_t size; ++ grub_size_t size, sz; + int found; + + found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, + &size, 0); + if (!found) + return 0; +- ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); ++ ++ if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz)) ++ return 0; ++ ++ ret = grub_zalloc (sz); + if (!ret) + return 0; + grub_memcpy (ret, nvlist, sizeof (grub_uint32_t)); +Index: grub-2.04/grub-core/fs/zfs/zfscrypt.c +=================================================================== +--- grub-2.04.orig/grub-core/fs/zfs/zfscrypt.c ++++ grub-2.04/grub-core/fs/zfs/zfscrypt.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in, + int passphrase) + { + struct grub_zfs_wrap_key *key; ++ grub_size_t sz; ++ + if (!passphrase && keylen > 32) + keylen = 32; +- key = grub_malloc (sizeof (*key) + keylen); ++ if (grub_add (sizeof (*key), keylen, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ key = grub_malloc (sz); + if (!key) + return grub_errno; + key->is_passphrase = passphrase; +Index: grub-2.04/grub-core/lib/arg.c +=================================================================== +--- grub-2.04.orig/grub-core/lib/arg.c ++++ grub-2.04/grub-core/lib/arg.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + /* Built-in parser for default options. */ + static const struct grub_arg_option help_options[] = +@@ -216,7 +217,13 @@ static inline grub_err_t + add_arg (char ***argl, int *num, char *s) + { + char **p = *argl; +- *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *)); ++ grub_size_t sz; ++ ++ if (grub_add (++(*num), 1, &sz) || ++ grub_mul (sz, sizeof (char *), &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ *argl = grub_realloc (*argl, sz); + if (! *argl) + { + grub_free (p); +@@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd + grub_size_t argcnt; + struct grub_arg_list *list; + const struct grub_arg_option *options; ++ grub_size_t sz0, sz1; + + options = extcmd->options; + if (! options) +@@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd + argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ + } + +- list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt); ++ if (grub_mul (sizeof (*list), i, &sz0) || ++ grub_mul (sizeof (char *), argcnt, &sz1) || ++ grub_add (sz0, sz1, &sz0)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return 0; ++ } ++ ++ list = grub_zalloc (sz0); + if (! list) + return 0; + +Index: grub-2.04/grub-core/loader/i386/bsd.c +=================================================================== +--- grub-2.04.orig/grub-core/loader/i386/bsd.c ++++ grub-2.04/grub-core/loader/i386/bsd.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include + #ifdef GRUB_MACHINE_PCBIOS + #include +@@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void) + struct grub_netbsd_btinfo_modules *mods; + unsigned i; + grub_err_t err; ++ grub_size_t sz; + + for (mod = netbsd_mods; mod; mod = mod->next) + modcnt++; + +- mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); ++ if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) || ++ grub_add (sz, sizeof (*mods), &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ mods = grub_malloc (sz); + if (!mods) + return grub_errno; + +Index: grub-2.04/grub-core/net/dns.c +=================================================================== +--- grub-2.04.orig/grub-core/net/dns.c ++++ grub-2.04/grub-core/net/dns.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + struct dns_cache_element + { +@@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct gr + { + int na = dns_servers_alloc * 2; + struct grub_net_network_level_address *ns; ++ grub_size_t sz; ++ + if (na < 8) + na = 8; +- ns = grub_realloc (dns_servers, na * sizeof (ns[0])); ++ ++ if (grub_mul (na, sizeof (ns[0]), &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ ns = grub_realloc (dns_servers, sz); + if (!ns) + return grub_errno; + dns_servers_alloc = na; +Index: grub-2.04/grub-core/normal/charset.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/charset.c ++++ grub-2.04/grub-core/normal/charset.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #if HAVE_FONT_SOURCE + #include "widthspec.h" +@@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub + { + struct grub_unicode_combining *n; + unsigned j; ++ grub_size_t sz; + + if (!haveout) + continue; +@@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub + n = out->combining_inline; + else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) + { +- n = grub_realloc (out->combining_ptr, +- sizeof (n[0]) * (out->ncomb + 1)); ++ if (grub_add (out->ncomb, 1, &sz) || ++ grub_mul (sz, sizeof (n[0]), &sz)) ++ goto fail; ++ ++ n = grub_realloc (out->combining_ptr, sz); + if (!n) + { ++ fail: + grub_errno = GRUB_ERR_NONE; + continue; + } +Index: grub-2.04/grub-core/normal/cmdline.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/cmdline.c ++++ grub-2.04/grub-core/normal/cmdline.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + static grub_uint32_t *kill_buf; + +@@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms + if (len + (*llen) >= (*max_len)) + { + grub_uint32_t *nbuf; +- (*max_len) *= 2; +- nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len)); ++ grub_size_t sz; ++ ++ if (grub_mul (*max_len, 2, max_len) || ++ grub_mul (*max_len, sizeof (grub_uint32_t), &sz)) ++ { ++ grub_errno = GRUB_ERR_OUT_OF_RANGE; ++ goto fail; ++ } ++ ++ nbuf = grub_realloc ((*buf), sz); + if (nbuf) + (*buf) = nbuf; + else + { ++ fail: + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + (*max_len) /= 2; +Index: grub-2.04/grub-core/normal/menu_entry.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/menu_entry.c ++++ grub-2.04/grub-core/normal/menu_entry.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + enum update_mode + { +@@ -113,10 +114,18 @@ ensure_space (struct line *linep, int ex + { + if (linep->max_len < linep->len + extra) + { +- linep->max_len = 2 * (linep->len + extra); +- linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0])); ++ grub_size_t sz0, sz1; ++ ++ if (grub_add (linep->len, extra, &sz0) || ++ grub_mul (sz0, 2, &sz0) || ++ grub_add (sz0, 1, &sz1) || ++ grub_mul (sz1, sizeof (linep->buf[0]), &sz1)) ++ return 0; ++ ++ linep->buf = grub_realloc (linep->buf, sz1); + if (! linep->buf) + return 0; ++ linep->max_len = sz0; + } + + return 1; +Index: grub-2.04/grub-core/script/argv.c +=================================================================== +--- grub-2.04.orig/grub-core/script/argv.c ++++ grub-2.04/grub-core/script/argv.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* Return nearest power of two that is >= v. */ + static unsigned +@@ -81,11 +82,16 @@ int + grub_script_argv_next (struct grub_script_argv *argv) + { + char **p = argv->args; ++ grub_size_t sz; + + if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0) + return 0; + +- p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); ++ if (grub_add (argv->argc, 2, &sz) || ++ grub_mul (sz, sizeof (char *), &sz)) ++ return 1; ++ ++ p = grub_realloc (p, round_up_exp (sz)); + if (! p) + return 1; + +@@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_scr + { + grub_size_t a; + char *p = argv->args[argv->argc - 1]; ++ grub_size_t sz; + + if (! s) + return 0; + + a = p ? grub_strlen (p) : 0; + +- p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); ++ if (grub_add (a, slen, &sz) || ++ grub_add (sz, 1, &sz) || ++ grub_mul (sz, sizeof (char), &sz)) ++ return 1; ++ ++ p = grub_realloc (p, round_up_exp (sz)); + if (! p) + return 1; + +Index: grub-2.04/grub-core/script/lexer.c +=================================================================== +--- grub-2.04.orig/grub-core/script/lexer.c ++++ grub-2.04/grub-core/script/lexer.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define yytext_ptr char * + #include "grub_script.tab.h" +@@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_pa + old = lexer->recording; + if (lexer->recordlen < len) + lexer->recordlen = len; +- lexer->recordlen *= 2; ++ ++ if (grub_mul (lexer->recordlen, 2, &lexer->recordlen)) ++ goto fail; ++ + lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); + if (!lexer->recording) + { ++ fail: + grub_free (old); + lexer->recordpos = 0; + lexer->recordlen = 0; +@@ -130,7 +135,7 @@ int + grub_script_lexer_yywrap (struct grub_parser_param *parserstate, + const char *input) + { +- grub_size_t len = 0; ++ grub_size_t len = 0, sz; + char *p = 0; + char *line = 0; + YY_BUFFER_STATE buffer; +@@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_pa + } + else if (len && line[len - 1] != '\n') + { +- p = grub_realloc (line, len + 2); ++ if (grub_add (len, 2, &sz)) ++ { ++ grub_free (line); ++ grub_script_yyerror (parserstate, N_("overflow is detected")); ++ return 1; ++ } ++ ++ p = grub_realloc (line, sz); + if (p) + { + p[len++] = '\n'; + p[len] = '\0'; + } ++ else ++ grub_free (line); ++ + line = p; + } + +Index: grub-2.04/grub-core/video/bitmap.c +=================================================================== +--- grub-2.04.orig/grub-core/video/bitmap.c ++++ grub-2.04/grub-core/video/bitmap.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_vi + enum grub_video_blit_format blit_format) + { + struct grub_video_mode_info *mode_info; +- unsigned int size; ++ grub_size_t size; + + if (!bitmap) + return grub_error (GRUB_ERR_BUG, "invalid argument"); +@@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_vi + + mode_info->pitch = width * mode_info->bytes_per_pixel; + +- /* Calculate size needed for the data. */ +- size = (width * mode_info->bytes_per_pixel) * height; ++ /* Calculate size needed for the data. */ ++ if (grub_mul (width, mode_info->bytes_per_pixel, &size) || ++ grub_mul (size, height, &size)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ goto fail; ++ } + + (*bitmap)->data = grub_zalloc (size); + if (! (*bitmap)->data) +- { +- grub_free (*bitmap); +- *bitmap = 0; +- +- return grub_errno; +- } ++ goto fail; + + return GRUB_ERR_NONE; ++ ++ fail: ++ grub_free (*bitmap); ++ *bitmap = NULL; ++ ++ return grub_errno; + } + + /* Frees all resources allocated by bitmap. */ +Index: grub-2.04/grub-core/video/readers/png.c +=================================================================== +--- grub-2.04.orig/grub-core/video/readers/png.c ++++ grub-2.04/grub-core/video/readers/png.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -301,9 +302,17 @@ grub_png_decode_image_header (struct gru + data->bpp <<= 1; + + data->color_bits = color_bits; +- data->row_bytes = data->image_width * data->bpp; ++ ++ if (grub_mul (data->image_width, data->bpp, &data->row_bytes)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ + if (data->color_bits <= 4) +- data->row_bytes = (data->image_width * data->color_bits + 7) / 8; ++ { ++ if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ data->row_bytes >>= 3; ++ } + + #ifndef GRUB_CPU_WORDS_BIGENDIAN + if (data->is_16bit || data->is_gray || data->is_palette) diff --git a/0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch b/0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch new file mode 100644 index 0000000..dc1f5e4 --- /dev/null +++ b/0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch @@ -0,0 +1,67 @@ +From 30508bd4692d2e022eff2e7f9c4be9f8abf57977 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Sat, 4 Jul 2020 12:25:09 -0400 +Subject: [PATCH 6/7] iso9660: Don't leak memory on realloc() failures + +Signed-off-by: Peter Jones +Reviewed-by: Daniel Kiper +--- + grub-core/fs/iso9660.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index 7ba5b300b..5ec4433b8 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -533,14 +533,20 @@ add_part (struct iterate_dir_ctx *ctx, + { + int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + grub_size_t sz; ++ char *new; + + if (grub_add (size, len2, &sz) || + grub_add (sz, 1, &sz)) + return; + +- ctx->symlink = grub_realloc (ctx->symlink, sz); +- if (! ctx->symlink) +- return; ++ new = grub_realloc (ctx->symlink, sz); ++ if (!new) ++ { ++ grub_free (ctx->symlink); ++ ctx->symlink = NULL; ++ return; ++ } ++ ctx->symlink = new; + + grub_memcpy (ctx->symlink + size, part, len2); + ctx->symlink[size + len2] = 0; +@@ -634,7 +640,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, + is the length. Both are part of the `Component + Record'. */ + if (ctx->symlink && !ctx->was_continue) +- add_part (ctx, "/", 1); ++ { ++ add_part (ctx, "/", 1); ++ if (grub_errno) ++ return grub_errno; ++ } ++ + add_part (ctx, (char *) &entry->data[pos + 2], + entry->data[pos + 1]); + ctx->was_continue = (entry->data[pos] & 1); +@@ -653,6 +664,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, + add_part (ctx, "/", 1); + break; + } ++ ++ /* Check if grub_realloc() failed in add_part(). */ ++ if (grub_errno) ++ return grub_errno; ++ + /* In pos + 1 the length of the `Component Record' is + stored. */ + pos += entry->data[pos + 1] + 2; +-- +2.27.0 diff --git a/0007-font-Do-not-load-more-than-one-NAME-section.patch b/0007-font-Do-not-load-more-than-one-NAME-section.patch new file mode 100644 index 0000000..34bc2b5 --- /dev/null +++ b/0007-font-Do-not-load-more-than-one-NAME-section.patch @@ -0,0 +1,35 @@ +From e2b5230126b340e1d88a079cd6a5c22dd4c00682 Mon Sep 17 00:00:00 2001 +From: Daniel Kiper +Date: Tue, 7 Jul 2020 15:36:26 +0200 +Subject: [PATCH 7/7] font: Do not load more than one NAME section + +The GRUB font file can have one NAME section only. Though if somebody +crafts a broken font file with many NAME sections and loads it then the +GRUB leaks memory. So, prevent against that by loading first NAME +section and failing in controlled way on following one. + +Reported-by: Chris Coulson +Signed-off-by: Daniel Kiper +--- + grub-core/font/font.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 5edb477ac..d09bb38d8 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -532,6 +532,12 @@ grub_font_load (const char *filename) + if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, + sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) + { ++ if (font->name != NULL) ++ { ++ grub_error (GRUB_ERR_BAD_FONT, "invalid font file: too many NAME sections"); ++ goto fail; ++ } ++ + font->name = read_section_as_string (§ion); + if (!font->name) + goto fail; +-- +2.27.0 diff --git a/0008-script-Remove-unused-fields-from-grub_script_functio.patch b/0008-script-Remove-unused-fields-from-grub_script_functio.patch new file mode 100644 index 0000000..12fc854 --- /dev/null +++ b/0008-script-Remove-unused-fields-from-grub_script_functio.patch @@ -0,0 +1,33 @@ +From 1804acfd35cff2aab9ec9dc586f74f5e3aa83ef2 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Fri, 10 Jul 2020 11:21:14 +0100 +Subject: [PATCH 18/27] script: Remove unused fields from grub_script_function + struct + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + include/grub/script_sh.h | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h +index 360c2be1f..b382bcf09 100644 +--- a/include/grub/script_sh.h ++++ b/include/grub/script_sh.h +@@ -359,13 +359,8 @@ struct grub_script_function + /* The script function. */ + struct grub_script *func; + +- /* The flags. */ +- unsigned flags; +- + /* The next element. */ + struct grub_script_function *next; +- +- int references; + }; + typedef struct grub_script_function *grub_script_function_t; + +-- +2.27.0 + diff --git a/0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch b/0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch new file mode 100644 index 0000000..7b670ed --- /dev/null +++ b/0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch @@ -0,0 +1,107 @@ +From 809f3a26897f5f648325c5741e72dc1b3db828ee Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Fri, 10 Jul 2020 14:41:45 +0100 +Subject: [PATCH 19/27] script: Avoid a use-after-free when redefining a + function during execution + +Defining a new function with the same name as a previously defined +function causes the grub_script and associated resources for the +previous function to be freed. If the previous function is currently +executing when a function with the same name is defined, this results +in use-after-frees when processing subsequent commands in the original +function. + +Instead, reject a new function definition if it has the same name as +a previously defined function, and that function is currently being +executed. Although a behavioural change, this should be backwards +compatible with existing configurations because they can't be +dependent on the current behaviour without being broken. + +Signed-off-by: Chris Coulson +Reviewed-by: Daniel Kiper +--- + grub-core/script/execute.c | 2 ++ + grub-core/script/function.c | 16 +++++++++++++--- + grub-core/script/parser.y | 3 ++- + include/grub/script_sh.h | 2 ++ + 4 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 8a9161cc8..ce83edd4b 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -838,7 +838,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) + old_scope = scope; + scope = &new_scope; + ++ func->executing++; + ret = grub_script_execute (func->func); ++ func->executing--; + + function_return = 0; + active_loops = loops; +diff --git a/grub-core/script/function.c b/grub-core/script/function.c +index d36655e51..3aad04bf9 100644 +--- a/grub-core/script/function.c ++++ b/grub-core/script/function.c +@@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, + func = (grub_script_function_t) grub_malloc (sizeof (*func)); + if (! func) + return 0; ++ func->executing = 0; + + func->name = grub_strdup (functionname_arg->str); + if (! func->name) +@@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, + grub_script_function_t q; + + q = *p; +- grub_script_free (q->func); +- q->func = cmd; + grub_free (func); +- func = q; ++ if (q->executing > 0) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("attempt to redefine a function being executed")); ++ func = NULL; ++ } ++ else ++ { ++ grub_script_free (q->func); ++ q->func = cmd; ++ func = q; ++ } + } + else + { +diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y +index 4f0ab8319..f80b86b6f 100644 +--- a/grub-core/script/parser.y ++++ b/grub-core/script/parser.y +@@ -289,7 +289,8 @@ function: "function" "name" + grub_script_mem_free (state->func_mem); + else { + script->children = state->scripts; +- grub_script_function_create ($2, script); ++ if (!grub_script_function_create ($2, script)) ++ grub_script_free (script); + } + + state->scripts = $3; +diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h +index b382bcf09..6c48e0751 100644 +--- a/include/grub/script_sh.h ++++ b/include/grub/script_sh.h +@@ -361,6 +361,8 @@ struct grub_script_function + + /* The next element. */ + struct grub_script_function *next; ++ ++ unsigned executing; + }; + typedef struct grub_script_function *grub_script_function_t; + +-- +2.27.0 + diff --git a/0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch b/0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch new file mode 100644 index 0000000..4868791 --- /dev/null +++ b/0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch @@ -0,0 +1,164 @@ +commit a59b854381d1148d32f74fbb9cf0f384972a5b4b +Author: Colin Watson +Date: Sat Jul 25 12:15:37 2020 +0100 + + linux: Fix integer overflows in initrd size handling + + These could be triggered by a crafted filesystem with very large files. + + Fixes: CVE-2020-15707 + + Signed-off-by: Colin Watson + Reviewed-by: Jan Setje-Eilers + +diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c +index 25624ebc1..e9f819ee9 100644 +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + struct newc_head + { +@@ -98,13 +99,13 @@ free_dir (struct dir *root) + grub_free (root); + } + +-static grub_size_t ++static grub_err_t + insert_dir (const char *name, struct dir **root, +- grub_uint8_t *ptr) ++ grub_uint8_t *ptr, grub_size_t *size) + { + struct dir *cur, **head = root; + const char *cb, *ce = name; +- grub_size_t size = 0; ++ *size = 0; + while (1) + { + for (cb = ce; *cb == '/'; cb++); +@@ -130,14 +131,22 @@ insert_dir (const char *name, struct dir **root, + ptr = make_header (ptr, name, ce - name, + 040777, 0); + } +- size += ALIGN_UP ((ce - (char *) name) +- + sizeof (struct newc_head), 4); ++ if (grub_add (*size, ++ ALIGN_UP ((ce - (char *) name) ++ + sizeof (struct newc_head), 4), ++ size)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ grub_free (n->name); ++ grub_free (n); ++ return grub_errno; ++ } + *head = n; + cur = n; + } + root = &cur->next; + } +- return size; ++ return GRUB_ERR_NONE; + } + + grub_err_t +@@ -173,26 +182,33 @@ grub_initrd_init (int argc, char *argv[], + eptr = grub_strchr (ptr, ':'); + if (eptr) + { ++ grub_size_t dir_size, name_len; ++ + initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); +- if (!initrd_ctx->components[i].newc_name) ++ if (!initrd_ctx->components[i].newc_name || ++ insert_dir (initrd_ctx->components[i].newc_name, &root, 0, ++ &dir_size)) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } +- initrd_ctx->size +- += ALIGN_UP (sizeof (struct newc_head) +- + grub_strlen (initrd_ctx->components[i].newc_name), +- 4); +- initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, +- &root, 0); ++ name_len = grub_strlen (initrd_ctx->components[i].newc_name); ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) + name_len, 4), ++ &initrd_ctx->size) || ++ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) ++ goto overflow; + newc = 1; + fname = eptr + 1; + } + } + else if (newc) + { +- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) +- + sizeof ("TRAILER!!!") - 1, 4); ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4), ++ &initrd_ctx->size)) ++ goto overflow; + free_dir (root); + root = 0; + newc = 0; +@@ -208,19 +224,29 @@ grub_initrd_init (int argc, char *argv[], + initrd_ctx->nfiles++; + initrd_ctx->components[i].size + = grub_file_size (initrd_ctx->components[i].file); +- initrd_ctx->size += initrd_ctx->components[i].size; ++ if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size, ++ &initrd_ctx->size)) ++ goto overflow; + } + + if (newc) + { + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); +- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) +- + sizeof ("TRAILER!!!") - 1, 4); ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4), ++ &initrd_ctx->size)) ++ goto overflow; + free_dir (root); + root = 0; + } + + return GRUB_ERR_NONE; ++ ++overflow: ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + } + + grub_size_t +@@ -261,8 +287,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + + if (initrd_ctx->components[i].newc_name) + { +- ptr += insert_dir (initrd_ctx->components[i].newc_name, +- &root, ptr); ++ grub_size_t dir_size; ++ ++ if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr, ++ &dir_size)) ++ { ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ ptr += dir_size; + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, + grub_strlen (initrd_ctx->components[i].newc_name), + 0100777, + diff --git a/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch b/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch index e97077d..7b5edd2 100644 --- a/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch +++ b/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch @@ -16,15 +16,20 @@ It is possible to boot into a separate GRUB instance by exporting the variable and loading the config file from the subvolume. Signed-off-by: Jeff Mahoney + +V1: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data + --- grub-core/fs/btrfs.c | 529 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 518 insertions(+), 11 deletions(-) -Index: grub-2.04~rc1/grub-core/fs/btrfs.c +Index: grub-2.04/grub-core/fs/btrfs.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/fs/btrfs.c -+++ grub-2.04~rc1/grub-core/fs/btrfs.c +--- grub-2.04.orig/grub-core/fs/btrfs.c ++++ grub-2.04/grub-core/fs/btrfs.c @@ -40,6 +40,9 @@ #include #include @@ -164,7 +169,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c return data; } -@@ -1654,6 +1739,91 @@ get_root (struct grub_btrfs_data *data, +@@ -1654,6 +1739,98 @@ get_root (struct grub_btrfs_data *data, } static grub_err_t @@ -207,8 +212,12 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + key_out.object_id != key_out.offset) { + struct grub_btrfs_inode_ref *inode_ref; + char *new; ++ grub_size_t sz; + -+ inode_ref = grub_malloc(elemsize + 1); ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ inode_ref = grub_malloc(sz); + if (!inode_ref) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate memory for inode_ref (%"PRIuGRUB_SIZE")\n", elemsize); @@ -217,7 +226,10 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + if (err) + return grub_error(err, "read_logical caught %d\n", err); + -+ alloc += grub_le_to_cpu16 (inode_ref->n) + 2; ++ if (grub_add (grub_le_to_cpu16 (inode_ref->n), 2, &sz) || ++ grub_add (alloc, sz, &alloc)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ + new = grub_malloc(alloc); + if (!new) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, @@ -256,7 +268,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, grub_uint64_t *tree, grub_uint8_t *type) -@@ -1671,14 +1841,26 @@ find_path (struct grub_btrfs_data *data, +@@ -1671,14 +1848,26 @@ find_path (struct grub_btrfs_data *data, char *origpath = NULL; unsigned symlinks_max = 32; @@ -287,7 +299,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c while (1) { while (path[0] == '/') -@@ -1851,9 +2033,21 @@ find_path (struct grub_btrfs_data *data, +@@ -1851,9 +2040,21 @@ find_path (struct grub_btrfs_data *data, path = path_alloc = tmp; if (path[0] == '/') { @@ -312,7 +324,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c } continue; } -@@ -2094,6 +2288,20 @@ grub_btrfs_read (grub_file_t file, char +@@ -2094,6 +2295,20 @@ grub_btrfs_read (grub_file_t file, char data->tree, file->offset, buf, len); } @@ -333,7 +345,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c static grub_err_t grub_btrfs_uuid (grub_device_t device, char **uuid) { -@@ -2105,15 +2313,7 @@ grub_btrfs_uuid (grub_device_t device, c +@@ -2105,15 +2320,7 @@ grub_btrfs_uuid (grub_device_t device, c if (!data) return grub_errno; @@ -350,7 +362,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c grub_btrfs_unmount (data); -@@ -2170,6 +2370,242 @@ grub_btrfs_embed (grub_device_t device _ +@@ -2170,6 +2377,248 @@ grub_btrfs_embed (grub_device_t device _ } #endif @@ -531,9 +543,15 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + + if (elemsize > allocated) + { ++ grub_size_t sz; ++ + grub_free(buf); -+ allocated = 2 * elemsize; -+ buf = grub_malloc(allocated + 1); ++ ++ if (grub_mul (elemsize, 2, &allocated) || ++ grub_add (allocated, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ buf = grub_malloc(sz); + if (!buf) + { + r = -grub_errno; @@ -593,7 +611,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .fs_dir = grub_btrfs_dir, -@@ -2185,12 +2621,88 @@ static struct grub_fs grub_btrfs_fs = { +@@ -2185,12 +2634,88 @@ static struct grub_fs grub_btrfs_fs = { #endif }; @@ -682,10 +700,10 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c } + +// vim: si et sw=2: -Index: grub-2.04~rc1/include/grub/btrfs.h +Index: grub-2.04/include/grub/btrfs.h =================================================================== ---- grub-2.04~rc1.orig/include/grub/btrfs.h -+++ grub-2.04~rc1/include/grub/btrfs.h +--- grub-2.04.orig/include/grub/btrfs.h ++++ grub-2.04/include/grub/btrfs.h @@ -29,6 +29,7 @@ enum GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84, GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90, diff --git a/grub2-btrfs-09-get-default-subvolume.patch b/grub2-btrfs-09-get-default-subvolume.patch index d15f42a..cb2f4f6 100644 --- a/grub2-btrfs-09-get-default-subvolume.patch +++ b/grub2-btrfs-09-get-default-subvolume.patch @@ -1,8 +1,13 @@ -Index: grub-2.04~rc1/grub-core/fs/btrfs.c + +V1: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data + +Index: grub-2.04/grub-core/fs/btrfs.c =================================================================== ---- grub-2.04~rc1.orig/grub-core/fs/btrfs.c -+++ grub-2.04~rc1/grub-core/fs/btrfs.c -@@ -2867,6 +2867,242 @@ out: +--- grub-2.04.orig/grub-core/fs/btrfs.c ++++ grub-2.04/grub-core/fs/btrfs.c +@@ -2880,6 +2880,254 @@ out: return 0; } @@ -26,6 +31,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + grub_disk_addr_t elemaddr; + grub_err_t err; + char *parent_path; ++ grub_size_t sz; + + *parent_id = 0; + *path_out = 0; @@ -44,7 +50,10 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root backrefs")); + } + -+ buf = grub_malloc(elemsize + 1); ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ buf = grub_malloc(sz); + if (!buf) + { + free_iterator(&desc); @@ -98,6 +107,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + struct grub_btrfs_dir_item *direl = NULL; + const char *ctoken = "default"; + grub_size_t ctokenlen = sizeof ("default") - 1; ++ grub_size_t sz; + + *id = 0; + key.object_id = data->sblock.root_dir_objectid; @@ -112,7 +122,14 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); + + struct grub_btrfs_dir_item *cdirel; -+ direl = grub_malloc (elemsize + 1); ++ ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ direl = grub_malloc (sz); ++ if (!direl) ++ return grub_errno; ++ + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); + if (err) + { @@ -245,7 +262,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .fs_dir = grub_btrfs_dir, -@@ -2885,6 +3121,7 @@ static struct grub_fs grub_btrfs_fs = { +@@ -2898,6 +3146,7 @@ static struct grub_fs grub_btrfs_fs = { static grub_command_t cmd_info; static grub_command_t cmd_mount_subvol; static grub_extcmd_t cmd_list_subvols; @@ -253,7 +270,7 @@ Index: grub-2.04~rc1/grub-core/fs/btrfs.c static char * subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), -@@ -2955,6 +3192,11 @@ GRUB_MOD_INIT (btrfs) +@@ -2968,6 +3217,11 @@ GRUB_MOD_INIT (btrfs) "[-p|-n] [-o var] DEVICE", "Print list of BtrFS subvolumes on " "DEVICE.", options); diff --git a/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch b/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch index 471debc..87e057c 100644 --- a/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch +++ b/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch @@ -14,6 +14,10 @@ gfxmenu to make it convenient for viewing the truncated text by pressing the ctrl+l and ctrl+r to scroll the highlighted text left and right. The scrolled result will remain in place to help memorizing it after changing highlight to other entry. + +V1: + * Use grub_calloc for overflow check and return NULL when it would + occur. --- grub-core/gfxmenu/gfxmenu.c | 3 +++ grub-core/gfxmenu/gui_label.c | 2 ++ @@ -24,20 +28,27 @@ changing highlight to other entry. include/grub/menu_viewer.h | 1 + 7 files changed, 112 insertions(+) -diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c -index 8a17dda2c..e834895fb 100644 ---- a/grub-core/gfxmenu/gfxmenu.c -+++ b/grub-core/gfxmenu/gfxmenu.c -@@ -108,6 +108,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) +Index: grub-2.04/grub-core/gfxmenu/gfxmenu.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/gfxmenu.c ++++ grub-2.04/grub-core/gfxmenu/gfxmenu.c +@@ -108,6 +108,15 @@ grub_gfxmenu_try (int entry, grub_menu_t view->menu = menu; view->nested = nested; view->first_timeout = -1; + if (menu->size) -+ view->menu_title_offset = grub_zalloc (sizeof (*view->menu_title_offset) * menu->size); ++ { ++ view->menu_title_offset = grub_calloc (menu->size, sizeof (*view->menu_title_offset)); ++ if (!view->menu_title_offset) ++ { ++ grub_free (instance); ++ return grub_errno; ++ } ++ } grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); if (view->double_repaint) -@@ -123,6 +125,7 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) +@@ -123,6 +132,7 @@ grub_gfxmenu_try (int entry, grub_menu_t instance->fini = grub_gfxmenu_viewer_fini; instance->print_timeout = grub_gfxmenu_print_timeout; instance->clear_timeout = grub_gfxmenu_clear_timeout; @@ -45,11 +56,11 @@ index 8a17dda2c..e834895fb 100644 grub_menu_register_viewer (instance); -diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c -index a4c817891..8b1358dd4 100644 ---- a/grub-core/gfxmenu/gui_label.c -+++ b/grub-core/gfxmenu/gui_label.c -@@ -192,6 +192,8 @@ label_set_property (void *vself, const char *name, const char *value) +Index: grub-2.04/grub-core/gfxmenu/gui_label.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/gui_label.c ++++ grub-2.04/grub-core/gfxmenu/gui_label.c +@@ -192,6 +192,8 @@ label_set_property (void *vself, const c "or `c' for a command-line."); else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) value = _("enter: boot, `e': options, `c': cmd-line"); @@ -58,10 +69,10 @@ index a4c817891..8b1358dd4 100644 /* FIXME: Add more templates here if needed. */ self->template = grub_strdup (value); self->text = grub_xasprintf (value, self->value); -diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c -index 01477cdf2..90487aef4 100644 ---- a/grub-core/gfxmenu/gui_list.c -+++ b/grub-core/gfxmenu/gui_list.c +Index: grub-2.04/grub-core/gfxmenu/gui_list.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/gui_list.c ++++ grub-2.04/grub-core/gfxmenu/gui_list.c @@ -24,6 +24,7 @@ #include #include @@ -104,7 +115,7 @@ index 01477cdf2..90487aef4 100644 /* Draw the list of items. */ static void draw_menu (list_impl_t self, int num_shown_items) -@@ -433,6 +461,16 @@ draw_menu (list_impl_t self, int num_shown_items) +@@ -433,6 +461,16 @@ draw_menu (list_impl_t self, int num_sho const char *item_title = grub_menu_get_entry (self->view->menu, menu_index)->title; @@ -121,10 +132,10 @@ index 01477cdf2..90487aef4 100644 sviewport.y = item_top + top_pad; sviewport.width = viewport_width; grub_gui_set_viewport (&sviewport, &svpsave); -diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c -index ad5e82b81..7aed7faa1 100644 ---- a/grub-core/gfxmenu/view.c -+++ b/grub-core/gfxmenu/view.c +Index: grub-2.04/grub-core/gfxmenu/view.c +=================================================================== +--- grub-2.04.orig/grub-core/gfxmenu/view.c ++++ grub-2.04/grub-core/gfxmenu/view.c @@ -37,6 +37,7 @@ #include #include @@ -133,7 +144,7 @@ index ad5e82b81..7aed7faa1 100644 static void init_terminal (grub_gfxmenu_view_t view); -@@ -142,6 +143,7 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) +@@ -142,6 +143,7 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_ grub_free (view->title_text); grub_free (view->progress_message_text); grub_free (view->theme_path); @@ -141,7 +152,7 @@ index ad5e82b81..7aed7faa1 100644 if (view->canvas) view->canvas->component.ops->destroy (view->canvas); grub_free (view); -@@ -410,6 +412,52 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data) +@@ -410,6 +412,52 @@ grub_gfxmenu_set_chosen_entry (int entry grub_gfxmenu_redraw_menu (view); } @@ -194,15 +205,14 @@ index ad5e82b81..7aed7faa1 100644 static void grub_gfxmenu_draw_terminal_box (void) { -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index e7a83c2d6..0af20d052 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -376,6 +376,15 @@ menu_set_chosen_entry (int entry) - cur->set_chosen_entry (entry, cur->data); +Index: grub-2.04/grub-core/normal/menu.c +=================================================================== +--- grub-2.04.orig/grub-core/normal/menu.c ++++ grub-2.04/grub-core/normal/menu.c +@@ -401,6 +401,15 @@ menu_set_chosen_entry (int entry) } -+static void + static void +menu_scroll_chosen_entry (int diren) +{ + struct grub_menu_viewer *cur; @@ -211,10 +221,11 @@ index e7a83c2d6..0af20d052 100644 + cur->scroll_chosen_entry (cur->data, diren); +} + - static void ++static void menu_print_timeout (int timeout) { -@@ -755,6 +764,13 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) + struct grub_menu_viewer *cur; +@@ -828,6 +837,13 @@ run_menu (grub_menu_t menu, int nested, menu_set_chosen_entry (current_entry); break; @@ -228,10 +239,10 @@ index e7a83c2d6..0af20d052 100644 case '\n': case '\r': case GRUB_TERM_KEY_RIGHT: -diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h -index 4203c8fb9..56c0d17ae 100644 ---- a/include/grub/gfxmenu_view.h -+++ b/include/grub/gfxmenu_view.h +Index: grub-2.04/include/grub/gfxmenu_view.h +=================================================================== +--- grub-2.04.orig/include/grub/gfxmenu_view.h ++++ grub-2.04/include/grub/gfxmenu_view.h @@ -61,6 +61,8 @@ void grub_gfxmenu_print_timeout (int timeout, void *data); void @@ -250,10 +261,10 @@ index 4203c8fb9..56c0d17ae 100644 }; #endif /* ! GRUB_GFXMENU_VIEW_HEADER */ -diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h -index c6513c4e8..5f2a39dc9 100644 ---- a/include/grub/menu_viewer.h -+++ b/include/grub/menu_viewer.h +Index: grub-2.04/include/grub/menu_viewer.h +=================================================================== +--- grub-2.04.orig/include/grub/menu_viewer.h ++++ grub-2.04/include/grub/menu_viewer.h @@ -33,6 +33,7 @@ struct grub_menu_viewer void (*set_chosen_entry) (int entry, void *data); void (*print_timeout) (int timeout, void *data); @@ -262,6 +273,3 @@ index c6513c4e8..5f2a39dc9 100644 void (*fini) (void *fini); }; --- -2.16.4 - diff --git a/grub2-grubenv-in-btrfs-header.patch b/grub2-grubenv-in-btrfs-header.patch index 61ebb4c..4b9b082 100644 --- a/grub2-grubenv-in-btrfs-header.patch +++ b/grub2-grubenv-in-btrfs-header.patch @@ -4,11 +4,16 @@ As a workaround use the Btrfs header to store known data of the GRUB environment block. v2: export env_block and make sure to use the device of grubenv + +v3: + * Use xcalloc for overflow check and return NULL when it would + occur. + --- -Index: grub-2.02/grub-core/kern/fs.c +Index: grub-2.04/grub-core/kern/fs.c =================================================================== ---- grub-2.02.orig/grub-core/kern/fs.c -+++ grub-2.02/grub-core/kern/fs.c +--- grub-2.04.orig/grub-core/kern/fs.c ++++ grub-2.04/grub-core/kern/fs.c @@ -27,6 +27,7 @@ #include #include @@ -31,10 +36,10 @@ Index: grub-2.02/grub-core/kern/fs.c ret += size; len -= size; sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS); -Index: grub-2.02/util/grub-editenv.c +Index: grub-2.04/util/grub-editenv.c =================================================================== ---- grub-2.02.orig/util/grub-editenv.c -+++ grub-2.02/util/grub-editenv.c +--- grub-2.04.orig/util/grub-editenv.c ++++ grub-2.04/util/grub-editenv.c @@ -23,8 +23,11 @@ #include #include @@ -207,7 +212,7 @@ Index: grub-2.02/util/grub-editenv.c } static void -@@ -202,6 +346,38 @@ write_envblk (const char *name, grub_env +@@ -203,6 +347,38 @@ write_envblk (const char *name, grub_env } static void @@ -246,7 +251,7 @@ Index: grub-2.02/util/grub-editenv.c set_variables (const char *name, int argc, char *argv[]) { grub_envblk_t envblk; -@@ -217,8 +393,27 @@ set_variables (const char *name, int arg +@@ -218,8 +394,27 @@ set_variables (const char *name, int arg *(p++) = 0; @@ -276,7 +281,7 @@ Index: grub-2.02/util/grub-editenv.c argc--; argv++; -@@ -226,26 +421,158 @@ set_variables (const char *name, int arg +@@ -227,26 +422,158 @@ set_variables (const char *name, int arg write_envblk (name, envblk); grub_envblk_close (envblk); @@ -371,7 +376,7 @@ Index: grub-2.02/util/grub-editenv.c + ndev++; + } + -+ grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); ++ grub_drives = xcalloc ((ndev + 1), sizeof (grub_drives[0])); + + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) @@ -435,7 +440,7 @@ Index: grub-2.02/util/grub-editenv.c int main (int argc, char *argv[]) { -@@ -277,6 +604,9 @@ main (int argc, char *argv[]) +@@ -278,6 +605,9 @@ main (int argc, char *argv[]) command = argv[curindex++]; } @@ -445,10 +450,10 @@ Index: grub-2.02/util/grub-editenv.c if (strcmp (command, "create") == 0) grub_util_create_envblk_file (filename); else if (strcmp (command, "list") == 0) -Index: grub-2.02/util/grub.d/00_header.in +Index: grub-2.04/util/grub.d/00_header.in =================================================================== ---- grub-2.02.orig/util/grub.d/00_header.in -+++ grub-2.02/util/grub.d/00_header.in +--- grub-2.04.orig/util/grub.d/00_header.in ++++ grub-2.04/util/grub.d/00_header.in @@ -46,6 +46,13 @@ cat << EOF if [ -s \$prefix/grubenv ]; then load_env diff --git a/grub2.changes b/grub2.changes index a52ce8c..1694b26 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Mon Jul 27 10:04:49 UTC 2020 - Michael Chang + +- Fix for CVE-2020-10713 (bsc#1168994) + * 0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch +- Fix for CVE-2020-14308 CVE-2020-14309, CVE-2020-14310, CVE-2020-14311 + (bsc#1173812) + * 0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch + * 0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch + * 0004-calloc-Use-calloc-at-most-places.patch + * 0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch + * 0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch + * 0007-font-Do-not-load-more-than-one-NAME-section.patch +- Fix CVE-2020-15706 (bsc#1174463) + * 0008-script-Remove-unused-fields-from-grub_script_functio.patch + * 0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch +- Fix CVE-2020-15707 (bsc#1174570) + * 0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch +- Use overflow checking primitives where the arithmetic expression for buffer + allocations may include unvalidated data +- Use grub_calloc for overflow check and return NULL when it would occur + * 0001-add-support-for-UEFI-network-protocols.patch + * 0003-bootp-New-net_bootp6-command.patch + * grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch + * grub2-btrfs-09-get-default-subvolume.patch + * grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch + * grub2-grubenv-in-btrfs-header.patch + ------------------------------------------------------------------- Thu Jul 16 13:15:27 UTC 2020 - Michel Normand diff --git a/grub2.spec b/grub2.spec index a586c08..834da37 100644 --- a/grub2.spec +++ b/grub2.spec @@ -302,6 +302,24 @@ Patch700: 0001-normal-Move-common-datetime-functions-out-of-the-nor.patch Patch701: 0002-kern-Add-X-option-to-printf-functions.patch Patch702: 0003-normal-main-Search-for-specific-config-files-for-net.patch Patch703: 0004-datetime-Enable-the-datetime-module-for-the-emu-plat.patch +# bsc#1168994 VUL-0: EMBARGOED: CVE-2020-10713: grub2: parsing overflows can +# bypass secure boot restrictions +Patch704: 0001-yylex-Make-lexer-fatal-errors-actually-be-fatal.patch +# bsc#1173812 VUL-0: EMBARGOED: CVE-2020-14308, CVE-2020-14309, CVE-2020-14310, +# CVE-2020-14311: grub2: avoid integer overflows +Patch705: 0002-safemath-Add-some-arithmetic-primitives-that-check-f.patch +Patch706: 0003-calloc-Make-sure-we-always-have-an-overflow-checking.patch +Patch707: 0004-calloc-Use-calloc-at-most-places.patch +Patch708: 0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch +Patch709: 0006-iso9660-Don-t-leak-memory-on-realloc-failures.patch +Patch710: 0007-font-Do-not-load-more-than-one-NAME-section.patch +# bsc#1174463 VUL-0: EMBARGOED: CVE-2020-15706: grub2: script: Avoid a +# use-after-free when redefining a function during execution +Patch711: 0008-script-Remove-unused-fields-from-grub_script_functio.patch +Patch712: 0009-script-Avoid-a-use-after-free-when-redefining-a-func.patch +# bsc#1174570 VUL-0: EMBARGOED: CVE-2020-15707: grub2: linux: Fix integer +# overflows in initrd size handling +Patch713: 0010-linux-Fix-integer-overflows-in-initrd-size-handling.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 @@ -607,6 +625,16 @@ swap partition while in resuming %patch701 -p1 %patch702 -p1 %patch703 -p1 +%patch704 -p1 +%patch705 -p1 +%patch706 -p1 +%patch707 -p1 +%patch708 -p1 +%patch709 -p1 +%patch710 -p1 +%patch711 -p1 +%patch712 -p1 +%patch713 -p1 %build # collect evidence to debug spurious build failure on SLE15