summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Swanson2021-06-20 08:07:01 -0700
committerMike Swanson2021-06-20 08:07:01 -0700
commitb780a410f2a725002f1ff11c583d226d0a9ce5f5 (patch)
tree7acbe31e1c7c8488be76be5e906929d311a4bbdc
parent0bd6092ac0d3d7e2ee1d34aa434162d4f1cfc3e3 (diff)
downloadaur-b780a410f2a725002f1ff11c583d226d0a9ce5f5.tar.gz
Update to 2.06-1, synced with core repo
-rw-r--r--.SRCINFO24
-rw-r--r--.gitignore1
-rw-r--r--0001-00_header-add-GRUB_COLOR_-variables.patch (renamed from 0004-add-GRUB_COLOR_variables.patch)17
-rw-r--r--0002-10_linux-detect-archlinux-initramfs.patch (renamed from 0003-10_linux-detect-archlinux-initramfs.patch)39
-rw-r--r--0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch36
-rw-r--r--0006-BootHole.patch5936
-rw-r--r--PKGBUILD64
-rw-r--r--grub-libzfs.install17
8 files changed, 86 insertions, 6048 deletions
diff --git a/.SRCINFO b/.SRCINFO
index a8dcfcd729d7..eea484fe77f2 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,7 +1,7 @@
pkgbase = grub-libzfs
pkgdesc = GNU GRand Unified Bootloader (2) - libzfs support
- pkgver = 2.04
- pkgrel = 10
+ pkgver = 2.06
+ pkgrel = 1
epoch = 2
url = https://www.gnu.org/software/grub/
install = grub-libzfs.install
@@ -50,28 +50,22 @@ pkgbase = grub-libzfs
options = !makeflags
backup = etc/default/grub
backup = etc/grub.d/40_custom
- source = git+https://git.savannah.gnu.org/git/grub.git#tag=grub-2.04?signed
- source = git+https://git.savannah.gnu.org/git/grub-extras.git#commit=8a245d5c1800627af4cefa99162a89c7a46d8842
+ source = git+https://git.savannah.gnu.org/git/grub.git#tag=53c5000739db114c229fe69ec3d4b76b92441098?signed
source = git+https://git.savannah.gnu.org/git/gnulib.git#commit=be584c56eb1311606e5ea1a36363b97bddb6eed3
- source = http://unifoundry.com/pub/unifont/unifont-13.0.06/font-builds/unifont-13.0.06.bdf.gz
- source = http://unifoundry.com/pub/unifont/unifont-13.0.06/font-builds/unifont-13.0.06.bdf.gz.sig
- source = 0003-10_linux-detect-archlinux-initramfs.patch
- source = 0004-add-GRUB_COLOR_variables.patch
- source = 0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch
- source = 0006-BootHole.patch
+ source = https://ftp.gnu.org/gnu/unifont/unifont-13.0.06/unifont-13.0.06.bdf.gz
+ source = https://ftp.gnu.org/gnu/unifont/unifont-13.0.06/unifont-13.0.06.bdf.gz.sig
+ source = 0001-00_header-add-GRUB_COLOR_-variables.patch
+ source = 0002-10_linux-detect-archlinux-initramfs.patch
source = grub.default
validpgpkeys = E53D497F3FA42AD8C9B4D1E835A93B74E82E4209
validpgpkeys = BE5C23209ACDDACEB20DB0A28C8189F1988C2166
validpgpkeys = 95D2E9AB8740D8046387FD151A09227B1F435A33
sha256sums = SKIP
sha256sums = SKIP
- sha256sums = SKIP
sha256sums = b7668a5d498972dc4981250c49f83601babce797be19b4fdd0f2f1c6cfbd0fc5
sha256sums = SKIP
- sha256sums = 171415ab075d1ac806f36c454feeb060f870416f24279b70104bba94bd6076d4
- sha256sums = a5198267ceb04dceb6d2ea7800281a42b3f91fd02da55d2cc9ea20d47273ca29
- sha256sums = 06820004912a3db195a76e68b376fce1ba6507ac740129f0b99257ef07aba1ea
- sha256sums = 55c559b6d8c4a832a43cc35c7635de37402ec9e3e3bfd8b2b7761a06f0bfda02
+ sha256sums = 5dee6628c48eef79812bb9e86ee772068d85e7fcebbd2b2b8d1e19d24eda9dab
+ sha256sums = 8488aec30a93e8fe66c23ef8c23aefda39c38389530e9e73ba3fbcc8315d244d
sha256sums = 791fadf182edf8d5bee4b45c008b08adce9689a9624971136527891a8f67d206
pkgname = grub-libzfs
diff --git a/.gitignore b/.gitignore
index 8e1ddcd40bbf..fce15edae897 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,5 @@
*.sig
/gnulib
/grub
-/grub-extras
/src
/pkg
diff --git a/0004-add-GRUB_COLOR_variables.patch b/0001-00_header-add-GRUB_COLOR_-variables.patch
index c113a81d5754..867e8feeb7b9 100644
--- a/0004-add-GRUB_COLOR_variables.patch
+++ b/0001-00_header-add-GRUB_COLOR_-variables.patch
@@ -1,18 +1,27 @@
+From 21e5bcf22ab1a9f08c63e2a0212219d7482f77c1 Mon Sep 17 00:00:00 2001
+From: Christian Hesse <mail@eworm.de>
+Date: Wed, 10 Mar 2021 18:42:25 +0100
+Subject: [PATCH] 00_header: add GRUB_COLOR_* variables
+---
+ util/grub-mkconfig.in | 2 ++
+ util/grub.d/00_header.in | 8 ++++++++
+ 2 files changed, 10 insertions(+)
+
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
-index 3390ba9..c416489 100644
+index f8cbb8d7a..1189d95f9 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
-@@ -218,6 +218,8 @@ export GRUB_DEFAULT \
+@@ -246,6 +246,8 @@ export GRUB_DEFAULT \
+ GRUB_BACKGROUND \
GRUB_THEME \
GRUB_GFXPAYLOAD_LINUX \
- GRUB_DISABLE_OS_PROBER \
+ GRUB_COLOR_NORMAL \
+ GRUB_COLOR_HIGHLIGHT \
GRUB_INIT_TUNE \
GRUB_SAVEDEFAULT \
GRUB_ENABLE_CRYPTODISK \
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
-index d2e7252..8259f45 100644
+index 93a90233e..c5955df00 100644
--- a/util/grub.d/00_header.in
+++ b/util/grub.d/00_header.in
@@ -125,6 +125,14 @@ cat <<EOF
diff --git a/0003-10_linux-detect-archlinux-initramfs.patch b/0002-10_linux-detect-archlinux-initramfs.patch
index 512fa0451504..5abb5e63dc88 100644
--- a/0003-10_linux-detect-archlinux-initramfs.patch
+++ b/0002-10_linux-detect-archlinux-initramfs.patch
@@ -1,17 +1,27 @@
+From dbc289f59a2b204af19ef7212f3b6b07d3060452 Mon Sep 17 00:00:00 2001
+From: Christian Hesse <mail@eworm.de>
+Date: Mon, 26 Apr 2021 11:10:01 +0200
+Subject: [PATCH 1/1] 10_linux: detect archlinux initramfs
+---
+ util/grub.d/10_linux.in | 29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
-index f5d3e78..ef59c8c 100644
+index e8b01c0d0..9b60af944 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
-@@ -83,6 +83,8 @@ linux_entry ()
+@@ -91,6 +91,10 @@ linux_entry ()
+ fi
+ if [ x$type != xsimple ] ; then
case $type in
- recovery)
- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;;
++ booster)
++ title="$(gettext_printf "%s, with Linux %s (booster initramfs)" "${os}" "${version}")" ;;
+ fallback)
+ title="$(gettext_printf "%s, with Linux %s (fallback initramfs)" "${os}" "${version}")" ;;
+ recovery)
+ title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;;
*)
- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
- esac
-@@ -186,7 +188,7 @@ while [ "x$list" != "x" ] ; do
+@@ -198,7 +202,7 @@ while [ "x$list" != "x" ] ; do
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
@@ -20,13 +30,13 @@ index f5d3e78..ef59c8c 100644
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
-@@ -248,6 +250,18 @@ while [ "x$list" != "x" ] ; do
+@@ -285,6 +289,29 @@ while [ "x$list" != "x" ] ; do
linux_entry "${OS}" "${version}" advanced \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
+
+ if test -e "${dirname}/initramfs-${version}-fallback.img" ; then
-+ initrd="initramfs-${version}-fallback.img"
++ initrd="${initrd_early} initramfs-${version}-fallback.img"
+
+ if test -n "${initrd}" ; then
+ gettext_printf "Found fallback initrd image(s) in %s:%s\n" "${dirname}" "${initrd_extra} ${initrd}" >&2
@@ -36,6 +46,17 @@ index f5d3e78..ef59c8c 100644
+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
+ fi
+
++ if test -e "${dirname}/booster-${version}.img" ; then
++ initrd="${initrd_early} booster-${version}.img"
++
++ if test -n "${initrd}" ; then
++ gettext_printf "Found booster initrd image(s) in %s:%s\n" "${dirname}" "${initrd_extra} ${initrd}" >&2
++ fi
++
++ linux_entry "${OS}" "${version}" booster \
++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
++ fi
++
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" recovery \
"single ${GRUB_CMDLINE_LINUX}"
diff --git a/0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch b/0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch
deleted file mode 100644
index 48a5b13cb47c..000000000000
--- a/0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From ee855b15ff185bad3b0495500ab234b9cab7436c Mon Sep 17 00:00:00 2001
-From: Martin Whitaker <fsf@martin-whitaker.me.uk>
-Date: Mon, 24 Feb 2020 22:11:29 +0000
-Subject: [PATCH] grub-install: fix inverted test for NLS enabled when copying
- locales.
-
-Commit 3d8439da8c9a4acf9bc1c41b364ec6e1680ef052 attempted to avoid
-copying locale files to the target directory when NLS was disabled.
-However the test is inverted, and it does the opposite.
-
-Signed-off-by: Martin Whitaker <fsf@martin-whitaker.me.uk>
-
-diff --git a/util/grub-install-common.c b/util/grub-install-common.c
-index ca0ac612a..f53bf0694 100644
---- a/util/grub-install-common.c
-+++ b/util/grub-install-common.c
-@@ -598,7 +598,7 @@ copy_all (const char *srcd,
- grub_util_fd_closedir (d);
- }
-
--#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
-+#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
- static const char *
- get_localedir (void)
- {
-@@ -659,7 +659,7 @@ static void
- grub_install_copy_nls(const char *src __attribute__ ((unused)),
- const char *dst __attribute__ ((unused)))
- {
--#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
-+#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS)
- char *dst_locale;
-
- dst_locale = grub_util_path_concat (2, dst, "locale");
---
-2.21.1
diff --git a/0006-BootHole.patch b/0006-BootHole.patch
deleted file mode 100644
index a63093bfb1fd..000000000000
--- a/0006-BootHole.patch
+++ /dev/null
@@ -1,5936 +0,0 @@
-From 705b89f19fff03054f7167e1785461492688d61b Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Wed, 15 Apr 2020 15:45:02 -0400
-Subject: 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.
-
-Fixes: CVE-2020-10713
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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) \
-
-From 016977edbd5d9f6fbab6412fb8b4d1f50eb432e7 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 15 Jun 2020 10:58:42 -0400
-Subject: 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 <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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 342c158e9..991479b52 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 <http://www.gnu.org/licenses/>.
-+ *
-+ * Arithmetic operations that protect against overflow.
-+ */
-+
-+#ifndef GRUB_SAFEMATH_H
-+#define GRUB_SAFEMATH_H 1
-+
-+#include <grub/compiler.h>
-+
-+/* 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 */
-
-From f80ca28e207484650fc7634545cd3dc6037de3c8 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 15 Jun 2020 12:15:29 -0400
-Subject: 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 <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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(-)
-
-diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
-index 65db79baa..dfd8a8ec4 100644
---- a/grub-core/kern/emu/misc.c
-+++ b/grub-core/kern/emu/misc.c
-@@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...)
- exit (1);
- }
-
-+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)
- {
-diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
-index f262e95e3..145b01d37 100644
---- a/grub-core/kern/emu/mm.c
-+++ b/grub-core/kern/emu/mm.c
-@@ -25,6 +25,16 @@
- #include <string.h>
- #include <grub/i18n.h>
-
-+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)
- {
-diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
-index ee88ff611..f2822a836 100644
---- a/grub-core/kern/mm.c
-+++ b/grub-core/kern/mm.c
-@@ -67,8 +67,10 @@
- #include <grub/dl.h>
- #include <grub/i18n.h>
- #include <grub/mm_private.h>
-+#include <grub/safemath.h>
-
- #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_size_t size)
- 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)
-@@ -561,6 +587,20 @@ grub_mm_dump (unsigned lineno)
- grub_printf ("\n");
- }
-
-+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)
- {
-diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c
-index beeb661a3..74c6eafe5 100644
---- a/grub-core/lib/libgcrypt_wrap/mem.c
-+++ b/grub-core/lib/libgcrypt_wrap/mem.c
-@@ -4,6 +4,7 @@
- #include <grub/crypto.h>
- #include <grub/dl.h>
- #include <grub/env.h>
-+#include <grub/safemath.h>
-
- 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;
-diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
-index 3b46f47ff..7a8d385e9 100644
---- a/grub-core/lib/posix_wrap/stdlib.h
-+++ b/grub-core/lib/posix_wrap/stdlib.h
-@@ -21,6 +21,7 @@
-
- #include <grub/mm.h>
- #include <grub/misc.h>
-+#include <grub/safemath.h>
-
- 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 *
-diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
-index ce464cfd0..ff9c48a64 100644
---- a/include/grub/emu/misc.h
-+++ b/include/grub/emu/misc.h
-@@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev);
- #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;
-diff --git a/include/grub/mm.h b/include/grub/mm.h
-index 28e2e53eb..9c38dd3ca 100644
---- a/include/grub/mm.h
-+++ b/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,
-
-From 65dfa11751111173ce6f492afce13d4a2c2b006c Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 15 Jun 2020 12:26:01 -0400
-Subject: 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 <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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 | 8 ++++----
- 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/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/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 ++--
- 85 files changed, 175 insertions(+), 174 deletions(-)
-
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index 34a7ff1b5..a06cce302 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/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 (grub_usb_controller_t controller, void *d
-
- /* 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);
-diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c
-index df1030221..cd81507f5 100644
---- a/grub-core/commands/efi/lsefisystab.c
-+++ b/grub-core/commands/efi/lsefisystab.c
-@@ -71,7 +71,8 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
- 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,
-diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
-index db7a8f002..5e3ec0d5e 100644
---- a/grub-core/commands/legacycfg.c
-+++ b/grub-core/commands/legacycfg.c
-@@ -314,7 +314,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
- 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_command *mycmd __attribute__ ((unused)),
- {
- 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 grub_command *mycmd __attribute__ ((unused
- 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]));
-diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
-index 2c5363da7..9164df744 100644
---- a/grub-core/commands/menuentry.c
-+++ b/grub-core/commands/menuentry.c
-@@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
- 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;
-
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 699447d11..7c8f97f6a 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
- else
- path_prefix = prefix;
-
-- mods = grub_malloc (argc * sizeof (mods[0]));
-+ mods = grub_calloc (argc, sizeof (mods[0]));
- if (!mods)
- return grub_errno;
-
-diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c
-index 22b46b187..051e31320 100644
---- a/grub-core/commands/parttool.c
-+++ b/grub-core/commands/parttool.c
-@@ -59,7 +59,13 @@ grub_parttool_register(const char *part_name,
- 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 __attribute__ ((unused)),
- 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 __attribute__ ((unused)),
- }
- 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])
- {
-diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c
-index f00b184c8..4019164f3 100644
---- a/grub-core/commands/regexp.c
-+++ b/grub-core/commands/regexp.c
-@@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
- 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;
-
-diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
-index d7fd26b94..47fc8eb99 100644
---- a/grub-core/commands/search_wrap.c
-+++ b/grub-core/commands/search_wrap.c
-@@ -122,7 +122,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
- 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;
-diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
-index c3b578acf..68ca9e0be 100644
---- a/grub-core/disk/diskfilter.c
-+++ b/grub-core/disk/diskfilter.c
-@@ -1134,7 +1134,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
- 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++)
- {
-@@ -1226,7 +1226,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
- 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);
-diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
-index f73257e66..03674cb47 100644
---- a/grub-core/disk/ieee1275/ofdisk.c
-+++ b/grub-core/disk/ieee1275/ofdisk.c
-@@ -297,7 +297,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
- /* 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)
- {
-diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
-index 2a22d2d6c..e6323701a 100644
---- a/grub-core/disk/ldm.c
-+++ b/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 *disk, unsigned int *nsectors,
- *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++)
-diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
-index 86c50c612..18b3a8bb1 100644
---- a/grub-core/disk/luks.c
-+++ b/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;
-
-diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
-index 7b265c780..d1df640b3 100644
---- a/grub-core/disk/lvm.c
-+++ b/grub-core/disk/lvm.c
-@@ -173,7 +173,7 @@ grub_lvm_detect (grub_disk_t disk,
- first one. */
-
- /* Allocate buffer space for the circular worst-case scenario. */
-- metadatabuf = grub_malloc (2 * mda_size);
-+ metadatabuf = grub_calloc (2, mda_size);
- if (! metadatabuf)
- goto fail;
-
-@@ -426,7 +426,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++)
-@@ -483,8 +483,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 = [");
-diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c
-index 48476cbbf..d6612eebd 100644
---- a/grub-core/disk/xen/xendisk.c
-+++ b/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))
-diff --git a/grub-core/efiemu/loadcore.c b/grub-core/efiemu/loadcore.c
-index 44085ef81..2b924623f 100644
---- a/grub-core/efiemu/loadcore.c
-+++ b/grub-core/efiemu/loadcore.c
-@@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e)
-
- 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);
-diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c
-index 52a032f7b..9b8e0d0ad 100644
---- a/grub-core/efiemu/mm.c
-+++ b/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 ();
-diff --git a/grub-core/font/font.c b/grub-core/font/font.c
-index 85a292557..8e118b315 100644
---- a/grub-core/font/font.c
-+++ b/grub-core/font/font.c
-@@ -293,8 +293,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
- 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));
-diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
-index 6b6a2bc91..220b3712f 100644
---- a/grub-core/fs/affs.c
-+++ b/grub-core/fs/affs.c
-@@ -301,7 +301,7 @@ grub_affs_read_symlink (grub_fshelp_node_t 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_t dir,
- 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, char **label)
- 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';
- }
-diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
-index 63f9657a6..4b8380439 100644
---- a/grub-core/fs/btrfs.c
-+++ b/grub-core/fs/btrfs.c
-@@ -415,7 +415,7 @@ lower_bound (struct grub_btrfs_data *data,
- {
- 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;
- }
-@@ -754,7 +754,7 @@ raid56_read_retry (struct grub_btrfs_data *data,
- 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;
-
-@@ -2167,7 +2167,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
- *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++)
-diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
-index ac0a40990..3fe842b4d 100644
---- a/grub-core/fs/hfs.c
-+++ b/grub-core/fs/hfs.c
-@@ -1360,7 +1360,7 @@ grub_hfs_label (grub_device_t device, char **label)
- 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);
-diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
-index 54786bb1c..dae43becc 100644
---- a/grub-core/fs/hfsplus.c
-+++ b/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, char **label)
- 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, char **label)
- }
- }
-
-- *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);
-diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
-index 49c0c632b..4f1b52a55 100644
---- a/grub-core/fs/iso9660.c
-+++ b/grub-core/fs/iso9660.c
-@@ -331,7 +331,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len)
- 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;
-
-diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
-index fc4e1f678..2f34f76da 100644
---- a/grub-core/fs/ntfs.c
-+++ b/grub-core/fs/ntfs.c
-@@ -556,8 +556,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
- 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);
-diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
-index 50c1fe72f..90f7fb379 100644
---- a/grub-core/fs/sfs.c
-+++ b/grub-core/fs/sfs.c
-@@ -266,7 +266,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
- 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;
-diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
-index 7d63e0c99..c551ed6b5 100644
---- a/grub-core/fs/tar.c
-+++ b/grub-core/fs/tar.c
-@@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
- 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);
-diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
-index dc8b6e2d1..a83761674 100644
---- a/grub-core/fs/udf.c
-+++ b/grub-core/fs/udf.c
-@@ -873,7 +873,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
- {
- 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, grub_size_t sz, char *outbuf)
- {
- 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++)
-diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
-index 2f72e42bf..381dde556 100644
---- a/grub-core/fs/zfs/zfs.c
-+++ b/grub-core/fs/zfs/zfs.c
-@@ -3325,7 +3325,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
- }
- 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);
-@@ -4336,7 +4336,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
- *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++)
-diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c
-index a9a415e31..ba1e1eab3 100644
---- a/grub-core/gfxmenu/gui_string_util.c
-+++ b/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;
-
-diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c
-index b60602889..470597ded 100644
---- a/grub-core/gfxmenu/widget-box.c
-+++ b/grub-core/gfxmenu/widget-box.c
-@@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix,
- 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. */
-diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
-index 6208a9763..43d98a7bd 100644
---- a/grub-core/io/gzio.c
-+++ b/grub-core/io/gzio.c
-@@ -554,7 +554,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
- 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)
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index 96204e39b..ad170c7ce 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -202,7 +202,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
-
- 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, const grub_efi_guid_t *guid,
-
- 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_path_t *dp0)
- 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);
-diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c
-index 8ac523953..f90b6c9ce 100644
---- a/grub-core/kern/emu/hostdisk.c
-+++ b/grub-core/kern/emu/hostdisk.c
-@@ -627,7 +627,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;
-diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
-index 2b85f4950..f90be6566 100644
---- a/grub-core/kern/fs.c
-+++ b/grub-core/kern/fs.c
-@@ -151,7 +151,7 @@ grub_fs_blocklist_open (grub_file_t file, const char *name)
- 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;
-
-diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
-index 18cad5803..83c068d61 100644
---- a/grub-core/kern/misc.c
-+++ b/grub-core/kern/misc.c
-@@ -691,7 +691,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args,
- 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;
-diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
-index 78175aac2..619db3122 100644
---- a/grub-core/kern/parser.c
-+++ b/grub-core/kern/parser.c
-@@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *cmdline,
- 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);
-diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c
-index be4816fe6..aac8f9ae1 100644
---- a/grub-core/kern/uboot/uboot.c
-+++ b/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;
-
-diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c
-index f5e946a2d..63f6fcd11 100644
---- a/grub-core/lib/libgcrypt/cipher/ac.c
-+++ b/grub-core/lib/libgcrypt/cipher/ac.c
-@@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
- 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 data, gcry_sexp_t *sexp,
- }
-
- /* 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 *identifier, int include_flags,
- /* 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_handle_t handle, unsigned int nbits,
- 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);
-diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c
-index 2788e349f..b12e79b19 100644
---- a/grub-core/lib/libgcrypt/cipher/primegen.c
-+++ b/grub-core/lib/libgcrypt/cipher/primegen.c
-@@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor,
- }
-
- /* 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 secret, int randomlevel,
- 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);
-diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c
-index 910982141..ca087ad75 100644
---- a/grub-core/lib/libgcrypt/cipher/pubkey.c
-+++ b/grub-core/lib/libgcrypt/cipher/pubkey.c
-@@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
- * 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_sexp_t s_hash, gcry_sexp_t s_skey)
- }
- 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 ();
-diff --git a/grub-core/lib/priority_queue.c b/grub-core/lib/priority_queue.c
-index 659be0b7f..7d5e7c05a 100644
---- a/grub-core/lib/priority_queue.c
-+++ b/grub-core/lib/priority_queue.c
-@@ -92,7 +92,7 @@ grub_priority_queue_new (grub_size_t elsize,
- {
- 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));
-diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c
-index ee9fa7b4f..467305b46 100644
---- a/grub-core/lib/reed_solomon.c
-+++ b/grub-core/lib/reed_solomon.c
-@@ -20,6 +20,7 @@
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-+#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_t s, grub_size_t rs)
- 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++)
-diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
-index ea3ebc719..5847aac36 100644
---- a/grub-core/lib/relocator.c
-+++ b/grub-core/lib/relocator.c
-@@ -495,9 +495,9 @@ malloc_in_range (struct grub_relocator *rel,
- }
- #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 *rel,
- #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 grub_relocator *rel, grub_addr_t addr,
- 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);
-diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c
-index 72bbead5b..2227b84bc 100644
---- a/grub-core/lib/zstd/fse_decompress.c
-+++ b/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)
-diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c
-index 092e8e307..979d425df 100644
---- a/grub-core/loader/arm/linux.c
-+++ b/grub-core/loader/arm/linux.c
-@@ -82,7 +82,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;
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index cd92ea3f2..daf8c6b54 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -116,7 +116,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
- 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;
-
-diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c
-index af6741d15..a8d8bf7da 100644
---- a/grub-core/loader/i386/bsdXX.c
-+++ b/grub-core/loader/i386/bsdXX.c
-@@ -48,7 +48,7 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr)
- 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;
-
-diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
-index e64ed08f5..b7d176b5d 100644
---- a/grub-core/loader/i386/xnu.c
-+++ b/grub-core/loader/i386/xnu.c
-@@ -295,7 +295,7 @@ grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *d
- 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 (struct grub_xnu_devprop_device_descriptor *
- 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);
-diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c
-index 085f9c689..05710c48e 100644
---- a/grub-core/loader/macho.c
-+++ b/grub-core/loader/macho.c
-@@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const char *filename, int is_64bit)
- 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,
-diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
-index 70cd1db51..cc6853692 100644
---- a/grub-core/loader/multiboot_elfxx.c
-+++ b/grub-core/loader/multiboot_elfxx.c
-@@ -217,7 +217,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
- {
- 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;
-
-diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
-index 7f74d1d6f..77d7060e1 100644
---- a/grub-core/loader/xnu.c
-+++ b/grub-core/loader/xnu.c
-@@ -800,7 +800,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
- 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);
-diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
-index 6a31cbae3..57b4e9a72 100644
---- a/grub-core/mmap/mmap.c
-+++ b/grub-core/mmap/mmap.c
-@@ -143,9 +143,9 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
-
- /* 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)
- {
-diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
-index 558d97ba1..dd0ffcdae 100644
---- a/grub-core/net/bootp.c
-+++ b/grub-core/net/bootp.c
-@@ -1559,7 +1559,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)),
- 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;
-
-diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
-index 5d9afe093..e332d5eb4 100644
---- a/grub-core/net/dns.c
-+++ b/grub-core/net/dns.c
-@@ -285,8 +285,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
- 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 __attribute__ ((unused)),
- 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;
-
-diff --git a/grub-core/net/net.c b/grub-core/net/net.c
-index b917a75d5..fed7bc57c 100644
---- a/grub-core/net/net.c
-+++ b/grub-core/net/net.c
-@@ -333,8 +333,8 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)),
- 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);
-diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
-index b0ab47d73..d57fb72fa 100644
---- a/grub-core/normal/charset.c
-+++ b/grub-core/normal/charset.c
-@@ -203,7 +203,7 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_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_uint32_t *in, grub_size_t inlen,
- }
- 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 grub_uint32_t *logical,
- } \
- }
-
-- 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_uint32_t *logical,
- {
- 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++)
-diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
-index c037d5050..c57242e2e 100644
---- a/grub-core/normal/cmdline.c
-+++ b/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_translated)
- 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_translated)
- 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_translated)
- }
- 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_translated)
- 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_translated)
-
- 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 ();
-diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
-index cdf3590a3..1993995be 100644
---- a/grub-core/normal/menu_entry.c
-+++ b/grub-core/normal/menu_entry.c
-@@ -95,8 +95,8 @@ init_line (struct screen *screen, struct line *linep)
- {
- 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, struct per_term_screen *term_screen,
- 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, const char *s, int update)
-
- /* 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 continuous, int update)
- 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 entry)
- 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 entry)
- }
- }
-
-- 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 ();
-diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
-index e22bb91f6..18240e76c 100644
---- a/grub-core/normal/menu_text.c
-+++ b/grub-core/normal/menu_text.c
-@@ -78,7 +78,7 @@ grub_print_message_indented_real (const char *msg, int margin_left,
- 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;
-@@ -211,7 +211,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
-
- title = entry ? entry->title : "";
- title_len = grub_strlen (title);
-- 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;
-diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
-index a1e5c5a0d..cc8c173b6 100644
---- a/grub-core/normal/term.c
-+++ b/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_t msg_len)
-
- 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 ();
-
-diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
-index 7adc0f30e..a5bd0752f 100644
---- a/grub-core/osdep/linux/getroot.c
-+++ b/grub-core/osdep/linux/getroot.c
-@@ -168,7 +168,7 @@ grub_util_raid_getmembers (const char *name, int bootable)
- 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++)
- {
-@@ -241,7 +241,7 @@ grub_find_root_devices_from_btrfs (const char *dir)
- 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++)
- {
-@@ -396,7 +396,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot)
- 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");
-diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c
-index 661d95461..eada663b2 100644
---- a/grub-core/osdep/windows/getroot.c
-+++ b/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
-diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c
-index 355100789..0be327394 100644
---- a/grub-core/osdep/windows/hostdisk.c
-+++ b/grub-core/osdep/windows/hostdisk.c
-@@ -111,7 +111,7 @@ grub_util_get_windows_path_real (const char *path)
-
- 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] = '*';
-diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c
-index e8ffd62c6..6297de632 100644
---- a/grub-core/osdep/windows/init.c
-+++ b/grub-core/osdep/windows/init.c
-@@ -161,7 +161,7 @@ grub_util_host_init (int *argc __attribute__ ((unused)),
- 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]);
-diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
-index e19a3d9a8..cb626c8c3 100644
---- a/grub-core/osdep/windows/platform.c
-+++ b/grub-core/osdep/windows/platform.c
-@@ -231,8 +231,8 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
- 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);
-diff --git a/grub-core/osdep/windows/relpath.c b/grub-core/osdep/windows/relpath.c
-index cb0861744..478e8ef14 100644
---- a/grub-core/osdep/windows/relpath.c
-+++ b/grub-core/osdep/windows/relpath.c
-@@ -72,7 +72,7 @@ grub_make_system_path_relative_to_its_root (const char *path)
- 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])
-diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c
-index 103f6796f..72a2e37cd 100644
---- a/grub-core/partmap/gpt.c
-+++ b/grub-core/partmap/gpt.c
-@@ -199,7 +199,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
- *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++)
-diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c
-index 7b8e45076..ee3f24982 100644
---- a/grub-core/partmap/msdos.c
-+++ b/grub-core/partmap/msdos.c
-@@ -337,7 +337,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
- 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++)
-diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
-index ee299fd0e..c8d6806fe 100644
---- a/grub-core/script/execute.c
-+++ b/grub-core/script/execute.c
-@@ -553,7 +553,7 @@ gettext_append (struct grub_script_argv *result, const char *orig_str)
- 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;
-diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c
-index 2d6085298..b5eb516be 100644
---- a/grub-core/tests/fake_input.c
-+++ b/grub-core/tests/fake_input.c
-@@ -49,7 +49,7 @@ grub_terminal_input_fake_sequence (int *seq_in, int nseq_in)
- 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;
-
-diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c
-index 74d5b65e5..44d081069 100644
---- a/grub-core/tests/video_checksum.c
-+++ b/grub-core/tests/video_checksum.c
-@@ -336,7 +336,7 @@ grub_video_capture_write_bmp (const char *fname,
- {
- 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 *fname,
- }
- 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 *fname,
- }
- 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);
-diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c
-index 4f83c7441..4d3195e01 100644
---- a/grub-core/video/capture.c
-+++ b/grub-core/video/capture.c
-@@ -89,7 +89,7 @@ grub_video_capture_start (const struct grub_video_mode_info *mode_info,
- 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;
-
-diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c
-index a2f639f66..0ebab6f57 100644
---- a/grub-core/video/emu/sdl.c
-+++ b/grub-core/video/emu/sdl.c
-@@ -172,7 +172,7 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count,
- 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;
-diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c
-index 01f47112d..b2f776c99 100644
---- a/grub-core/video/i386/pc/vga.c
-+++ b/grub-core/video/i386/pc/vga.c
-@@ -127,7 +127,7 @@ grub_video_vga_setup (unsigned int width, unsigned int height,
-
- 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)
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index 777e71334..61bd64537 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -309,7 +309,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
- 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;
-
-diff --git a/include/grub/unicode.h b/include/grub/unicode.h
-index a0403e91f..4de986a85 100644
---- a/include/grub/unicode.h
-+++ b/include/grub/unicode.h
-@@ -293,7 +293,7 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
- 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_unicode_glyph *out,
- 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,
-diff --git a/util/getroot.c b/util/getroot.c
-index cdd41153c..6ae35ecaa 100644
---- a/util/getroot.c
-+++ b/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++)
- {
-diff --git a/util/grub-file.c b/util/grub-file.c
-index 50c18b683..b2e7dd69f 100644
---- a/util/grub-file.c
-+++ b/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)
- {
-diff --git a/util/grub-fstest.c b/util/grub-fstest.c
-index f14e02d97..57246af7c 100644
---- a/util/grub-fstest.c
-+++ b/util/grub-fstest.c
-@@ -650,7 +650,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
- 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);
-
-diff --git a/util/grub-install-common.c b/util/grub-install-common.c
-index fdfe2c7ea..447504d3f 100644
---- a/util/grub-install-common.c
-+++ b/util/grub-install-common.c
-@@ -286,7 +286,7 @@ handle_install_list (struct install_list *il, const char *val,
- 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++)
- {
-diff --git a/util/grub-install.c b/util/grub-install.c
-index 666cef3d2..bd6d8dbb3 100644
---- a/util/grub-install.c
-+++ b/util/grub-install.c
-@@ -655,7 +655,7 @@ device_map_check_duplicates (const char *dev_map)
- if (! fp)
- return;
-
-- d = xmalloc (alloced * sizeof (d[0]));
-+ d = xcalloc (alloced, sizeof (d[0]));
-
- while (fgets (buf, sizeof (buf), fp))
- {
-@@ -1374,7 +1374,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++)
-diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
-index bc087c2b5..d97d0e7be 100644
---- a/util/grub-mkimagexx.c
-+++ b/util/grub-mkimagexx.c
-@@ -2294,10 +2294,8 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
- + 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);
-
-diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
-index 45d6140d3..cb972f120 100644
---- a/util/grub-mkrescue.c
-+++ b/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 */
-diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
-index 4907d44c0..edf309717 100644
---- a/util/grub-mkstandalone.c
-+++ b/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);
-
-diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c
-index 0d4084a10..11331294f 100644
---- a/util/grub-pe2elf.c
-+++ b/util/grub-pe2elf.c
-@@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char *name, char *image,
- 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 char *name, char *image,
-
- 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 *name, char *image,
- 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)
-diff --git a/util/grub-probe.c b/util/grub-probe.c
-index 81d27eead..cbe6ed94c 100644
---- a/util/grub-probe.c
-+++ b/util/grub-probe.c
-@@ -361,8 +361,8 @@ probe (const char *path, char **device_names, char delim)
- 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++)
-
-From d84e89f4734711d8ff3c84b6c58985c824b4d889 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Mon, 15 Jun 2020 12:28:27 -0400
-Subject: 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 <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/commands/legacycfg.c | 29 +++++++++++++++----
- grub-core/commands/wildcard.c | 36 ++++++++++++++++++++----
- grub-core/disk/ldm.c | 32 +++++++++++++++------
- grub-core/font/font.c | 7 ++++-
- grub-core/fs/btrfs.c | 28 +++++++++++++------
- grub-core/fs/ext2.c | 10 ++++++-
- grub-core/fs/iso9660.c | 51 ++++++++++++++++++++++++----------
- grub-core/fs/sfs.c | 27 ++++++++++++++----
- grub-core/fs/squash4.c | 45 ++++++++++++++++++++++--------
- grub-core/fs/udf.c | 41 +++++++++++++++++----------
- grub-core/fs/xfs.c | 11 +++++---
- grub-core/fs/zfs/zfs.c | 22 ++++++++++-----
- grub-core/fs/zfs/zfscrypt.c | 7 ++++-
- grub-core/lib/arg.c | 20 +++++++++++--
- grub-core/loader/i386/bsd.c | 8 +++++-
- grub-core/net/dns.c | 9 +++++-
- grub-core/normal/charset.c | 10 +++++--
- grub-core/normal/cmdline.c | 14 ++++++++--
- grub-core/normal/menu_entry.c | 13 +++++++--
- grub-core/script/argv.c | 16 +++++++++--
- grub-core/script/lexer.c | 21 ++++++++++++--
- grub-core/video/bitmap.c | 25 +++++++++++------
- grub-core/video/readers/png.c | 13 +++++++--
- 23 files changed, 382 insertions(+), 113 deletions(-)
-
-diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
-index 5e3ec0d5e..cc5971f4d 100644
---- a/grub-core/commands/legacycfg.c
-+++ b/grub-core/commands/legacycfg.c
-@@ -32,6 +32,7 @@
- #include <grub/auth.h>
- #include <grub/disk.h>
- #include <grub/partition.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -104,13 +105,22 @@ legacy_file (const char *filename)
- if (newsuffix)
- {
- char *t;
--
-+ grub_size_t sz;
-+
-+ if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) ||
-+ grub_add (sz, 1, &sz))
-+ {
-+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
-+ goto fail_0;
-+ }
-+
- t = suffix;
-- suffix = grub_realloc (suffix, grub_strlen (suffix)
-- + grub_strlen (newsuffix) + 1);
-+ suffix = grub_realloc (suffix, sz);
- if (!suffix)
- {
- grub_free (t);
-+
-+ fail_0:
- grub_free (entrysrc);
- grub_free (parsed);
- grub_free (newsuffix);
-@@ -154,13 +164,22 @@ legacy_file (const char *filename)
- else
- {
- char *t;
-+ grub_size_t sz;
-+
-+ if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) ||
-+ grub_add (sz, 1, &sz))
-+ {
-+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
-+ goto fail_1;
-+ }
-
- t = entrysrc;
-- entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
-- + grub_strlen (parsed) + 1);
-+ entrysrc = grub_realloc (entrysrc, sz);
- if (!entrysrc)
- {
- grub_free (t);
-+
-+ fail_1:
- grub_free (parsed);
- grub_free (suffix);
- return grub_errno;
-diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
-index 4a106ca04..cc3290311 100644
---- a/grub-core/commands/wildcard.c
-+++ b/grub-core/commands/wildcard.c
-@@ -23,6 +23,7 @@
- #include <grub/file.h>
- #include <grub/device.h>
- #include <grub/script_sh.h>
-+#include <grub/safemath.h>
-
- #include <regex.h>
-
-@@ -48,6 +49,7 @@ merge (char **dest, char **ps)
- int i;
- int j;
- char **p;
-+ grub_size_t sz;
-
- if (! dest)
- return ps;
-@@ -60,7 +62,12 @@ merge (char **dest, char **ps)
- for (j = 0; ps[j]; j++)
- ;
-
-- p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
-+ if (grub_add (i, j, &sz) ||
-+ grub_add (sz, 1, &sz) ||
-+ grub_mul (sz, sizeof (char *), &sz))
-+ return dest;
-+
-+ p = grub_realloc (dest, sz);
- if (! p)
- {
- grub_free (dest);
-@@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp)
- char ch;
- int i = 0;
- unsigned len = end - start;
-- char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
-+ char *buffer;
-+ grub_size_t sz;
-
-+ /* Worst case size is (len * 2 + 2 + 1). */
-+ if (grub_mul (len, 2, &sz) ||
-+ grub_add (sz, 3, &sz))
-+ return 1;
-+
-+ buffer = grub_malloc (sz);
- if (! buffer)
- return 1;
-
-@@ -226,6 +240,7 @@ match_devices_iter (const char *name, void *data)
- struct match_devices_ctx *ctx = data;
- char **t;
- char *buffer;
-+ grub_size_t sz;
-
- /* skip partitions if asked to. */
- if (ctx->noparts && grub_strchr (name, ','))
-@@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data)
- if (regexec (ctx->regexp, buffer, 0, 0, 0))
- {
- grub_dprintf ("expand", "not matched\n");
-+ fail:
- grub_free (buffer);
- return 0;
- }
-
-- t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2));
-+ if (grub_add (ctx->ndev, 2, &sz) ||
-+ grub_mul (sz, sizeof (char *), &sz))
-+ goto fail;
-+
-+ t = grub_realloc (ctx->devs, sz);
- if (! t)
- {
- grub_free (buffer);
-@@ -300,6 +320,7 @@ match_files_iter (const char *name,
- struct match_files_ctx *ctx = data;
- char **t;
- char *buffer;
-+ grub_size_t sz;
-
- /* skip . and .. names */
- if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
-@@ -315,9 +336,14 @@ match_files_iter (const char *name,
- if (! buffer)
- return 1;
-
-- t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2));
-- if (! t)
-+ if (grub_add (ctx->nfile, 2, &sz) ||
-+ grub_mul (sz, sizeof (char *), &sz))
-+ goto fail;
-+
-+ t = grub_realloc (ctx->files, sz);
-+ if (!t)
- {
-+ fail:
- grub_free (buffer);
- return 1;
- }
-diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
-index e6323701a..58f8a53e1 100644
---- a/grub-core/disk/ldm.c
-+++ b/grub-core/disk/ldm.c
-@@ -25,6 +25,7 @@
- #include <grub/msdos_partition.h>
- #include <grub/gpt_partition.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- #ifdef GRUB_UTIL
- #include <grub/emu/misc.h>
-@@ -289,6 +290,7 @@ make_vg (grub_disk_t disk,
- struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
- / sizeof (struct grub_ldm_vblk)];
- unsigned i;
-+ grub_size_t sz;
- err = grub_disk_read (disk, cursec, 0,
- sizeof(vblk), &vblk);
- if (err)
-@@ -350,7 +352,13 @@ make_vg (grub_disk_t disk,
- grub_free (lv);
- goto fail2;
- }
-- lv->name = grub_malloc (*ptr + 1);
-+ if (grub_add (*ptr, 1, &sz))
-+ {
-+ grub_free (lv->internal_id);
-+ grub_free (lv);
-+ goto fail2;
-+ }
-+ lv->name = grub_malloc (sz);
- if (!lv->name)
- {
- grub_free (lv->internal_id);
-@@ -599,10 +607,13 @@ make_vg (grub_disk_t disk,
- if (lv->segments->node_alloc == lv->segments->node_count)
- {
- void *t;
-- lv->segments->node_alloc *= 2;
-- t = grub_realloc (lv->segments->nodes,
-- sizeof (*lv->segments->nodes)
-- * lv->segments->node_alloc);
-+ grub_size_t sz;
-+
-+ if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
-+ grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
-+ goto fail2;
-+
-+ t = grub_realloc (lv->segments->nodes, sz);
- if (!t)
- goto fail2;
- lv->segments->nodes = t;
-@@ -723,10 +734,13 @@ make_vg (grub_disk_t disk,
- if (comp->segment_alloc == comp->segment_count)
- {
- void *t;
-- comp->segment_alloc *= 2;
-- t = grub_realloc (comp->segments,
-- comp->segment_alloc
-- * sizeof (*comp->segments));
-+ grub_size_t sz;
-+
-+ if (grub_mul (comp->segment_alloc, 2, &comp->segment_alloc) ||
-+ grub_mul (comp->segment_alloc, sizeof (*comp->segments), &sz))
-+ goto fail2;
-+
-+ t = grub_realloc (comp->segments, sz);
- if (!t)
- goto fail2;
- comp->segments = t;
-diff --git a/grub-core/font/font.c b/grub-core/font/font.c
-index 8e118b315..5edb477ac 100644
---- a/grub-core/font/font.c
-+++ b/grub-core/font/font.c
-@@ -30,6 +30,7 @@
- #include <grub/unicode.h>
- #include <grub/fontformat.h>
- #include <grub/env.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -360,9 +361,13 @@ static char *
- read_section_as_string (struct font_file_section *section)
- {
- char *str;
-+ grub_size_t sz;
- grub_ssize_t ret;
-
-- str = grub_malloc (section->length + 1);
-+ if (grub_add (section->length, 1, &sz))
-+ return NULL;
-+
-+ str = grub_malloc (sz);
- if (!str)
- return 0;
-
-diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
-index 4b8380439..27339bdb3 100644
---- a/grub-core/fs/btrfs.c
-+++ b/grub-core/fs/btrfs.c
-@@ -40,6 +40,7 @@
- #include <grub/btrfs.h>
- #include <grub/crypto.h>
- #include <grub/diskfilter.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -331,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc,
- if (desc->allocated < desc->depth)
- {
- void *newdata;
-- desc->allocated *= 2;
-- newdata = grub_realloc (desc->data, sizeof (desc->data[0])
-- * desc->allocated);
-+ grub_size_t sz;
-+
-+ if (grub_mul (desc->allocated, 2, &desc->allocated) ||
-+ grub_mul (desc->allocated, sizeof (desc->data[0]), &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ newdata = grub_realloc (desc->data, sz);
- if (!newdata)
- return grub_errno;
- desc->data = newdata;
-@@ -624,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id)
- if (data->n_devices_attached > data->n_devices_allocated)
- {
- void *tmp;
-- data->n_devices_allocated = 2 * data->n_devices_attached + 1;
-- data->devices_attached
-- = grub_realloc (tmp = data->devices_attached,
-- data->n_devices_allocated
-- * sizeof (data->devices_attached[0]));
-+ grub_size_t sz;
-+
-+ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
-+ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
-+ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
-+ goto fail;
-+
-+ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
- if (!data->devices_attached)
- {
-+ data->devices_attached = tmp;
-+
-+ fail:
- if (ctx.dev_found)
- grub_device_close (ctx.dev_found);
-- data->devices_attached = tmp;
- return NULL;
- }
- }
-diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
-index 9b389802a..ac33bcd68 100644
---- a/grub-core/fs/ext2.c
-+++ b/grub-core/fs/ext2.c
-@@ -46,6 +46,7 @@
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/fshelp.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
- {
- char *symlink;
- struct grub_fshelp_node *diro = node;
-+ grub_size_t sz;
-
- if (! diro->inode_read)
- {
-@@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node)
- }
- }
-
-- symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
-+ if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz))
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+ return NULL;
-+ }
-+
-+ symlink = grub_malloc (sz);
- if (! symlink)
- return 0;
-
-diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
-index 4f1b52a55..7ba5b300b 100644
---- a/grub-core/fs/iso9660.c
-+++ b/grub-core/fs/iso9660.c
-@@ -28,6 +28,7 @@
- #include <grub/fshelp.h>
- #include <grub/charset.h>
- #include <grub/datetime.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -531,8 +532,13 @@ add_part (struct iterate_dir_ctx *ctx,
- int len2)
- {
- int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0;
-+ grub_size_t sz;
-
-- ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1);
-+ if (grub_add (size, len2, &sz) ||
-+ grub_add (sz, 1, &sz))
-+ return;
-+
-+ ctx->symlink = grub_realloc (ctx->symlink, sz);
- if (! ctx->symlink)
- return;
-
-@@ -560,17 +566,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
- {
- grub_size_t off = 0, csize = 1;
- char *old;
-+ grub_size_t sz;
-+
- csize = entry->len - 5;
- old = ctx->filename;
- if (ctx->filename_alloc)
- {
- off = grub_strlen (ctx->filename);
-- ctx->filename = grub_realloc (ctx->filename, csize + off + 1);
-+ if (grub_add (csize, off, &sz) ||
-+ grub_add (sz, 1, &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+ ctx->filename = grub_realloc (ctx->filename, sz);
- }
- else
- {
- off = 0;
-- ctx->filename = grub_zalloc (csize + 1);
-+ if (grub_add (csize, 1, &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+ ctx->filename = grub_zalloc (sz);
- }
- if (!ctx->filename)
- {
-@@ -776,14 +789,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
- if (node->have_dirents >= node->alloc_dirents)
- {
- struct grub_fshelp_node *new_node;
-- node->alloc_dirents *= 2;
-- new_node = grub_realloc (node,
-- sizeof (struct grub_fshelp_node)
-- + ((node->alloc_dirents
-- - ARRAY_SIZE (node->dirents))
-- * sizeof (node->dirents[0])));
-+ grub_size_t sz;
-+
-+ if (grub_mul (node->alloc_dirents, 2, &node->alloc_dirents) ||
-+ grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
-+ grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
-+ grub_add (sz, sizeof (struct grub_fshelp_node), &sz))
-+ goto fail_0;
-+
-+ new_node = grub_realloc (node, sz);
- if (!new_node)
- {
-+ fail_0:
- if (ctx.filename_alloc)
- grub_free (ctx.filename);
- grub_free (node);
-@@ -799,14 +816,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
- * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1)
- {
- struct grub_fshelp_node *new_node;
-- new_node = grub_realloc (node,
-- sizeof (struct grub_fshelp_node)
-- + ((node->alloc_dirents
-- - ARRAY_SIZE (node->dirents))
-- * sizeof (node->dirents[0]))
-- + grub_strlen (ctx.symlink) + 1);
-+ grub_size_t sz;
-+
-+ if (grub_sub (node->alloc_dirents, ARRAY_SIZE (node->dirents), &sz) ||
-+ grub_mul (sz, sizeof (node->dirents[0]), &sz) ||
-+ grub_add (sz, sizeof (struct grub_fshelp_node) + 1, &sz) ||
-+ grub_add (sz, grub_strlen (ctx.symlink), &sz))
-+ goto fail_1;
-+
-+ new_node = grub_realloc (node, sz);
- if (!new_node)
- {
-+ fail_1:
- if (ctx.filename_alloc)
- grub_free (ctx.filename);
- grub_free (node);
-diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
-index 90f7fb379..de2b107a4 100644
---- a/grub-core/fs/sfs.c
-+++ b/grub-core/fs/sfs.c
-@@ -26,6 +26,7 @@
- #include <grub/types.h>
- #include <grub/fshelp.h>
- #include <grub/charset.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -307,10 +308,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
- if (node->cache && node->cache_size >= node->cache_allocated)
- {
- struct cache_entry *e = node->cache;
-- e = grub_realloc (node->cache,node->cache_allocated * 2
-- * sizeof (e[0]));
-+ grub_size_t sz;
-+
-+ if (grub_mul (node->cache_allocated, 2 * sizeof (e[0]), &sz))
-+ goto fail;
-+
-+ e = grub_realloc (node->cache, sz);
- if (!e)
- {
-+ fail:
- grub_errno = 0;
- grub_free (node->cache);
- node->cache = 0;
-@@ -477,10 +483,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node,
- grub_size_t len = grub_strlen (name);
- grub_uint8_t *name_u8;
- int ret;
-+ grub_size_t sz;
-+
-+ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
-+ grub_add (sz, 1, &sz))
-+ return 1;
-+
- *node = grub_malloc (sizeof (**node));
- if (!*node)
- return 1;
-- name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
-+ name_u8 = grub_malloc (sz);
- if (!name_u8)
- {
- grub_free (*node);
-@@ -724,8 +736,13 @@ grub_sfs_label (grub_device_t device, char **label)
- data = grub_sfs_mount (disk);
- if (data)
- {
-- grub_size_t len = grub_strlen (data->label);
-- *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1);
-+ grub_size_t sz, len = grub_strlen (data->label);
-+
-+ if (grub_mul (len, GRUB_MAX_UTF8_PER_LATIN1, &sz) ||
-+ grub_add (sz, 1, &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ *label = grub_malloc (sz);
- if (*label)
- *grub_latin1_to_utf8 ((grub_uint8_t *) *label,
- (const grub_uint8_t *) data->label,
-diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
-index 95d5c1e1f..785123894 100644
---- a/grub-core/fs/squash4.c
-+++ b/grub-core/fs/squash4.c
-@@ -26,6 +26,7 @@
- #include <grub/types.h>
- #include <grub/fshelp.h>
- #include <grub/deflate.h>
-+#include <grub/safemath.h>
- #include <minilzo.h>
-
- #include "xz.h"
-@@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
- {
- char *ret;
- grub_err_t err;
-- ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1);
-+ grub_size_t sz;
-+
-+ if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+ return NULL;
-+ }
-+
-+ ret = grub_malloc (sz);
-+ if (!ret)
-+ return NULL;
-
- err = read_chunk (node->data, ret,
- grub_le_to_cpu32 (node->ino.symlink.namelen),
-@@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
-
- {
- grub_fshelp_node_t node;
-- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
-+ grub_size_t sz;
-+
-+ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
-+ grub_add (sz, sizeof (*node), &sz))
-+ return 0;
-+
-+ node = grub_malloc (sz);
- if (!node)
- return 0;
-- grub_memcpy (node, dir,
-- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
-+ grub_memcpy (node, dir, sz);
- if (hook (".", GRUB_FSHELP_DIR, node, hook_data))
- return 1;
-
-@@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
- {
- grub_err_t err;
-
-- node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
-+ if (grub_mul (dir->stsize, sizeof (dir->stack[0]), &sz) ||
-+ grub_add (sz, sizeof (*node), &sz))
-+ return 0;
-+
-+ node = grub_malloc (sz);
- if (!node)
- return 0;
-
-- grub_memcpy (node, dir,
-- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
-+ grub_memcpy (node, dir, sz);
-
- node->stsize--;
- err = read_chunk (dir->data, &node->ino, sizeof (node->ino),
-@@ -557,6 +576,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
- enum grub_fshelp_filetype filetype = GRUB_FSHELP_REG;
- struct grub_squash_dirent di;
- struct grub_squash_inode ino;
-+ grub_size_t sz;
-
- err = read_chunk (dir->data, &di, sizeof (di),
- grub_le_to_cpu64 (dir->data->sb.diroffset)
-@@ -589,13 +609,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
- if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK)
- filetype = GRUB_FSHELP_SYMLINK;
-
-- node = grub_malloc (sizeof (*node)
-- + (dir->stsize + 1) * sizeof (dir->stack[0]));
-+ if (grub_add (dir->stsize, 1, &sz) ||
-+ grub_mul (sz, sizeof (dir->stack[0]), &sz) ||
-+ grub_add (sz, sizeof (*node), &sz))
-+ return 0;
-+
-+ node = grub_malloc (sz);
- if (! node)
- return 0;
-
-- grub_memcpy (node, dir,
-- sizeof (*node) + dir->stsize * sizeof (dir->stack[0]));
-+ grub_memcpy (node, dir, sz - sizeof(dir->stack[0]));
-
- node->ino = ino;
- node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk);
-diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
-index a83761674..21ac7f446 100644
---- a/grub-core/fs/udf.c
-+++ b/grub-core/fs/udf.c
-@@ -28,6 +28,7 @@
- #include <grub/charset.h>
- #include <grub/datetime.h>
- #include <grub/udf.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -890,9 +891,19 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf)
- utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2];
- }
- if (!outbuf)
-- outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1);
-+ {
-+ grub_size_t size;
-+
-+ if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) ||
-+ grub_add (size, 1, &size))
-+ goto fail;
-+
-+ outbuf = grub_malloc (size);
-+ }
- if (outbuf)
- *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
-+
-+ fail:
- grub_free (utf16);
- return outbuf;
- }
-@@ -1005,7 +1016,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- grub_size_t sz = U64 (node->block.fe.file_size);
- grub_uint8_t *raw;
- const grub_uint8_t *ptr;
-- char *out, *optr;
-+ char *out = NULL, *optr;
-
- if (sz < 4)
- return NULL;
-@@ -1013,14 +1024,16 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- if (!raw)
- return NULL;
- if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0)
-- {
-- grub_free (raw);
-- return NULL;
-- }
-+ goto fail_1;
-
-- out = grub_malloc (sz * 2 + 1);
-+ if (grub_mul (sz, 2, &sz) ||
-+ grub_add (sz, 1, &sz))
-+ goto fail_0;
-+
-+ out = grub_malloc (sz);
- if (!out)
- {
-+ fail_0:
- grub_free (raw);
- return NULL;
- }
-@@ -1031,17 +1044,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- {
- grub_size_t s;
- if ((grub_size_t) (ptr - raw + 4) > sz)
-- goto fail;
-+ goto fail_1;
- if (!(ptr[2] == 0 && ptr[3] == 0))
-- goto fail;
-+ goto fail_1;
- s = 4 + ptr[1];
- if ((grub_size_t) (ptr - raw + s) > sz)
-- goto fail;
-+ goto fail_1;
- switch (*ptr)
- {
- case 1:
- if (ptr[1])
-- goto fail;
-+ goto fail_1;
- /* Fallthrough. */
- case 2:
- /* in 4 bytes. out: 1 byte. */
-@@ -1066,11 +1079,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- if (optr != out)
- *optr++ = '/';
- if (!read_string (ptr + 4, s - 4, optr))
-- goto fail;
-+ goto fail_1;
- optr += grub_strlen (optr);
- break;
- default:
-- goto fail;
-+ goto fail_1;
- }
- ptr += s;
- }
-@@ -1078,7 +1091,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node)
- grub_free (raw);
- return out;
-
-- fail:
-+ fail_1:
- grub_free (raw);
- grub_free (out);
- grub_error (GRUB_ERR_BAD_FS, "invalid symlink");
-diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
-index 96ffecbfc..ea6590290 100644
---- a/grub-core/fs/xfs.c
-+++ b/grub-core/fs/xfs.c
-@@ -25,6 +25,7 @@
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/fshelp.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -899,6 +900,7 @@ static struct grub_xfs_data *
- grub_xfs_mount (grub_disk_t disk)
- {
- struct grub_xfs_data *data = 0;
-+ grub_size_t sz;
-
- data = grub_zalloc (sizeof (struct grub_xfs_data));
- if (!data)
-@@ -913,10 +915,11 @@ grub_xfs_mount (grub_disk_t disk)
- if (!grub_xfs_sb_valid(data))
- goto fail;
-
-- data = grub_realloc (data,
-- sizeof (struct grub_xfs_data)
-- - sizeof (struct grub_xfs_inode)
-- + grub_xfs_inode_size(data) + 1);
-+ if (grub_add (grub_xfs_inode_size (data),
-+ sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
-+ goto fail;
-+
-+ data = grub_realloc (data, sz);
-
- if (! data)
- goto fail;
-diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
-index 381dde556..36d0373a6 100644
---- a/grub-core/fs/zfs/zfs.c
-+++ b/grub-core/fs/zfs/zfs.c
-@@ -55,6 +55,7 @@
- #include <grub/deflate.h>
- #include <grub/crypto.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -773,11 +774,14 @@ fill_vdev_info (struct grub_zfs_data *data,
- if (data->n_devices_attached > data->n_devices_allocated)
- {
- void *tmp;
-- data->n_devices_allocated = 2 * data->n_devices_attached + 1;
-- data->devices_attached
-- = grub_realloc (tmp = data->devices_attached,
-- data->n_devices_allocated
-- * sizeof (data->devices_attached[0]));
-+ grub_size_t sz;
-+
-+ if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) ||
-+ grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) ||
-+ grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ data->devices_attached = grub_realloc (tmp = data->devices_attached, sz);
- if (!data->devices_attached)
- {
- data->devices_attached = tmp;
-@@ -3468,14 +3472,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name)
- {
- char *nvpair;
- char *ret;
-- grub_size_t size;
-+ grub_size_t size, sz;
- int found;
-
- found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
- &size, 0);
- if (!found)
- return 0;
-- ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t));
-+
-+ if (grub_add (size, 3 * sizeof (grub_uint32_t), &sz))
-+ return 0;
-+
-+ ret = grub_zalloc (sz);
- if (!ret)
- return 0;
- grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
-diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c
-index 1402e0bc2..de3b015f5 100644
---- a/grub-core/fs/zfs/zfscrypt.c
-+++ b/grub-core/fs/zfs/zfscrypt.c
-@@ -22,6 +22,7 @@
- #include <grub/misc.h>
- #include <grub/disk.h>
- #include <grub/partition.h>
-+#include <grub/safemath.h>
- #include <grub/dl.h>
- #include <grub/types.h>
- #include <grub/zfs/zfs.h>
-@@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in,
- int passphrase)
- {
- struct grub_zfs_wrap_key *key;
-+ grub_size_t sz;
-+
- if (!passphrase && keylen > 32)
- keylen = 32;
-- key = grub_malloc (sizeof (*key) + keylen);
-+ if (grub_add (sizeof (*key), keylen, &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+ key = grub_malloc (sz);
- if (!key)
- return grub_errno;
- key->is_passphrase = passphrase;
-diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
-index fd7744a6f..3288609a5 100644
---- a/grub-core/lib/arg.c
-+++ b/grub-core/lib/arg.c
-@@ -23,6 +23,7 @@
- #include <grub/term.h>
- #include <grub/extcmd.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- /* Built-in parser for default options. */
- static const struct grub_arg_option help_options[] =
-@@ -216,7 +217,13 @@ static inline grub_err_t
- add_arg (char ***argl, int *num, char *s)
- {
- char **p = *argl;
-- *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *));
-+ grub_size_t sz;
-+
-+ if (grub_add (++(*num), 1, &sz) ||
-+ grub_mul (sz, sizeof (char *), &sz))
-+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+
-+ *argl = grub_realloc (*argl, sz);
- if (! *argl)
- {
- grub_free (p);
-@@ -431,6 +438,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
- grub_size_t argcnt;
- struct grub_arg_list *list;
- const struct grub_arg_option *options;
-+ grub_size_t sz0, sz1;
-
- options = extcmd->options;
- if (! options)
-@@ -443,7 +451,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc,
- argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */
- }
-
-- list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt);
-+ if (grub_mul (sizeof (*list), i, &sz0) ||
-+ grub_mul (sizeof (char *), argcnt, &sz1) ||
-+ grub_add (sz0, sz1, &sz0))
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+ return 0;
-+ }
-+
-+ list = grub_zalloc (sz0);
- if (! list)
- return 0;
-
-diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
-index 3730ed382..b92cbe98d 100644
---- a/grub-core/loader/i386/bsd.c
-+++ b/grub-core/loader/i386/bsd.c
-@@ -35,6 +35,7 @@
- #include <grub/ns8250.h>
- #include <grub/bsdlabel.h>
- #include <grub/crypto.h>
-+#include <grub/safemath.h>
- #include <grub/verify.h>
- #ifdef GRUB_MACHINE_PCBIOS
- #include <grub/machine/int.h>
-@@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void)
- struct grub_netbsd_btinfo_modules *mods;
- unsigned i;
- grub_err_t err;
-+ grub_size_t sz;
-
- for (mod = netbsd_mods; mod; mod = mod->next)
- modcnt++;
-
-- mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
-+ if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) ||
-+ grub_add (sz, sizeof (*mods), &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ mods = grub_malloc (sz);
- if (!mods)
- return grub_errno;
-
-diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
-index e332d5eb4..906ec7d67 100644
---- a/grub-core/net/dns.c
-+++ b/grub-core/net/dns.c
-@@ -22,6 +22,7 @@
- #include <grub/i18n.h>
- #include <grub/err.h>
- #include <grub/time.h>
-+#include <grub/safemath.h>
-
- struct dns_cache_element
- {
-@@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s)
- {
- int na = dns_servers_alloc * 2;
- struct grub_net_network_level_address *ns;
-+ grub_size_t sz;
-+
- if (na < 8)
- na = 8;
-- ns = grub_realloc (dns_servers, na * sizeof (ns[0]));
-+
-+ if (grub_mul (na, sizeof (ns[0]), &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ ns = grub_realloc (dns_servers, sz);
- if (!ns)
- return grub_errno;
- dns_servers_alloc = na;
-diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
-index d57fb72fa..4dfcc3107 100644
---- a/grub-core/normal/charset.c
-+++ b/grub-core/normal/charset.c
-@@ -48,6 +48,7 @@
- #include <grub/unicode.h>
- #include <grub/term.h>
- #include <grub/normal.h>
-+#include <grub/safemath.h>
-
- #if HAVE_FONT_SOURCE
- #include "widthspec.h"
-@@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
- {
- struct grub_unicode_combining *n;
- unsigned j;
-+ grub_size_t sz;
-
- if (!haveout)
- continue;
-@@ -477,10 +479,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
- n = out->combining_inline;
- else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
- {
-- n = grub_realloc (out->combining_ptr,
-- sizeof (n[0]) * (out->ncomb + 1));
-+ if (grub_add (out->ncomb, 1, &sz) ||
-+ grub_mul (sz, sizeof (n[0]), &sz))
-+ goto fail;
-+
-+ n = grub_realloc (out->combining_ptr, sz);
- if (!n)
- {
-+ fail:
- grub_errno = GRUB_ERR_NONE;
- continue;
- }
-diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c
-index c57242e2e..de03fe63b 100644
---- a/grub-core/normal/cmdline.c
-+++ b/grub-core/normal/cmdline.c
-@@ -28,6 +28,7 @@
- #include <grub/env.h>
- #include <grub/i18n.h>
- #include <grub/charset.h>
-+#include <grub/safemath.h>
-
- static grub_uint32_t *kill_buf;
-
-@@ -307,12 +308,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms,
- if (len + (*llen) >= (*max_len))
- {
- grub_uint32_t *nbuf;
-- (*max_len) *= 2;
-- nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len));
-+ grub_size_t sz;
-+
-+ if (grub_mul (*max_len, 2, max_len) ||
-+ grub_mul (*max_len, sizeof (grub_uint32_t), &sz))
-+ {
-+ grub_errno = GRUB_ERR_OUT_OF_RANGE;
-+ goto fail;
-+ }
-+
-+ nbuf = grub_realloc ((*buf), sz);
- if (nbuf)
- (*buf) = nbuf;
- else
- {
-+ fail:
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- (*max_len) /= 2;
-diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
-index 1993995be..50eef918c 100644
---- a/grub-core/normal/menu_entry.c
-+++ b/grub-core/normal/menu_entry.c
-@@ -27,6 +27,7 @@
- #include <grub/auth.h>
- #include <grub/i18n.h>
- #include <grub/charset.h>
-+#include <grub/safemath.h>
-
- enum update_mode
- {
-@@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra)
- {
- if (linep->max_len < linep->len + extra)
- {
-- linep->max_len = 2 * (linep->len + extra);
-- linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
-+ grub_size_t sz0, sz1;
-+
-+ if (grub_add (linep->len, extra, &sz0) ||
-+ grub_mul (sz0, 2, &sz0) ||
-+ grub_add (sz0, 1, &sz1) ||
-+ grub_mul (sz1, sizeof (linep->buf[0]), &sz1))
-+ return 0;
-+
-+ linep->buf = grub_realloc (linep->buf, sz1);
- if (! linep->buf)
- return 0;
-+ linep->max_len = sz0;
- }
-
- return 1;
-diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c
-index 217ec5d1e..5751fdd57 100644
---- a/grub-core/script/argv.c
-+++ b/grub-core/script/argv.c
-@@ -20,6 +20,7 @@
- #include <grub/mm.h>
- #include <grub/misc.h>
- #include <grub/script_sh.h>
-+#include <grub/safemath.h>
-
- /* Return nearest power of two that is >= v. */
- static unsigned
-@@ -81,11 +82,16 @@ int
- grub_script_argv_next (struct grub_script_argv *argv)
- {
- char **p = argv->args;
-+ grub_size_t sz;
-
- if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
- return 0;
-
-- p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
-+ if (grub_add (argv->argc, 2, &sz) ||
-+ grub_mul (sz, sizeof (char *), &sz))
-+ return 1;
-+
-+ p = grub_realloc (p, round_up_exp (sz));
- if (! p)
- return 1;
-
-@@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s,
- {
- grub_size_t a;
- char *p = argv->args[argv->argc - 1];
-+ grub_size_t sz;
-
- if (! s)
- return 0;
-
- a = p ? grub_strlen (p) : 0;
-
-- p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char)));
-+ if (grub_add (a, slen, &sz) ||
-+ grub_add (sz, 1, &sz) ||
-+ grub_mul (sz, sizeof (char), &sz))
-+ return 1;
-+
-+ p = grub_realloc (p, round_up_exp (sz));
- if (! p)
- return 1;
-
-diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
-index c6bd3172f..5fb0cbd0b 100644
---- a/grub-core/script/lexer.c
-+++ b/grub-core/script/lexer.c
-@@ -24,6 +24,7 @@
- #include <grub/mm.h>
- #include <grub/script_sh.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- #define yytext_ptr char *
- #include "grub_script.tab.h"
-@@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str)
- old = lexer->recording;
- if (lexer->recordlen < len)
- lexer->recordlen = len;
-- lexer->recordlen *= 2;
-+
-+ if (grub_mul (lexer->recordlen, 2, &lexer->recordlen))
-+ goto fail;
-+
- lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
- if (!lexer->recording)
- {
-+ fail:
- grub_free (old);
- lexer->recordpos = 0;
- lexer->recordlen = 0;
-@@ -130,7 +135,7 @@ int
- grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
- const char *input)
- {
-- grub_size_t len = 0;
-+ grub_size_t len = 0, sz;
- char *p = 0;
- char *line = 0;
- YY_BUFFER_STATE buffer;
-@@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
- }
- else if (len && line[len - 1] != '\n')
- {
-- p = grub_realloc (line, len + 2);
-+ if (grub_add (len, 2, &sz))
-+ {
-+ grub_free (line);
-+ grub_script_yyerror (parserstate, N_("overflow is detected"));
-+ return 1;
-+ }
-+
-+ p = grub_realloc (line, sz);
- if (p)
- {
- p[len++] = '\n';
- p[len] = '\0';
- }
-+ else
-+ grub_free (line);
-+
- line = p;
- }
-
-diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c
-index b2e031566..6256e209a 100644
---- a/grub-core/video/bitmap.c
-+++ b/grub-core/video/bitmap.c
-@@ -23,6 +23,7 @@
- #include <grub/mm.h>
- #include <grub/misc.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
- enum grub_video_blit_format blit_format)
- {
- struct grub_video_mode_info *mode_info;
-- unsigned int size;
-+ grub_size_t size;
-
- if (!bitmap)
- return grub_error (GRUB_ERR_BUG, "invalid argument");
-@@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
-
- mode_info->pitch = width * mode_info->bytes_per_pixel;
-
-- /* Calculate size needed for the data. */
-- size = (width * mode_info->bytes_per_pixel) * height;
-+ /* Calculate size needed for the data. */
-+ if (grub_mul (width, mode_info->bytes_per_pixel, &size) ||
-+ grub_mul (size, height, &size))
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+ goto fail;
-+ }
-
- (*bitmap)->data = grub_zalloc (size);
- if (! (*bitmap)->data)
-- {
-- grub_free (*bitmap);
-- *bitmap = 0;
--
-- return grub_errno;
-- }
-+ goto fail;
-
- return GRUB_ERR_NONE;
-+
-+ fail:
-+ grub_free (*bitmap);
-+ *bitmap = NULL;
-+
-+ return grub_errno;
- }
-
- /* Frees all resources allocated by bitmap. */
-diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
-index 61bd64537..0157ff742 100644
---- a/grub-core/video/readers/png.c
-+++ b/grub-core/video/readers/png.c
-@@ -23,6 +23,7 @@
- #include <grub/mm.h>
- #include <grub/misc.h>
- #include <grub/bufio.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -301,9 +302,17 @@ grub_png_decode_image_header (struct grub_png_data *data)
- data->bpp <<= 1;
-
- data->color_bits = color_bits;
-- data->row_bytes = data->image_width * data->bpp;
-+
-+ if (grub_mul (data->image_width, data->bpp, &data->row_bytes))
-+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+
- if (data->color_bits <= 4)
-- data->row_bytes = (data->image_width * data->color_bits + 7) / 8;
-+ {
-+ if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes))
-+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+
-+ data->row_bytes >>= 3;
-+ }
-
- #ifndef GRUB_CPU_WORDS_BIGENDIAN
- if (data->is_16bit || data->is_gray || data->is_palette)
-
-From 99c176e216b7196ac8d2af2b9bc483070b1a170a Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Sat, 4 Jul 2020 12:25:09 -0400
-Subject: iso9660: Don't leak memory on realloc() failures
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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;
-
-From fcc11dc1e68192d50cfb914314fb5e2f0504c498 Mon Sep 17 00:00:00 2001
-From: Daniel Kiper <daniel.kiper@oracle.com>
-Date: Tue, 7 Jul 2020 15:36:26 +0200
-Subject: 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 <chris.coulson@canonical.com>
-Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
-Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
----
- 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 (&section);
- if (!font->name)
- goto fail;
-
-From e283bb250350e8c2f7edeb344a624c57c26b042f Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Wed, 8 Jul 2020 20:41:56 +0000
-Subject: gfxmenu: Fix double free in load_image()
-
-self->bitmap should be zeroed after free. Otherwise, there is a chance
-to double free (USE_AFTER_FREE) it later in rescale_image().
-
-Fixes: CID 292472
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/gfxmenu/gui_image.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c
-index 29784ed2d..6b2e976f1 100644
---- a/grub-core/gfxmenu/gui_image.c
-+++ b/grub-core/gfxmenu/gui_image.c
-@@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path)
- return grub_errno;
-
- if (self->bitmap && (self->bitmap != self->raw_bitmap))
-- grub_video_bitmap_destroy (self->bitmap);
-+ {
-+ grub_video_bitmap_destroy (self->bitmap);
-+ self->bitmap = 0;
-+ }
- if (self->raw_bitmap)
- grub_video_bitmap_destroy (self->raw_bitmap);
-
-
-From 387219ffbb751afd336ebd71f1a375d9923ba416 Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Wed, 8 Jul 2020 21:30:43 +0000
-Subject: xnu: Fix double free in grub_xnu_devprop_add_property()
-
-grub_xnu_devprop_add_property() should not free utf8 and utf16 as it get
-allocated and freed in the caller.
-
-Minor improvement: do prop fields initialization after memory allocations.
-
-Fixes: CID 292442, CID 292457, CID 292460, CID 292466
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/loader/i386/xnu.c | 17 ++++++++---------
- 1 file changed, 8 insertions(+), 9 deletions(-)
-
-diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
-index b7d176b5d..e9e119259 100644
---- a/grub-core/loader/i386/xnu.c
-+++ b/grub-core/loader/i386/xnu.c
-@@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
- if (!prop)
- return grub_errno;
-
-- prop->name = utf8;
-- prop->name16 = utf16;
-- prop->name16len = utf16len;
--
-- prop->length = datalen;
-- prop->data = grub_malloc (prop->length);
-+ prop->data = grub_malloc (datalen);
- if (!prop->data)
- {
-- grub_free (prop->name);
-- grub_free (prop->name16);
- grub_free (prop);
- return grub_errno;
- }
-- grub_memcpy (prop->data, data, prop->length);
-+ grub_memcpy (prop->data, data, datalen);
-+
-+ prop->name = utf8;
-+ prop->name16 = utf16;
-+ prop->name16len = utf16len;
-+ prop->length = datalen;
-+
- grub_list_push (GRUB_AS_LIST_P (&dev->properties),
- GRUB_AS_LIST (prop));
- return GRUB_ERR_NONE;
-
-From 8b93dd5ba38c2d726a08b271b14a74e8f960d147 Mon Sep 17 00:00:00 2001
-From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Date: Thu, 9 Jul 2020 03:05:23 +0000
-Subject: lzma: Make sure we don't dereference past array
-
-The two dimensional array p->posSlotEncoder[4][64] is being dereferenced
-using the GetLenToPosState() macro which checks if len is less than 5,
-and if so subtracts 2 from it. If len = 0, that is 0 - 2 = 4294967294.
-Obviously we don't want to dereference that far out so we check if the
-position found is greater or equal kNumLenToPosStates (4) and bail out.
-
-N.B.: Upstream LZMA 18.05 and later has this function completely rewritten
-without any history.
-
-Fixes: CID 51526
-
-Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/lib/LzmaEnc.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c
-index f2ec04a8c..753e56a95 100644
---- a/grub-core/lib/LzmaEnc.c
-+++ b/grub-core/lib/LzmaEnc.c
-@@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
- }
- else
- {
-- UInt32 posSlot;
-+ UInt32 posSlot, lenToPosState;
- RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
- p->state = kMatchNextStates[p->state];
- LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
- pos -= LZMA_NUM_REPS;
- GetPosSlot(pos, posSlot);
-- RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-+ lenToPosState = GetLenToPosState(len);
-+ if (lenToPosState >= kNumLenToPosStates)
-+ {
-+ p->result = SZ_ERROR_DATA;
-+ return CheckErrors(p);
-+ }
-+ RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot);
-
- if (posSlot >= kStartPosModelIndex)
- {
-
-From 2328abbe2caa2129084da04a3e19461ddc571549 Mon Sep 17 00:00:00 2001
-From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Date: Tue, 7 Jul 2020 15:12:25 -0400
-Subject: term: Fix overflow on user inputs
-
-This requires a very weird input from the serial interface but can cause
-an overflow in input_buf (keys) overwriting the next variable (npending)
-with the user choice:
-
-(pahole output)
-
-struct grub_terminfo_input_state {
- int input_buf[6]; /* 0 24 */
- int npending; /* 24 4 */ <- CORRUPT
- ...snip...
-
-The magic string requires causing this is "ESC,O,],0,1,2,q" and we overflow
-npending with "q" (aka increase npending to 161). The simplest fix is to
-just to disallow overwrites input_buf, which exactly what this patch does.
-
-Fixes: CID 292449
-
-Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/term/terminfo.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
-index 63892ad42..aa3a108ca 100644
---- a/grub-core/term/terminfo.c
-+++ b/grub-core/term/terminfo.c
-@@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term)
- }
-
- static void
--grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
-+grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len,
- int (*readkey) (struct grub_term_input *term))
- {
- int c;
-@@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len,
- if (c == -1) \
- return; \
- \
-+ if (*len >= max_len) \
-+ return; \
-+ \
- keys[*len] = c; \
- (*len)++; \
- }
-@@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi)
- return ret;
- }
-
-- grub_terminfo_readkey (termi, data->input_buf,
-- &data->npending, data->readkey);
-+ grub_terminfo_readkey (termi, data->input_buf, &data->npending,
-+ GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey);
-
- #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)
- if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC
-
-From ba1d97845644290f03754432bcb6bbd6fefe7003 Mon Sep 17 00:00:00 2001
-From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Date: Tue, 7 Jul 2020 22:02:31 -0400
-Subject: udf: Fix memory leak
-
-Fixes: CID 73796
-
-Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
----
- grub-core/fs/udf.c | 17 +++++++++++++----
- 1 file changed, 13 insertions(+), 4 deletions(-)
-
-diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
-index 21ac7f446..2ac5c1d00 100644
---- a/grub-core/fs/udf.c
-+++ b/grub-core/fs/udf.c
-@@ -965,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
- return 0;
-
- if (grub_udf_read_icb (dir->data, &dirent.icb, child))
-- return 0;
--
-+ {
-+ grub_free (child);
-+ return 0;
-+ }
- if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT)
- {
- /* This is the parent directory. */
-@@ -988,11 +990,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir,
- dirent.file_ident_length,
- (char *) raw))
- != dirent.file_ident_length)
-- return 0;
-+ {
-+ grub_free (child);
-+ return 0;
-+ }
-
- filename = read_string (raw, dirent.file_ident_length, 0);
- if (!filename)
-- grub_print_error ();
-+ {
-+ /* As the hook won't get called. */
-+ grub_free (child);
-+ grub_print_error ();
-+ }
-
- if (filename && hook (filename, type, child, hook_data))
- {
-
-From 3b39c2023f3aa242b008385939a7394e5946e94b Mon Sep 17 00:00:00 2001
-From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Date: Fri, 26 Jun 2020 10:51:43 -0400
-Subject: multiboot2: Fix memory leak if
- grub_create_loader_cmdline() fails
-
-Fixes: CID 292468
-
-Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/loader/multiboot_mbi2.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
-index 53da78615..0efc66062 100644
---- a/grub-core/loader/multiboot_mbi2.c
-+++ b/grub-core/loader/multiboot_mbi2.c
-@@ -1070,7 +1070,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size,
- err = grub_create_loader_cmdline (argc, argv, newmod->cmdline,
- newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE);
- if (err)
-- return err;
-+ {
-+ grub_free (newmod->cmdline);
-+ grub_free (newmod);
-+ return err;
-+ }
-
- if (modules_last)
- modules_last->next = newmod;
-
-From 7726da0d972c3996b3ced02586204334eb03d472 Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Thu, 9 Jul 2020 08:10:40 +0000
-Subject: tftp: Do not use priority queue
-
-There is not need to reassemble the order of blocks. Per RFC 1350,
-server must wait for the ACK, before sending next block. Data packets
-can be served immediately without putting them to priority queue.
-
-Logic to handle incoming packet is this:
- - if packet block id equal to expected block id, then
- process the packet,
- - if packet block id is less than expected - this is retransmit
- of old packet, then ACK it and drop the packet,
- - if packet block id is more than expected - that shouldn't
- happen, just drop the packet.
-
-It makes the tftp receive path code simpler, smaller and faster.
-As a benefit, this change fixes CID# 73624 and CID# 96690, caused
-by following while loop:
-
- while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
-
-where tftph pointer is not moving from one iteration to another, causing
-to serve same packet again. Luckily, double serving didn't happen due to
-data->block++ during the first iteration.
-
-Fixes: CID 73624, CID 96690
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/net/tftp.c | 168 ++++++++++++++-----------------------------
- 1 file changed, 53 insertions(+), 115 deletions(-)
-
-diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
-index a0817a075..84229d03d 100644
---- a/grub-core/net/tftp.c
-+++ b/grub-core/net/tftp.c
-@@ -25,7 +25,6 @@
- #include <grub/mm.h>
- #include <grub/dl.h>
- #include <grub/file.h>
--#include <grub/priority_queue.h>
- #include <grub/i18n.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-@@ -106,31 +105,8 @@ typedef struct tftp_data
- int have_oack;
- struct grub_error_saved save_err;
- grub_net_udp_socket_t sock;
-- grub_priority_queue_t pq;
- } *tftp_data_t;
-
--static int
--cmp_block (grub_uint16_t a, grub_uint16_t b)
--{
-- grub_int16_t i = (grub_int16_t) (a - b);
-- if (i > 0)
-- return +1;
-- if (i < 0)
-- return -1;
-- return 0;
--}
--
--static int
--cmp (const void *a__, const void *b__)
--{
-- struct grub_net_buff *a_ = *(struct grub_net_buff **) a__;
-- struct grub_net_buff *b_ = *(struct grub_net_buff **) b__;
-- struct tftphdr *a = (struct tftphdr *) a_->data;
-- struct tftphdr *b = (struct tftphdr *) b_->data;
-- /* We want the first elements to be on top. */
-- return -cmp_block (grub_be_to_cpu16 (a->u.data.block), grub_be_to_cpu16 (b->u.data.block));
--}
--
- static grub_err_t
- ack (tftp_data_t data, grub_uint64_t block)
- {
-@@ -207,73 +183,60 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
- return GRUB_ERR_NONE;
- }
-
-- err = grub_priority_queue_push (data->pq, &nb);
-- if (err)
-- return err;
--
-- {
-- struct grub_net_buff **nb_top_p, *nb_top;
-- while (1)
-- {
-- nb_top_p = grub_priority_queue_top (data->pq);
-- if (!nb_top_p)
-- return GRUB_ERR_NONE;
-- nb_top = *nb_top_p;
-- tftph = (struct tftphdr *) nb_top->data;
-- if (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) >= 0)
-- break;
-- ack (data, grub_be_to_cpu16 (tftph->u.data.block));
-- grub_netbuff_free (nb_top);
-- grub_priority_queue_pop (data->pq);
-- }
-- while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0)
-- {
-- unsigned size;
--
-- grub_priority_queue_pop (data->pq);
--
-- if (file->device->net->packs.count < 50)
-+ /* Ack old/retransmitted block. */
-+ if (grub_be_to_cpu16 (tftph->u.data.block) < data->block + 1)
-+ ack (data, grub_be_to_cpu16 (tftph->u.data.block));
-+ /* Ignore unexpected block. */
-+ else if (grub_be_to_cpu16 (tftph->u.data.block) > data->block + 1)
-+ grub_dprintf ("tftp", "TFTP unexpected block # %d\n", tftph->u.data.block);
-+ else
-+ {
-+ unsigned size;
-+
-+ if (file->device->net->packs.count < 50)
-+ {
- err = ack (data, data->block + 1);
-- else
-- {
-- file->device->net->stall = 1;
-- err = 0;
-- }
-- if (err)
-- return err;
--
-- err = grub_netbuff_pull (nb_top, sizeof (tftph->opcode) +
-- sizeof (tftph->u.data.block));
-- if (err)
-- return err;
-- size = nb_top->tail - nb_top->data;
--
-- data->block++;
-- if (size < data->block_size)
-- {
-- if (data->ack_sent < data->block)
-- ack (data, data->block);
-- file->device->net->eof = 1;
-- file->device->net->stall = 1;
-- grub_net_udp_close (data->sock);
-- data->sock = NULL;
-- }
-- /* Prevent garbage in broken cards. Is it still necessary
-- given that IP implementation has been fixed?
-- */
-- if (size > data->block_size)
-- {
-- err = grub_netbuff_unput (nb_top, size - data->block_size);
-- if (err)
-- return err;
-- }
-- /* If there is data, puts packet in socket list. */
-- if ((nb_top->tail - nb_top->data) > 0)
-- grub_net_put_packet (&file->device->net->packs, nb_top);
-- else
-- grub_netbuff_free (nb_top);
-- }
-- }
-+ if (err)
-+ return err;
-+ }
-+ else
-+ file->device->net->stall = 1;
-+
-+ err = grub_netbuff_pull (nb, sizeof (tftph->opcode) +
-+ sizeof (tftph->u.data.block));
-+ if (err)
-+ return err;
-+ size = nb->tail - nb->data;
-+
-+ data->block++;
-+ if (size < data->block_size)
-+ {
-+ if (data->ack_sent < data->block)
-+ ack (data, data->block);
-+ file->device->net->eof = 1;
-+ file->device->net->stall = 1;
-+ grub_net_udp_close (data->sock);
-+ data->sock = NULL;
-+ }
-+ /*
-+ * Prevent garbage in broken cards. Is it still necessary
-+ * given that IP implementation has been fixed?
-+ */
-+ if (size > data->block_size)
-+ {
-+ err = grub_netbuff_unput (nb, size - data->block_size);
-+ if (err)
-+ return err;
-+ }
-+ /* If there is data, puts packet in socket list. */
-+ if ((nb->tail - nb->data) > 0)
-+ {
-+ grub_net_put_packet (&file->device->net->packs, nb);
-+ /* Do not free nb. */
-+ return GRUB_ERR_NONE;
-+ }
-+ }
-+ grub_netbuff_free (nb);
- return GRUB_ERR_NONE;
- case TFTP_ERROR:
- data->have_oack = 1;
-@@ -287,19 +250,6 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
- }
- }
-
--static void
--destroy_pq (tftp_data_t data)
--{
-- struct grub_net_buff **nb_p;
-- while ((nb_p = grub_priority_queue_top (data->pq)))
-- {
-- grub_netbuff_free (*nb_p);
-- grub_priority_queue_pop (data->pq);
-- }
--
-- grub_priority_queue_destroy (data->pq);
--}
--
- static grub_err_t
- tftp_open (struct grub_file *file, const char *filename)
- {
-@@ -322,17 +322,9 @@ tftp_open (struct grub_file *file, const char *filename)
- file->not_easily_seekable = 1;
- file->data = data;
-
-- data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp);
-- if (!data->pq)
-- {
-- grub_free (data);
-- return grub_errno;
-- }
--
- err = grub_net_resolve_address (file->device->net->server, &addr);
- if (err)
- {
-- destroy_pq (data);
- grub_free (data);
- return err;
- }
-@@ -396,7 +338,6 @@ tftp_open (struct grub_file *file, const char *filename)
- file);
- if (!data->sock)
- {
-- destroy_pq (data);
- grub_free (data);
- return grub_errno;
- }
-@@ -410,7 +351,6 @@ tftp_open (struct grub_file *file, const char *filename)
- if (err)
- {
- grub_net_udp_close (data->sock);
-- destroy_pq (data);
- grub_free (data);
- return err;
- }
-@@ -427,7 +367,6 @@ tftp_open (struct grub_file *file, const char *filename)
- if (grub_errno)
- {
- grub_net_udp_close (data->sock);
-- destroy_pq (data);
- grub_free (data);
- return grub_errno;
- }
-@@ -470,7 +409,6 @@ tftp_close (struct grub_file *file)
- grub_print_error ();
- grub_net_udp_close (data->sock);
- }
-- destroy_pq (data);
- grub_free (data);
- return GRUB_ERR_NONE;
- }
-
-From f1e2fd65877424ee8d8d2bdd78ce28b420dee4d8 Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Wed, 15 Jul 2020 06:42:37 +0000
-Subject: relocator: Protect grub_relocator_alloc_chunk_addr()
- input args against integer underflow/overflow
-
-Use arithmetic macros from safemath.h to accomplish it. In this commit,
-I didn't want to be too paranoid to check every possible math equation
-for overflow/underflow. Only obvious places (with non zero chance of
-overflow/underflow) were refactored.
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/loader/i386/linux.c | 9 +++++++--
- grub-core/loader/i386/pc/linux.c | 9 +++++++--
- grub-core/loader/i386/xen.c | 12 ++++++++++--
- grub-core/loader/xnu.c | 11 +++++++----
- 4 files changed, 31 insertions(+), 10 deletions(-)
-
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index 2eab9bb10..58d76fc0a 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -36,6 +36,7 @@
- #include <grub/lib/cmdline.h>
- #include <grub/linux.h>
- #include <grub/machine/kernel.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -549,9 +550,13 @@ grub_linux_boot (void)
-
- {
- grub_relocator_chunk_t ch;
-+ grub_size_t sz;
-+
-+ if (grub_add (ctx.real_size, efi_mmap_size, &sz))
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
- err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-- ctx.real_mode_target,
-- (ctx.real_size + efi_mmap_size));
-+ ctx.real_mode_target, sz);
- if (err)
- return err;
- real_mode_mem = get_virtual_current_address (ch);
-diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
-index 47ea2945e..31f09922b 100644
---- a/grub-core/loader/i386/pc/linux.c
-+++ b/grub-core/loader/i386/pc/linux.c
-@@ -35,6 +35,7 @@
- #include <grub/i386/floppy.h>
- #include <grub/lib/cmdline.h>
- #include <grub/linux.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -218,8 +219,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
- real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
-- grub_linux16_prot_size = grub_file_size (file)
-- - real_size - GRUB_DISK_SECTOR_SIZE;
-+ if (grub_sub (grub_file_size (file), real_size, &grub_linux16_prot_size) ||
-+ grub_sub (grub_linux16_prot_size, GRUB_DISK_SECTOR_SIZE, &grub_linux16_prot_size))
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
-+ goto fail;
-+ }
-
- if (! grub_linux_is_bzimage
- && GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size
-diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c
-index 8f662c8ac..cd24874ca 100644
---- a/grub-core/loader/i386/xen.c
-+++ b/grub-core/loader/i386/xen.c
-@@ -41,6 +41,7 @@
- #include <grub/linux.h>
- #include <grub/i386/memory.h>
- #include <grub/verify.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -636,6 +637,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
- grub_relocator_chunk_t ch;
- grub_addr_t kern_start;
- grub_addr_t kern_end;
-+ grub_size_t sz;
-
- if (argc == 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
-@@ -703,8 +705,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)),
-
- xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE);
-
-- err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start,
-- kern_end - kern_start);
-+
-+ if (grub_sub (kern_end, kern_start, &sz))
-+ {
-+ err = GRUB_ERR_OUT_OF_RANGE;
-+ goto fail;
-+ }
-+
-+ err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, sz);
- if (err)
- goto fail;
- kern_chunk_src = get_virtual_current_address (ch);
-diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
-index 77d7060e1..9ae4ceb35 100644
---- a/grub-core/loader/xnu.c
-+++ b/grub-core/loader/xnu.c
-@@ -34,6 +34,7 @@
- #include <grub/env.h>
- #include <grub/i18n.h>
- #include <grub/verify.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
- {
- grub_err_t err;
- grub_relocator_chunk_t ch;
-+ grub_addr_t tgt;
-+
-+ if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt))
-+ return GRUB_ERR_OUT_OF_RANGE;
-
-- err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
-- grub_xnu_heap_target_start
-- + grub_xnu_heap_size, size);
-+ err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size);
- if (err)
- return err;
-
- *src = get_virtual_current_address (ch);
-- *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
-+ *target = tgt;
- grub_xnu_heap_size += size;
- grub_dprintf ("xnu", "val=%p\n", *src);
- return GRUB_ERR_NONE;
-
-From e39786ab462b1e4770fb35c736927286381ec47d Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Wed, 8 Jul 2020 01:44:38 +0000
-Subject: relocator: Protect grub_relocator_alloc_chunk_align()
- max_addr against integer underflow
-
-This commit introduces integer underflow mitigation in max_addr calculation
-in grub_relocator_alloc_chunk_align() invocation.
-
-It consists of 2 fixes:
- 1. Introduced grub_relocator_alloc_chunk_align_safe() wrapper function to perform
- sanity check for min/max and size values, and to make safe invocation of
- grub_relocator_alloc_chunk_align() with validated max_addr value. Replace all
- invocations such as grub_relocator_alloc_chunk_align(..., min_addr, max_addr - size, size, ...)
- by grub_relocator_alloc_chunk_align_safe(..., min_addr, max_addr, size, ...).
- 2. Introduced UP_TO_TOP32(s) macro for the cases where max_addr is 32-bit top
- address (0xffffffff - size + 1) or similar.
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/lib/i386/relocator.c | 28 ++++++++++----------------
- grub-core/lib/mips/relocator.c | 6 ++----
- grub-core/lib/powerpc/relocator.c | 6 ++----
- grub-core/lib/x86_64/efi/relocator.c | 7 +++----
- grub-core/loader/i386/linux.c | 5 ++---
- grub-core/loader/i386/multiboot_mbi.c | 7 +++----
- grub-core/loader/i386/pc/linux.c | 6 ++----
- grub-core/loader/mips/linux.c | 9 +++------
- grub-core/loader/multiboot.c | 2 +-
- grub-core/loader/multiboot_elfxx.c | 10 ++++-----
- grub-core/loader/multiboot_mbi2.c | 10 ++++-----
- grub-core/loader/xnu_resume.c | 2 +-
- include/grub/relocator.h | 29 +++++++++++++++++++++++++++
- 13 files changed, 69 insertions(+), 58 deletions(-)
-
-diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
-index 71dd4f0ab..34cbe834f 100644
---- a/grub-core/lib/i386/relocator.c
-+++ b/grub-core/lib/i386/relocator.c
-@@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel,
- /* Specific memory range due to Global Descriptor Table for use by payload
- that we will store in returned chunk. The address range and preference
- are based on "THE LINUX/x86 BOOT PROTOCOL" specification. */
-- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x1000,
-- 0x9a000 - RELOCATOR_SIZEOF (32),
-- RELOCATOR_SIZEOF (32), 16,
-- GRUB_RELOCATOR_PREFERENCE_LOW,
-- avoid_efi_bootservices);
-+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x1000, 0x9a000,
-+ RELOCATOR_SIZEOF (32), 16,
-+ GRUB_RELOCATOR_PREFERENCE_LOW,
-+ avoid_efi_bootservices);
- if (err)
- return err;
-
-@@ -125,13 +124,10 @@ grub_relocator16_boot (struct grub_relocator *rel,
- grub_relocator_chunk_t ch;
-
- /* Put it higher than the byte it checks for A20 check. */
-- err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
-- 0xa0000 - RELOCATOR_SIZEOF (16)
-- - GRUB_RELOCATOR16_STACK_SIZE,
-- RELOCATOR_SIZEOF (16)
-- + GRUB_RELOCATOR16_STACK_SIZE, 16,
-- GRUB_RELOCATOR_PREFERENCE_NONE,
-- 0);
-+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0x8010, 0xa0000,
-+ RELOCATOR_SIZEOF (16) +
-+ GRUB_RELOCATOR16_STACK_SIZE, 16,
-+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
- if (err)
- return err;
-
-@@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel,
- void *relst;
- grub_relocator_chunk_t ch;
-
-- err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
-- max_addr - RELOCATOR_SIZEOF (64),
-- RELOCATOR_SIZEOF (64), 16,
-- GRUB_RELOCATOR_PREFERENCE_NONE,
-- 0);
-+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr,
-+ RELOCATOR_SIZEOF (64), 16,
-+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
- if (err)
- return err;
-
-diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c
-index 9d5f49cb9..743b213e6 100644
---- a/grub-core/lib/mips/relocator.c
-+++ b/grub-core/lib/mips/relocator.c
-@@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
- unsigned i;
- grub_addr_t vtarget;
-
-- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
-- (0xffffffff - stateset_size)
-- + 1, stateset_size,
-- sizeof (grub_uint32_t),
-+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
-+ stateset_size, sizeof (grub_uint32_t),
- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
- if (err)
- return err;
-diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c
-index bdf2b111b..8ffb8b686 100644
---- a/grub-core/lib/powerpc/relocator.c
-+++ b/grub-core/lib/powerpc/relocator.c
-@@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel,
- unsigned i;
- grub_relocator_chunk_t ch;
-
-- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
-- (0xffffffff - stateset_size)
-- + 1, stateset_size,
-- sizeof (grub_uint32_t),
-+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, UP_TO_TOP32 (stateset_size),
-+ stateset_size, sizeof (grub_uint32_t),
- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
- if (err)
- return err;
-diff --git a/grub-core/lib/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c
-index 3caef7a40..7d200a125 100644
---- a/grub-core/lib/x86_64/efi/relocator.c
-+++ b/grub-core/lib/x86_64/efi/relocator.c
-@@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel,
- * 64-bit relocator code may live above 4 GiB quite well.
- * However, I do not want ask for problems. Just in case.
- */
-- err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
-- 0x100000000 - RELOCATOR_SIZEOF (64_efi),
-- RELOCATOR_SIZEOF (64_efi), 16,
-- GRUB_RELOCATOR_PREFERENCE_NONE, 1);
-+ err = grub_relocator_alloc_chunk_align_safe (rel, &ch, 0, 0x100000000,
-+ RELOCATOR_SIZEOF (64_efi), 16,
-+ GRUB_RELOCATOR_PREFERENCE_NONE, 1);
- if (err)
- return err;
-
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index 58d76fc0a..c98fbbb37 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -183,9 +183,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
- for (; err && *align + 1 > min_align; (*align)--)
- {
- grub_errno = GRUB_ERR_NONE;
-- err = grub_relocator_alloc_chunk_align (relocator, &ch,
-- 0x1000000,
-- 0xffffffff & ~prot_size,
-+ err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000,
-+ UP_TO_TOP32 (prot_size),
- prot_size, 1 << *align,
- GRUB_RELOCATOR_PREFERENCE_LOW,
- 1);
-diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
-index ad3cc292f..a67d9d0a8 100644
---- a/grub-core/loader/i386/multiboot_mbi.c
-+++ b/grub-core/loader/i386/multiboot_mbi.c
-@@ -466,10 +466,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
-
- bufsize = grub_multiboot_get_mbi_size ();
-
-- err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
-- 0x10000, 0xa0000 - bufsize,
-- bufsize, 4,
-- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
-+ err = grub_relocator_alloc_chunk_align_safe (grub_multiboot_relocator, &ch,
-+ 0x10000, 0xa0000, bufsize, 4,
-+ GRUB_RELOCATOR_PREFERENCE_NONE, 0);
- if (err)
- return err;
- ptrorig = get_virtual_current_address (ch);
-diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
-index 31f09922b..5fed5ffdf 100644
---- a/grub-core/loader/i386/pc/linux.c
-+++ b/grub-core/loader/i386/pc/linux.c
-@@ -453,10 +453,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
-
- {
- grub_relocator_chunk_t ch;
-- err = grub_relocator_alloc_chunk_align (relocator, &ch,
-- addr_min, addr_max - size,
-- size, 0x1000,
-- GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
-+ err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size,
-+ 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0);
- if (err)
- return err;
- initrd_chunk = get_virtual_current_address (ch);
-diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c
-index 7b723bf18..e4ed95921 100644
---- a/grub-core/loader/mips/linux.c
-+++ b/grub-core/loader/mips/linux.c
-@@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
- {
- grub_relocator_chunk_t ch;
-
-- err = grub_relocator_alloc_chunk_align (relocator, &ch,
-- (target_addr & 0x1fffffff)
-- + linux_size + 0x10000,
-- (0x10000000 - size),
-- size, 0x10000,
-- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
-+ err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) +
-+ linux_size + 0x10000, 0x10000000, size,
-+ 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0);
-
- if (err)
- goto fail;
-diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c
-index 4a98d7082..facb13f3d 100644
---- a/grub-core/loader/multiboot.c
-+++ b/grub-core/loader/multiboot.c
-@@ -403,7 +403,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
- {
- grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
-- lowest_addr, (0xffffffff - size) + 1,
-+ lowest_addr, UP_TO_TOP32 (size),
- size, MULTIBOOT_MOD_ALIGN,
- GRUB_RELOCATOR_PREFERENCE_NONE, 1);
- if (err)
-diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c
-index cc6853692..f2318e0d1 100644
---- a/grub-core/loader/multiboot_elfxx.c
-+++ b/grub-core/loader/multiboot_elfxx.c
-@@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
- if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
- return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
-
-- err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch,
-- mld->min_addr, mld->max_addr - load_size,
-- load_size, mld->align ? mld->align : 1,
-- mld->preference, mld->avoid_efi_boot_services);
-+ err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch,
-+ mld->min_addr, mld->max_addr,
-+ load_size, mld->align ? mld->align : 1,
-+ mld->preference, mld->avoid_efi_boot_services);
-
- if (err)
- {
-@@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
- continue;
-
- err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0,
-- (0xffffffff - sh->sh_size) + 1,
-+ UP_TO_TOP32 (sh->sh_size),
- sh->sh_size, sh->sh_addralign,
- GRUB_RELOCATOR_PREFERENCE_NONE,
- mld->avoid_efi_boot_services);
-diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
-index 0efc66062..03967839c 100644
---- a/grub-core/loader/multiboot_mbi2.c
-+++ b/grub-core/loader/multiboot_mbi2.c
-@@ -295,10 +295,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename)
- return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
- }
-
-- err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
-- mld.min_addr, mld.max_addr - code_size,
-- code_size, mld.align ? mld.align : 1,
-- mld.preference, keep_bs);
-+ err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch,
-+ mld.min_addr, mld.max_addr,
-+ code_size, mld.align ? mld.align : 1,
-+ mld.preference, keep_bs);
- }
- else
- err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator,
-@@ -708,7 +708,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target)
- COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0);
-
- err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch,
-- 0, 0xffffffff - bufsize,
-+ 0, UP_TO_TOP32 (bufsize),
- bufsize, MULTIBOOT_TAG_ALIGN,
- GRUB_RELOCATOR_PREFERENCE_NONE, 1);
- if (err)
-diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c
-index 8089804d4..d648ef0cd 100644
---- a/grub-core/loader/xnu_resume.c
-+++ b/grub-core/loader/xnu_resume.c
-@@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename)
- {
- grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0,
-- (0xffffffff - hibhead.image_size) + 1,
-+ UP_TO_TOP32 (hibhead.image_size),
- hibhead.image_size,
- GRUB_XNU_PAGESIZE,
- GRUB_RELOCATOR_PREFERENCE_NONE, 0);
-diff --git a/include/grub/relocator.h b/include/grub/relocator.h
-index 24d8672d2..1b3bdd92a 100644
---- a/include/grub/relocator.h
-+++ b/include/grub/relocator.h
-@@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
- int preference,
- int avoid_efi_boot_services);
-
-+/*
-+ * Wrapper for grub_relocator_alloc_chunk_align() with purpose of
-+ * protecting against integer underflow.
-+ *
-+ * Compare to its callee, max_addr has different meaning here.
-+ * It covers entire chunk and not just start address of the chunk.
-+ */
-+static inline grub_err_t
-+grub_relocator_alloc_chunk_align_safe (struct grub_relocator *rel,
-+ grub_relocator_chunk_t *out,
-+ grub_phys_addr_t min_addr,
-+ grub_phys_addr_t max_addr,
-+ grub_size_t size, grub_size_t align,
-+ int preference,
-+ int avoid_efi_boot_services)
-+{
-+ /* Sanity check and ensure following equation (max_addr - size) is safe. */
-+ if (max_addr < size || (max_addr - size) < min_addr)
-+ return GRUB_ERR_OUT_OF_RANGE;
-+
-+ return grub_relocator_alloc_chunk_align (rel, out, min_addr,
-+ max_addr - size,
-+ size, align, preference,
-+ avoid_efi_boot_services);
-+}
-+
-+/* Top 32-bit address minus s bytes and plus 1 byte. */
-+#define UP_TO_TOP32(s) ((~(s) & 0xffffffff) + 1)
-+
- #define GRUB_RELOCATOR_PREFERENCE_NONE 0
- #define GRUB_RELOCATOR_PREFERENCE_LOW 1
- #define GRUB_RELOCATOR_PREFERENCE_HIGH 2
-
-From 7855b7e78de5f257fa686ec569bda27472c4f5da Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Fri, 10 Jul 2020 11:21:14 +0100
-Subject: script: Remove unused fields from grub_script_function
- struct
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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;
-
-
-From fdc80d2460e5d3b54f5cde8657f9e171b0b9a376 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Fri, 10 Jul 2020 14:41:45 +0100
-Subject: 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.
-
-Fixes: CVE-2020-15706
-
-Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- 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 c8d6806fe..7e028e135 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 = $<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;
-
-
-From dcc097ac0531485f0785816469370bfcb1a29f60 Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Fri, 17 Jul 2020 05:17:26 +0000
-Subject: relocator: Fix grub_relocator_alloc_chunk_align() top
- memory allocation
-
-Current implementation of grub_relocator_alloc_chunk_align()
-does not allow allocation of the top byte.
-
-Assuming input args are:
- max_addr = 0xfffff000;
- size = 0x1000;
-
-And this is valid. But following overflow protection will
-unnecessarily move max_addr one byte down (to 0xffffefff):
- if (max_addr > ~size)
- max_addr = ~size;
-
-~size + 1 will fix the situation. In addition, check size
-for non zero to do not zero max_addr.
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/lib/relocator.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c
-index 5847aac36..f2c1944c2 100644
---- a/grub-core/lib/relocator.c
-+++ b/grub-core/lib/relocator.c
-@@ -1386,8 +1386,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
- };
- grub_addr_t min_addr2 = 0, max_addr2;
-
-- if (max_addr > ~size)
-- max_addr = ~size;
-+ if (size && (max_addr > ~size))
-+ max_addr = ~size + 1;
-
- #ifdef GRUB_MACHINE_PCBIOS
- if (min_addr < 0x1000)
-
-From 2db482b906c425aa755fc78e8e8980659b92f5a1 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Sun, 19 Jul 2020 14:43:31 -0400
-Subject: hfsplus: fix two more overflows
-
-Both node->size and node->namelen come from the supplied filesystem,
-which may be user-supplied. We can't trust them for the math unless we
-know they don't overflow; making sure they go through calloc() first
-will give us that.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
----
- grub-core/fs/hfsplus.c | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
-index dae43becc..9c4e4c88c 100644
---- a/grub-core/fs/hfsplus.c
-+++ b/grub-core/fs/hfsplus.c
-@@ -31,6 +31,7 @@
- #include <grub/hfs.h>
- #include <grub/charset.h>
- #include <grub/hfsplus.h>
-+#include <grub/safemath.h>
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -475,8 +476,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
- {
- char *symlink;
- grub_ssize_t numread;
-+ grub_size_t sz = node->size;
-
-- symlink = grub_malloc (node->size + 1);
-+ if (grub_add (sz, 1, &sz))
-+ return NULL;
-+
-+ symlink = grub_malloc (sz);
- if (!symlink)
- return 0;
-
-@@ -715,8 +720,8 @@ list_nodes (void *record, void *hook_arg)
- if (type == GRUB_FSHELP_UNKNOWN)
- return 0;
-
-- filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen)
-- * GRUB_MAX_UTF8_PER_UTF16 + 1);
-+ filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen),
-+ GRUB_MAX_UTF8_PER_UTF16 + 1);
- if (! filename)
- return 0;
-
-
-From fc669c03dbffd20667f40a2375c30ef91cdc2707 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Sun, 19 Jul 2020 15:48:20 -0400
-Subject: lvm: fix two more potential data-dependent alloc
- overflows
-
-It appears to be possible to make a (possibly invalid) lvm PV with a
-metadata size field that overflows our type when adding it to the
-address we've allocated. Even if it doesn't, it may be possible to do
-so with the math using the outcome of that as an operand. Check them
-both.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
----
- grub-core/disk/lvm.c | 47 ++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 39 insertions(+), 8 deletions(-)
-
-diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
-index d1df640b3..e1299a348 100644
---- a/grub-core/disk/lvm.c
-+++ b/grub-core/disk/lvm.c
-@@ -25,6 +25,7 @@
- #include <grub/lvm.h>
- #include <grub/partition.h>
- #include <grub/i18n.h>
-+#include <grub/safemath.h>
-
- #ifdef GRUB_UTIL
- #include <grub/emu/misc.h>
-@@ -102,10 +103,11 @@ grub_lvm_detect (grub_disk_t disk,
- {
- grub_err_t err;
- grub_uint64_t mda_offset, mda_size;
-+ grub_size_t ptr;
- char buf[GRUB_LVM_LABEL_SIZE];
- char vg_id[GRUB_LVM_ID_STRLEN+1];
- char pv_id[GRUB_LVM_ID_STRLEN+1];
-- char *metadatabuf, *p, *q, *vgname;
-+ char *metadatabuf, *p, *q, *mda_end, *vgname;
- struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf;
- struct grub_lvm_pv_header *pvh;
- struct grub_lvm_disk_locn *dlocn;
-@@ -205,19 +207,31 @@ grub_lvm_detect (grub_disk_t disk,
- grub_le_to_cpu64 (rlocn->size) -
- grub_le_to_cpu64 (mdah->size));
- }
-- p = q = metadatabuf + grub_le_to_cpu64 (rlocn->offset);
-
-- while (*q != ' ' && q < metadatabuf + mda_size)
-- q++;
--
-- if (q == metadatabuf + mda_size)
-+ if (grub_add ((grub_size_t)metadatabuf,
-+ (grub_size_t)grub_le_to_cpu64 (rlocn->offset),
-+ &ptr))
- {
-+error_parsing_metadata:
- #ifdef GRUB_UTIL
- grub_util_info ("error parsing metadata");
- #endif
- goto fail2;
- }
-
-+ p = q = (char *)ptr;
-+
-+ if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr))
-+ goto error_parsing_metadata;
-+
-+ mda_end = (char *)ptr;
-+
-+ while (*q != ' ' && q < mda_end)
-+ q++;
-+
-+ if (q == mda_end)
-+ goto error_parsing_metadata;
-+
- vgname_len = q - p;
- vgname = grub_malloc (vgname_len + 1);
- if (!vgname)
-@@ -367,8 +381,25 @@ grub_lvm_detect (grub_disk_t disk,
- {
- const char *iptr;
- char *optr;
-- lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len
-- + 1 + 2 * s + 1);
-+
-+ /* this is kind of hard to read with our safe (but rather
-+ * baroque) math primatives, but it boils down to:
-+ *
-+ * sz0 = vgname_len * 2 + 1
-+ * + s * 2 + 1
-+ * + sizeof ("lvm/") - 1;
-+ */
-+ grub_size_t sz0 = vgname_len, sz1 = s;
-+
-+ if (grub_mul (sz0, 2, &sz0) ||
-+ grub_add (sz0, 1, &sz0) ||
-+ grub_mul (sz1, 2, &sz1) ||
-+ grub_add (sz1, 1, &sz1) ||
-+ grub_add (sz0, sz1, &sz0) ||
-+ grub_add (sz0, sizeof ("lvm/") - 1, &sz0))
-+ goto lvs_fail;
-+
-+ lv->fullname = grub_malloc (sz0);
- if (!lv->fullname)
- goto lvs_fail;
-
-
-From c0a2098a2d47a752f9416a655a7010973298f66f Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Sun, 19 Jul 2020 16:08:08 -0400
-Subject: emu: make grub_free(NULL) safe
-
-The grub_free() implementation in kern/mm.c safely handles NULL
-pointers, and code at many places depends on this. We don't know that
-the same is true on all host OSes, so we need to handle the same
-behavior in grub-emu's implementation.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
-Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
----
- grub-core/kern/emu/mm.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c
-index 145b01d37..4d1046a21 100644
---- a/grub-core/kern/emu/mm.c
-+++ b/grub-core/kern/emu/mm.c
-@@ -60,7 +60,8 @@ grub_zalloc (grub_size_t size)
- void
- grub_free (void *ptr)
- {
-- free (ptr);
-+ if (ptr)
-+ free (ptr);
- }
-
- void *
-
-From 9735a4b2f52caf79e5804ca3e959f0f444a8716c Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Sun, 19 Jul 2020 16:53:27 -0400
-Subject: efi: fix some malformed device path arithmetic errors.
-
-Several places we take the length of a device path and subtract 4 from
-it, without ever checking that it's >= 4. There are also cases where
-this kind of malformation will result in unpredictable iteration,
-including treating the length from one dp node as the type in the next
-node. These are all errors, no matter where the data comes from.
-
-This patch adds a checking macro, GRUB_EFI_DEVICE_PATH_VALID(), which
-can be used in several places, and makes GRUB_EFI_NEXT_DEVICE_PATH()
-return NULL and GRUB_EFI_END_ENTIRE_DEVICE_PATH() evaluate as true when
-the length is too small. Additionally, it makes several places in the
-code check for and return errors in these cases.
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
----
- grub-core/kern/efi/efi.c | 67 +++++++++++++++++++++++++-----
- grub-core/loader/efi/chainloader.c | 19 ++++++++-
- grub-core/loader/i386/xnu.c | 9 ++--
- include/grub/efi/api.h | 14 ++++---
- 4 files changed, 88 insertions(+), 21 deletions(-)
-
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index ad170c7ce..e12261fd5 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -360,7 +360,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
-
- dp = dp0;
-
-- while (1)
-+ while (dp)
- {
- grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
- grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-@@ -370,9 +370,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
- if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
- && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
- {
-- grub_efi_uint16_t len;
-- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
-- / sizeof (grub_efi_char16_t));
-+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
-+
-+ if (len < 4)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "malformed EFI Device Path node has length=%d", len);
-+ return NULL;
-+ }
-+ len = (len - 4) / sizeof (grub_efi_char16_t);
- filesize += GRUB_MAX_UTF8_PER_UTF16 * len + 2;
- }
-
-@@ -388,7 +394,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
- if (!name)
- return NULL;
-
-- while (1)
-+ while (dp)
- {
- grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
- grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-@@ -404,8 +410,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
-
- *p++ = '/';
-
-- len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
-- / sizeof (grub_efi_char16_t));
-+ len = GRUB_EFI_DEVICE_PATH_LENGTH (dp);
-+ if (len < 4)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "malformed EFI Device Path node has length=%d", len);
-+ return NULL;
-+ }
-+
-+ len = (len - 4) / sizeof (grub_efi_char16_t);
- fp = (grub_efi_file_path_device_path_t *) dp;
- /* According to EFI spec Path Name is NULL terminated */
- while (len > 0 && fp->path_name[len - 1] == 0)
-@@ -480,7 +493,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
- ;
- p = GRUB_EFI_NEXT_DEVICE_PATH (p))
- {
-- total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
-+ grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (p);
-+
-+ /*
-+ * In the event that we find a node that's completely garbage, for
-+ * example if we get to 0x7f 0x01 0x02 0x00 ... (EndInstance with a size
-+ * of 2), GRUB_EFI_END_ENTIRE_DEVICE_PATH() will be true and
-+ * GRUB_EFI_NEXT_DEVICE_PATH() will return NULL, so we won't continue,
-+ * and neither should our consumers, but there won't be any error raised
-+ * even though the device path is junk.
-+ *
-+ * This keeps us from passing junk down back to our caller.
-+ */
-+ if (len < 4)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "malformed EFI Device Path node has length=%d", len);
-+ return NULL;
-+ }
-+
-+ total_size += len;
- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
- break;
- }
-@@ -525,7 +557,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
- void
- grub_efi_print_device_path (grub_efi_device_path_t *dp)
- {
-- while (1)
-+ while (GRUB_EFI_DEVICE_PATH_VALID (dp))
- {
- grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
- grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
-@@ -937,7 +969,11 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
- /* Return non-zero. */
- return 1;
-
-- while (1)
-+ if (dp1 == dp2)
-+ return 0;
-+
-+ while (GRUB_EFI_DEVICE_PATH_VALID (dp1)
-+ && GRUB_EFI_DEVICE_PATH_VALID (dp2))
- {
- grub_efi_uint8_t type1, type2;
- grub_efi_uint8_t subtype1, subtype2;
-@@ -973,5 +1009,16 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
- dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
- }
-
-+ /*
-+ * There's no "right" answer here, but we probably don't want to call a valid
-+ * dp and an invalid dp equal, so pick one way or the other.
-+ */
-+ if (GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
-+ !GRUB_EFI_DEVICE_PATH_VALID (dp2))
-+ return 1;
-+ else if (!GRUB_EFI_DEVICE_PATH_VALID (dp1) &&
-+ GRUB_EFI_DEVICE_PATH_VALID (dp2))
-+ return -1;
-+
- return 0;
- }
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index daf8c6b54..978fab002 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -116,6 +116,12 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
- fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
- fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
-
-+ if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
-+ return;
-+ }
-+
- path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
- if (!path_name)
- return;
-@@ -156,9 +162,18 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
-
- size = 0;
- d = dp;
-- while (1)
-+ while (d)
- {
-- size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
-+ grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (d);
-+
-+ if (len < 4)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "malformed EFI Device Path node has length=%d", len);
-+ return NULL;
-+ }
-+
-+ size += len;
- if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
- break;
- d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
-index e9e119259..a70093607 100644
---- a/grub-core/loader/i386/xnu.c
-+++ b/grub-core/loader/i386/xnu.c
-@@ -515,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
-
- devhead = buf;
- buf = devhead + 1;
-- dpstart = buf;
-+ dp = dpstart = buf;
-
-- do
-+ while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend)
- {
-- dp = buf;
- buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
-+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
-+ break;
-+ dp = buf;
- }
-- while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);
-
- dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
- - (char *) dpstart);
-diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
-index 75befd10e..a3f4df91d 100644
---- a/include/grub/efi/api.h
-+++ b/include/grub/efi/api.h
-@@ -635,6 +635,7 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
- #define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f)
- #define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype)
- #define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length)
-+#define GRUB_EFI_DEVICE_PATH_VALID(dp) ((dp) != NULL && GRUB_EFI_DEVICE_PATH_LENGTH (dp) >= 4)
-
- /* The End of Device Path nodes. */
- #define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f)
-@@ -643,13 +644,16 @@ typedef struct grub_efi_device_path grub_efi_device_path_protocol_t;
- #define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01
-
- #define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \
-- (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
-- && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
-- == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE))
-+ (!GRUB_EFI_DEVICE_PATH_VALID (dp) || \
-+ (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \
-+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \
-+ == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)))
-
- #define GRUB_EFI_NEXT_DEVICE_PATH(dp) \
-- ((grub_efi_device_path_t *) ((char *) (dp) \
-- + GRUB_EFI_DEVICE_PATH_LENGTH (dp)))
-+ (GRUB_EFI_DEVICE_PATH_VALID (dp) \
-+ ? ((grub_efi_device_path_t *) \
-+ ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \
-+ : NULL)
-
- /* Hardware Device Path. */
- #define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1
-
-From c5763039a630dee079f0afbd5ced9cd74efe0b71 Mon Sep 17 00:00:00 2001
-From: Chris Coulson <chris.coulson@canonical.com>
-Date: Wed, 22 Jul 2020 17:06:04 +0100
-Subject: Fix a regression caused by "efi: fix some malformed
- device path arithmetic errors"
-
-This commit introduced a bogus check inside copy_file_path to
-determine whether the destination grub_efi_file_path_device_path_t
-was valid before anything was copied to it. Depending on the
-contents of the heap buffer, this check could fail which would
-result in copy_file_path returning early.
-
-Without any error propagated to the caller, make_file_path would
-then try to advance the invalid device path node with
-GRUB_EFI_NEXT_DEVICE_PATH, which would also fail, returning a NULL
-pointer that would subsequently be dereferenced.
-
-Remove the bogus check, and also propagate errors from copy_file_path.
----
- grub-core/loader/efi/chainloader.c | 25 +++++++++++++------------
- 1 file changed, 13 insertions(+), 12 deletions(-)
-
-diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
-index 978fab002..e9b06242a 100644
---- a/grub-core/loader/efi/chainloader.c
-+++ b/grub-core/loader/efi/chainloader.c
-@@ -106,7 +106,7 @@ grub_chainloader_boot (void)
- return grub_errno;
- }
-
--static void
-+static grub_err_t
- copy_file_path (grub_efi_file_path_device_path_t *fp,
- const char *str, grub_efi_uint16_t len)
- {
-@@ -116,15 +116,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
- fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
- fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
-
-- if (!GRUB_EFI_DEVICE_PATH_VALID ((grub_efi_device_path_t *)fp))
-- {
-- grub_error (GRUB_ERR_BAD_ARGUMENT, "EFI Device Path is invalid");
-- return;
-- }
--
- path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
- if (!path_name)
-- return;
-+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer");
-
- size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
- (const grub_uint8_t *) str, len, 0);
-@@ -137,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
- fp->path_name[size++] = '\0';
- fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
- grub_free (path_name);
-+ return GRUB_ERR_NONE;
- }
-
- static grub_efi_device_path_t *
-@@ -195,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
- d = (grub_efi_device_path_t *) ((char *) file_path
- + ((char *) d - (char *) dp));
- grub_efi_print_device_path (d);
-- copy_file_path ((grub_efi_file_path_device_path_t *) d,
-- dir_start, dir_end - dir_start);
-+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
-+ dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
-+ {
-+ fail:
-+ grub_free (file_path);
-+ return 0;
-+ }
-
- /* Fill the file path for the file. */
- d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-- copy_file_path ((grub_efi_file_path_device_path_t *) d,
-- dir_end + 1, grub_strlen (dir_end + 1));
-+ if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
-+ dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE)
-+ goto fail;
-
- /* Fill the end of device path nodes. */
- d = GRUB_EFI_NEXT_DEVICE_PATH (d);
-
-From 3e6aa687d9a2f8d172536a67d0d0f8bc7adb3108 Mon Sep 17 00:00:00 2001
-From: Alexander Burmashev <alexander.burmashev@oracle.com>
-Date: Wed, 22 Jul 2020 06:04:38 -0700
-Subject: update safemath with fallback code for gcc older than
- 5.1
-
-The code used in the header was taken from linux kernel commit
-f0907827a8a9152aedac2833ed1b674a7b2a44f2. Rasmus Villemoes
-<linux@rasmusvillemoes.dk>, the original author of the patch, was
-contacted directly, confirmed his authorship of the code, and gave his
-permission on treating that dual license as MIT and including into GRUB2
-sources
-
-Signed-off-by: Alex Burmashev <alexander.burmashev@oracle.com>
----
- include/grub/safemath.h | 119 +++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 118 insertions(+), 1 deletion(-)
-
-diff --git a/include/grub/safemath.h b/include/grub/safemath.h
-index c17b89bba..1ccac276b 100644
---- a/include/grub/safemath.h
-+++ b/include/grub/safemath.h
-@@ -31,7 +31,124 @@
- #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
-+/*
-+ * Copyright 2020 Rasmus Villemoes
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to
-+ * deal in the Software without restriction, including without limitation the
-+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-+ * sell copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-+ * IN THE SOFTWARE.
-+ */
-+/*
-+ * The code used in this header was taken from linux kernel commit
-+ * f0907827a8a9152aedac2833ed1b674a7b2a44f2
-+ * Rasmus Villemoes <linux@rasmusvillemoes.dk>, the original author of the
-+ * patch, was contacted directly, confirmed his authorship of the code, and
-+ * gave his permission on treating that dual license as MIT and including into
-+ * GRUB2 sources
-+ */
-+
-+#include <grub/types.h>
-+#define is_signed_type(type) (((type)(-1)) < (type)1)
-+#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
-+#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
-+#define type_min(T) ((T)((T)-type_max(T)-(T)1))
-+
-+#define __unsigned_add_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = __a + __b; \
-+ *__d < __a; \
-+})
-+#define __unsigned_sub_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = __a - __b; \
-+ __a < __b; \
-+})
-+#define __unsigned_mul_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = __a * __b; \
-+ __builtin_constant_p(__b) ? \
-+ __b > 0 && __a > type_max(typeof(__a)) / __b :\
-+ __a > 0 && __b > type_max(typeof(__b)) / __a; \
-+})
-+
-+#define __signed_add_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = (grub_uint64_t)__a + (grub_uint64_t)__b; \
-+ (((~(__a ^ __b)) & (*__d ^ __a)) \
-+ & type_min(typeof(__a))) != 0; \
-+})
-+
-+#define __signed_sub_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = (grub_uint64_t)__a - (grub_uint64_t)__b; \
-+ ((((__a ^ __b)) & (*__d ^ __a)) \
-+ & type_min(typeof(__a))) != 0; \
-+})
-+
-+#define __signed_mul_overflow(a, b, d) ({ \
-+ typeof(+(a)) __a = (a); \
-+ typeof(+(b)) __b = (b); \
-+ typeof(d) __d = (d); \
-+ typeof(+(a)) __tmax = type_max(typeof(+(a))); \
-+ typeof(+(a)) __tmin = type_min(typeof(+(a))); \
-+ (void) (&__a == &__b); \
-+ (void) (&__a == __d); \
-+ *__d = (grub_uint64_t)__a * (grub_uint64_t)__b; \
-+ (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) ||\
-+ (__b < (typeof(__b))-1 && \
-+ (__a > __tmin/__b || __a < __tmax/__b)) || \
-+ (__b == (typeof(__b))-1 && __a == __tmin); \
-+})
-+
-+#define grub_add(a, b, d) \
-+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
-+ __signed_add_overflow(a, b, d), \
-+ __unsigned_add_overflow(a, b, d))
-+
-+#define grub_sub(a, b, d) \
-+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
-+ __signed_sub_overflow(a, b, d), \
-+ __unsigned_sub_overflow(a, b, d))
-+
-+#define grub_mul(a, b, d) \
-+ __builtin_choose_expr(is_signed_type(typeof(+(a))), \
-+ __signed_mul_overflow(a, b, d), \
-+ __unsigned_mul_overflow(a, b, d))
-+
- #endif
-
- #endif /* GRUB_SAFEMATH_H */
-
-From bb5fc65035e82509b0565bfe2994fbe6cc11016e Mon Sep 17 00:00:00 2001
-From: Alexey Makhalov <amakhalov@vmware.com>
-Date: Mon, 20 Jul 2020 23:03:05 +0000
-Subject: efi: Fix use-after-free in halt/reboot path
-
-commit 92bfc33db984 ("efi: Free malloc regions on exit")
-introduced memory freeing in grub_efi_fini(), which is
-used not only by exit path but by halt/reboot one as well.
-As result of memory freeing, code and data regions used by
-modules, such as halt, reboot, acpi (used by halt) also got
-freed. After return to module code, CPU executes, filled
-by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
-a code. Which leads to #UD exception later.
-
-grub> halt
-!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
-RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
-RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
-RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
-RSI - 00000000064DB768, RDI - 000000000832C5C3
-R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
-R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
-R14 - 0000000003E10D80, R15 - 00000000061E2F60
-DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
-GS - 0000000000000030, SS - 0000000000000030
-CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
-CR4 - 0000000000000668, CR8 - 0000000000000000
-DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
-DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
-GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
-IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
-FXSAVE_STATE - 0000000007F0F4C0
-
-Proposal here is to continue to free allocated memory for
-exit boot services path but keep it for halt/reboot path
-as it won't be much security concern here.
-Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
-loader flag to be used by efi halt/reboot path.
-
-Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
-Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
----
- grub-core/kern/arm/efi/init.c | 3 +++
- grub-core/kern/arm64/efi/init.c | 3 +++
- grub-core/kern/efi/efi.c | 3 ++-
- grub-core/kern/efi/init.c | 1 -
- grub-core/kern/i386/efi/init.c | 9 +++++++--
- grub-core/kern/ia64/efi/init.c | 9 +++++++--
- grub-core/kern/riscv/efi/init.c | 3 +++
- grub-core/lib/efi/halt.c | 3 ++-
- include/grub/loader.h | 1 +
- 9 files changed, 28 insertions(+), 7 deletions(-)
-
-diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
-index 06df60e2f..40c3b467f 100644
---- a/grub-core/kern/arm/efi/init.c
-+++ b/grub-core/kern/arm/efi/init.c
-@@ -71,4 +71,7 @@ grub_machine_fini (int flags)
- efi_call_1 (b->close_event, tmr_evt);
-
- grub_efi_fini ();
-+
-+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
-+ grub_efi_memory_fini ();
- }
-diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c
-index 6224999ec..5010caefd 100644
---- a/grub-core/kern/arm64/efi/init.c
-+++ b/grub-core/kern/arm64/efi/init.c
-@@ -57,4 +57,7 @@ grub_machine_fini (int flags)
- return;
-
- grub_efi_fini ();
-+
-+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
-+ grub_efi_memory_fini ();
- }
-diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
-index e12261fd5..acb38d61f 100644
---- a/grub-core/kern/efi/efi.c
-+++ b/grub-core/kern/efi/efi.c
-@@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
- void
- grub_reboot (void)
- {
-- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
-+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
-+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
- efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
- GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
- for (;;) ;
-diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
-index 3dfdf2d22..2c31847bf 100644
---- a/grub-core/kern/efi/init.c
-+++ b/grub-core/kern/efi/init.c
-@@ -80,5 +80,4 @@ grub_efi_fini (void)
- {
- grub_efidisk_fini ();
- grub_console_fini ();
-- grub_efi_memory_fini ();
- }
-diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
-index da499aba0..deb2eacd8 100644
---- a/grub-core/kern/i386/efi/init.c
-+++ b/grub-core/kern/i386/efi/init.c
-@@ -39,6 +39,11 @@ grub_machine_init (void)
- void
- grub_machine_fini (int flags)
- {
-- if (flags & GRUB_LOADER_FLAG_NORETURN)
-- grub_efi_fini ();
-+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
-+ return;
-+
-+ grub_efi_fini ();
-+
-+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
-+ grub_efi_memory_fini ();
- }
-diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c
-index b5ecbd091..f1965571b 100644
---- a/grub-core/kern/ia64/efi/init.c
-+++ b/grub-core/kern/ia64/efi/init.c
-@@ -70,6 +70,11 @@ grub_machine_init (void)
- void
- grub_machine_fini (int flags)
- {
-- if (flags & GRUB_LOADER_FLAG_NORETURN)
-- grub_efi_fini ();
-+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
-+ return;
-+
-+ grub_efi_fini ();
-+
-+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
-+ grub_efi_memory_fini ();
- }
-diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
-index 7eb1969d0..38795fe67 100644
---- a/grub-core/kern/riscv/efi/init.c
-+++ b/grub-core/kern/riscv/efi/init.c
-@@ -73,4 +73,7 @@ grub_machine_fini (int flags)
- return;
-
- grub_efi_fini ();
-+
-+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
-+ grub_efi_memory_fini ();
- }
-diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
-index 5859f0498..29d413641 100644
---- a/grub-core/lib/efi/halt.c
-+++ b/grub-core/lib/efi/halt.c
-@@ -28,7 +28,8 @@
- void
- grub_halt (void)
- {
-- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
-+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
-+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
- #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \
- !defined(__riscv)
- grub_acpi_halt ();
-diff --git a/include/grub/loader.h b/include/grub/loader.h
-index 7f82a499f..b20864282 100644
---- a/include/grub/loader.h
-+++ b/include/grub/loader.h
-@@ -33,6 +33,7 @@ enum
- {
- GRUB_LOADER_FLAG_NORETURN = 1,
- GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2,
-+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4,
- };
-
- void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
-
-From 6d438b80c4cfe75a67f619918706630ccc2252b6 Mon Sep 17 00:00:00 2001
-From: Peter Jones <pjones@redhat.com>
-Date: Fri, 24 Jul 2020 13:57:27 -0400
-Subject: linux loader: avoid overflow on initrd size calculation
-
-Signed-off-by: Peter Jones <pjones@redhat.com>
----
- grub-core/loader/linux.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
-index 471b214d6..25624ebc1 100644
---- a/grub-core/loader/linux.c
-+++ b/grub-core/loader/linux.c
-@@ -151,8 +151,8 @@ grub_initrd_init (int argc, char *argv[],
- initrd_ctx->nfiles = 0;
- initrd_ctx->components = 0;
-
-- initrd_ctx->components = grub_zalloc (argc
-- * sizeof (initrd_ctx->components[0]));
-+ initrd_ctx->components = grub_calloc (argc,
-+ sizeof (initrd_ctx->components[0]));
- if (!initrd_ctx->components)
- return grub_errno;
-
-
-From 81fae35a346bef8f7b27ba8d186a18ae21281755 Mon Sep 17 00:00:00 2001
-From: Colin Watson <cjwatson@debian.org>
-Date: Sat, 25 Jul 2020 12:15:37 +0100
-Subject: 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 <cjwatson@debian.org>
-Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
----
- grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++-----------
- 1 file changed, 54 insertions(+), 20 deletions(-)
-
-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 <grub/misc.h>
- #include <grub/file.h>
- #include <grub/mm.h>
-+#include <grub/safemath.h>
-
- 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/PKGBUILD b/PKGBUILD
index 7aaf531ae4e5..9c7972ba4387 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -9,22 +9,21 @@ _IA32_EFI_IN_ARCH_X64="1"
## "1" to enable EMU build, "0" to disable
_GRUB_EMU_BUILD="0"
-_GRUB_EXTRAS_COMMIT="8a245d5c1800627af4cefa99162a89c7a46d8842"
-_GNULIB_COMMIT="be584c56eb1311606e5ea1a36363b97bddb6eed3"
-_UNIFONT_VER="13.0.06"
+[[ "${CARCH}" == 'x86_64' ]] && _EFI_ARCH='x86_64'
+[[ "${CARCH}" == 'i686' ]] && _EFI_ARCH='i386'
-[[ "${CARCH}" == "x86_64" ]] && _EFI_ARCH="x86_64"
-[[ "${CARCH}" == "i686" ]] && _EFI_ARCH="i386"
-
-[[ "${CARCH}" == "x86_64" ]] && _EMU_ARCH="x86_64"
-[[ "${CARCH}" == "i686" ]] && _EMU_ARCH="i386"
+[[ "${CARCH}" == 'x86_64' ]] && _EMU_ARCH='x86_64'
+[[ "${CARCH}" == 'i686' ]] && _EMU_ARCH='i386'
pkgname='grub-libzfs'
pkgdesc='GNU GRand Unified Bootloader (2) - libzfs support'
epoch=2
-_pkgver=2.04
+_tag='53c5000739db114c229fe69ec3d4b76b92441098' # git rev-parse grub-${_pkgver}
+_gnulib_commit='be584c56eb1311606e5ea1a36363b97bddb6eed3'
+_unifont_ver='13.0.06'
+_pkgver=2.06
pkgver=${_pkgver/-/}
-pkgrel=10
+pkgrel=1
url='https://www.gnu.org/software/grub/'
arch=('x86_64')
license=('GPL3')
@@ -58,33 +57,22 @@ validpgpkeys=('E53D497F3FA42AD8C9B4D1E835A93B74E82E4209' # Vladimir 'phcoder' S
'BE5C23209ACDDACEB20DB0A28C8189F1988C2166' # Daniel Kiper <dkiper@net-space.pl>
'95D2E9AB8740D8046387FD151A09227B1F435A33') # Paul Hardy <unifoundry@unifoundry.com>
-source=("git+https://git.savannah.gnu.org/git/grub.git#tag=grub-${_pkgver}?signed"
- "git+https://git.savannah.gnu.org/git/grub-extras.git#commit=${_GRUB_EXTRAS_COMMIT}"
- "git+https://git.savannah.gnu.org/git/gnulib.git#commit=${_GNULIB_COMMIT}"
- "http://unifoundry.com/pub/unifont/unifont-${_UNIFONT_VER}/font-builds/unifont-${_UNIFONT_VER}.bdf.gz"{,.sig}
- '0003-10_linux-detect-archlinux-initramfs.patch'
- '0004-add-GRUB_COLOR_variables.patch'
- '0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch'
- '0006-BootHole.patch'
+source=("git+https://git.savannah.gnu.org/git/grub.git#tag=${_tag}?signed"
+ "git+https://git.savannah.gnu.org/git/gnulib.git#commit=${_gnulib_commit}"
+ "https://ftp.gnu.org/gnu/unifont/unifont-${_unifont_ver}/unifont-${_unifont_ver}.bdf.gz"{,.sig}
+ '0001-00_header-add-GRUB_COLOR_-variables.patch'
+ '0002-10_linux-detect-archlinux-initramfs.patch'
'grub.default')
sha256sums=('SKIP'
'SKIP'
- 'SKIP'
'b7668a5d498972dc4981250c49f83601babce797be19b4fdd0f2f1c6cfbd0fc5'
'SKIP'
- '171415ab075d1ac806f36c454feeb060f870416f24279b70104bba94bd6076d4'
- 'a5198267ceb04dceb6d2ea7800281a42b3f91fd02da55d2cc9ea20d47273ca29'
- '06820004912a3db195a76e68b376fce1ba6507ac740129f0b99257ef07aba1ea'
- '55c559b6d8c4a832a43cc35c7635de37402ec9e3e3bfd8b2b7761a06f0bfda02'
+ '5dee6628c48eef79812bb9e86ee772068d85e7fcebbd2b2b8d1e19d24eda9dab'
+ '8488aec30a93e8fe66c23ef8c23aefda39c38389530e9e73ba3fbcc8315d244d'
'791fadf182edf8d5bee4b45c008b08adce9689a9624971136527891a8f67d206')
_backports=(
- # grub-mkconfig: Use portable "command -v" to detect installed programs
- '28a7e597de0d5584f65e36f9588ff9041936e617'
-
- # build: Fix GRUB i386-pc build with Ubuntu gcc
- '6643507ce30f775008e093580f0c9499dfb2c485'
)
_configure_options=(
@@ -121,18 +109,12 @@ prepare() {
git cherry-pick -n "${_c}"
done
- echo "Patch to detect of Arch Linux initramfs images by grub-mkconfig..."
- patch -Np1 -i "${srcdir}/0003-10_linux-detect-archlinux-initramfs.patch"
-
echo "Patch to enable GRUB_COLOR_* variables in grub-mkconfig..."
## Based on http://lists.gnu.org/archive/html/grub-devel/2012-02/msg00021.html
- patch -Np1 -i "${srcdir}/0004-add-GRUB_COLOR_variables.patch"
-
- echo "Patch to NLS installation..."
- patch -Np1 -i "${srcdir}/0005-grub-install-fix-inverted-test-for-NLS-enabled-when-.patch"
+ patch -Np1 -i "${srcdir}/0001-00_header-add-GRUB_COLOR_-variables.patch"
- echo "Patch BootHole..."
- patch -Np1 -i "${srcdir}/0006-BootHole.patch"
+ echo "Patch to detect of Arch Linux initramfs images by grub-mkconfig..."
+ patch -Np1 -i "${srcdir}/0002-10_linux-detect-archlinux-initramfs.patch"
echo "Fix DejaVuSans.ttf location so that grub-mkfont can create *.pf2 files for starfield theme..."
sed 's|/usr/share/fonts/dejavu|/usr/share/fonts/dejavu /usr/share/fonts/TTF|g' -i "configure.ac"
@@ -148,7 +130,7 @@ prepare() {
echo "Avoid problem with unifont during compile of grub..."
# http://savannah.gnu.org/bugs/?40330 and https://bugs.archlinux.org/task/37847
- gzip -cd "${srcdir}/unifont-${_UNIFONT_VER}.bdf.gz" > "unifont.bdf"
+ gzip -cd "${srcdir}/unifont-${_unifont_ver}.bdf.gz" > "unifont.bdf"
echo "Run bootstrap..."
./bootstrap \
@@ -171,12 +153,6 @@ _build_grub-common_and_bios() {
cp -r "${srcdir}/grub/" "${srcdir}/grub-bios/"
cd "${srcdir}/grub-bios/"
- echo "Add the grub-extra sources for bios build..."
- install -d "${srcdir}/grub-bios/grub-extras"
- cp -r "${srcdir}/grub-extras/915resolution" \
- "${srcdir}/grub-bios/grub-extras/915resolution"
- export GRUB_CONTRIB="${srcdir}/grub-bios/grub-extras/"
-
echo "Unset all compiler FLAGS for bios build..."
unset CFLAGS
unset CPPFLAGS
diff --git a/grub-libzfs.install b/grub-libzfs.install
index c13ef99c77c5..c268996d1e57 100644
--- a/grub-libzfs.install
+++ b/grub-libzfs.install
@@ -6,12 +6,23 @@ post_upgrade() {
if [ ! -f /boot/grub/grub.cfg -a -f /boot/grub/grub.cfg.pacsave ]; then
mv /boot/grub/grub.cfg.pacsave /boot/grub/grub.cfg
fi
+
+ # return if old package version greater 2:2.06-0...
+ (( $(vercmp $2 '2:2.06-0') > 0 )) && return
+
+ if [[ -e /sys/firmware/efi/efivars ]]; then
+ cat <<EOM
+:: Grub does no longer support side-loading modules when secure boot is
+ enabled. Thus booting will fail, unless you have an efi executable
+ 'grubx64.efi' with bundled modules.
+EOM
+ fi
}
post_install() {
- cat << 'EOM'
-Generate your bootloader configuration with:
- grub-mkconfig -o /boot/grub/grub.cfg
+ cat <<EOM
+:: Generate your bootloader configuration with:
+ grub-mkconfig -o /boot/grub/grub.cfg
EOM
}