]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/commitdiff
grub: update to 2.04
authorArne Fitzenreiter <arne_f@ipfire.org>
Fri, 14 Aug 2020 11:30:47 +0000 (13:30 +0200)
committerArne Fitzenreiter <arne_f@ipfire.org>
Fri, 14 Aug 2020 15:10:14 +0000 (15:10 +0000)
fixes: #12463

Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
Acked-by: Michael Tremer <michael.tremer@ipfire.org>
config/rootfiles/common/aarch64/grub
config/rootfiles/common/i586/grub
config/rootfiles/common/x86_64/grub
lfs/grub
src/patches/grub-2.02-X86_64_PLT32.patch [deleted file]
src/patches/grub-2.02-fix-packed-not-aligned-error-on-gcc-8.patch [deleted file]
src/patches/grub-2.02-xfs-accept-filesystem-with-sparse-inodes.patch [deleted file]
src/patches/grub/grub-2.04-BootHole.patch [new file with mode: 0644]

index 6de37dd35cebe9e245ef8a621c17d1a656552ed8..f8ac7d408a368740af25a7f8dfb972ed6203d9bb 100644 (file)
@@ -10,7 +10,7 @@ etc/grub.d/20_linux_xen
 etc/grub.d/30_os-prober
 etc/grub.d/40_custom
 etc/grub.d/41_custom
-etc/grub.d/README
+#etc/grub.d/README
 usr/bin/grub-editenv
 usr/bin/grub-file
 usr/bin/grub-fstest
@@ -123,8 +123,11 @@ usr/lib/grub/arm64-efi/ext2.mod
 usr/lib/grub/arm64-efi/ext2.module
 usr/lib/grub/arm64-efi/extcmd.mod
 usr/lib/grub/arm64-efi/extcmd.module
+usr/lib/grub/arm64-efi/f2fs.mod
+usr/lib/grub/arm64-efi/f2fs.module
 usr/lib/grub/arm64-efi/fat.mod
 usr/lib/grub/arm64-efi/fat.module
+usr/lib/grub/arm64-efi/fdt.lst
 usr/lib/grub/arm64-efi/fdt.mod
 usr/lib/grub/arm64-efi/fdt.module
 usr/lib/grub/arm64-efi/file.mod
@@ -342,6 +345,8 @@ usr/lib/grub/arm64-efi/pbkdf2.mod
 usr/lib/grub/arm64-efi/pbkdf2.module
 usr/lib/grub/arm64-efi/pbkdf2_test.mod
 usr/lib/grub/arm64-efi/pbkdf2_test.module
+usr/lib/grub/arm64-efi/pgp.mod
+usr/lib/grub/arm64-efi/pgp.module
 usr/lib/grub/arm64-efi/png.mod
 usr/lib/grub/arm64-efi/png.module
 usr/lib/grub/arm64-efi/priority_queue.mod
@@ -394,6 +399,8 @@ usr/lib/grub/arm64-efi/sleep_test.mod
 usr/lib/grub/arm64-efi/sleep_test.module
 usr/lib/grub/arm64-efi/squash4.mod
 usr/lib/grub/arm64-efi/squash4.module
+usr/lib/grub/arm64-efi/strtoull_test.mod
+usr/lib/grub/arm64-efi/strtoull_test.module
 usr/lib/grub/arm64-efi/syslinuxcfg.mod
 usr/lib/grub/arm64-efi/syslinuxcfg.module
 usr/lib/grub/arm64-efi/tar.mod
@@ -431,8 +438,8 @@ usr/lib/grub/arm64-efi/ufs1_be.mod
 usr/lib/grub/arm64-efi/ufs1_be.module
 usr/lib/grub/arm64-efi/ufs2.mod
 usr/lib/grub/arm64-efi/ufs2.module
-usr/lib/grub/arm64-efi/verify.mod
-usr/lib/grub/arm64-efi/verify.module
+usr/lib/grub/arm64-efi/verifiers.mod
+usr/lib/grub/arm64-efi/verifiers.module
 usr/lib/grub/arm64-efi/video.lst
 usr/lib/grub/arm64-efi/video.mod
 usr/lib/grub/arm64-efi/video.module
@@ -462,6 +469,8 @@ usr/lib/grub/arm64-efi/zfscrypt.mod
 usr/lib/grub/arm64-efi/zfscrypt.module
 usr/lib/grub/arm64-efi/zfsinfo.mod
 usr/lib/grub/arm64-efi/zfsinfo.module
+usr/lib/grub/arm64-efi/zstd.mod
+usr/lib/grub/arm64-efi/zstd.module
 usr/sbin/grub-bios-setup
 usr/sbin/grub-install
 usr/sbin/grub-macbless
@@ -524,7 +533,9 @@ usr/share/grub/unicode.pf2
 #usr/share/locale/pa/LC_MESSAGES
 #usr/share/locale/pa/LC_MESSAGES/grub.mo
 #usr/share/locale/pl/LC_MESSAGES/grub.mo
+#usr/share/locale/pt/LC_MESSAGES/grub.mo
 #usr/share/locale/pt_BR/LC_MESSAGES/grub.mo
+#usr/share/locale/ro/LC_MESSAGES/grub.mo
 #usr/share/locale/ru/LC_MESSAGES/grub.mo
 #usr/share/locale/sl/LC_MESSAGES/grub.mo
 #usr/share/locale/sr/LC_MESSAGES/grub.mo
index bc28d45931e5c99b99b89383892cbb7ea69563c8..4f12eda828508ad3411c9108f6fa7e3e5b9e4b9e 100644 (file)
@@ -4,7 +4,7 @@ boot/grub/splash.png
 #etc/bash_completion.d
 #etc/bash_completion.d/grub
 etc/default/grub
-etc/grub.d
+#etc/grub.d
 etc/grub.d/00_header
 etc/grub.d/10_linux
 etc/grub.d/20_linux_xen
@@ -30,561 +30,574 @@ usr/bin/grub-render-label
 usr/bin/grub-script-check
 usr/bin/grub-syslinux2cfg
 #usr/lib/grub
-usr/lib/grub/i386-pc
-#usr/lib/grub/i386-pc/acpi.mod
-#usr/lib/grub/i386-pc/acpi.module
-#usr/lib/grub/i386-pc/adler32.mod
-#usr/lib/grub/i386-pc/adler32.module
-#usr/lib/grub/i386-pc/affs.mod
-#usr/lib/grub/i386-pc/affs.module
-#usr/lib/grub/i386-pc/afs.mod
-#usr/lib/grub/i386-pc/afs.module
-#usr/lib/grub/i386-pc/ahci.mod
-#usr/lib/grub/i386-pc/ahci.module
-#usr/lib/grub/i386-pc/all_video.mod
-#usr/lib/grub/i386-pc/all_video.module
-#usr/lib/grub/i386-pc/aout.mod
-#usr/lib/grub/i386-pc/aout.module
-#usr/lib/grub/i386-pc/archelp.mod
-#usr/lib/grub/i386-pc/archelp.module
-#usr/lib/grub/i386-pc/at_keyboard.mod
-#usr/lib/grub/i386-pc/at_keyboard.module
-#usr/lib/grub/i386-pc/ata.mod
-#usr/lib/grub/i386-pc/ata.module
-#usr/lib/grub/i386-pc/backtrace.mod
-#usr/lib/grub/i386-pc/backtrace.module
-#usr/lib/grub/i386-pc/bfs.mod
-#usr/lib/grub/i386-pc/bfs.module
-#usr/lib/grub/i386-pc/biosdisk.mod
-#usr/lib/grub/i386-pc/biosdisk.module
-#usr/lib/grub/i386-pc/bitmap.mod
-#usr/lib/grub/i386-pc/bitmap.module
-#usr/lib/grub/i386-pc/bitmap_scale.mod
-#usr/lib/grub/i386-pc/bitmap_scale.module
-#usr/lib/grub/i386-pc/blocklist.mod
-#usr/lib/grub/i386-pc/blocklist.module
-#usr/lib/grub/i386-pc/boot.image
-#usr/lib/grub/i386-pc/boot.img
-#usr/lib/grub/i386-pc/boot.mod
-#usr/lib/grub/i386-pc/boot.module
-#usr/lib/grub/i386-pc/boot_hybrid.image
-#usr/lib/grub/i386-pc/boot_hybrid.img
-#usr/lib/grub/i386-pc/bsd.mod
-#usr/lib/grub/i386-pc/bsd.module
-#usr/lib/grub/i386-pc/bswap_test.mod
-#usr/lib/grub/i386-pc/bswap_test.module
-#usr/lib/grub/i386-pc/btrfs.mod
-#usr/lib/grub/i386-pc/btrfs.module
-#usr/lib/grub/i386-pc/bufio.mod
-#usr/lib/grub/i386-pc/bufio.module
-#usr/lib/grub/i386-pc/cat.mod
-#usr/lib/grub/i386-pc/cat.module
-#usr/lib/grub/i386-pc/cbfs.mod
-#usr/lib/grub/i386-pc/cbfs.module
-#usr/lib/grub/i386-pc/cbls.mod
-#usr/lib/grub/i386-pc/cbls.module
-#usr/lib/grub/i386-pc/cbmemc.mod
-#usr/lib/grub/i386-pc/cbmemc.module
-#usr/lib/grub/i386-pc/cbtable.mod
-#usr/lib/grub/i386-pc/cbtable.module
-#usr/lib/grub/i386-pc/cbtime.mod
-#usr/lib/grub/i386-pc/cbtime.module
-#usr/lib/grub/i386-pc/cdboot.image
-#usr/lib/grub/i386-pc/cdboot.img
-#usr/lib/grub/i386-pc/chain.mod
-#usr/lib/grub/i386-pc/chain.module
-#usr/lib/grub/i386-pc/cmdline_cat_test.mod
-#usr/lib/grub/i386-pc/cmdline_cat_test.module
-#usr/lib/grub/i386-pc/cmosdump.mod
-#usr/lib/grub/i386-pc/cmosdump.module
-#usr/lib/grub/i386-pc/cmostest.mod
-#usr/lib/grub/i386-pc/cmostest.module
-#usr/lib/grub/i386-pc/cmp.mod
-#usr/lib/grub/i386-pc/cmp.module
-#usr/lib/grub/i386-pc/cmp_test.mod
-#usr/lib/grub/i386-pc/cmp_test.module
-#usr/lib/grub/i386-pc/command.lst
-#usr/lib/grub/i386-pc/config.h
-#usr/lib/grub/i386-pc/configfile.mod
-#usr/lib/grub/i386-pc/configfile.module
-#usr/lib/grub/i386-pc/cpio.mod
-#usr/lib/grub/i386-pc/cpio.module
-#usr/lib/grub/i386-pc/cpio_be.mod
-#usr/lib/grub/i386-pc/cpio_be.module
-#usr/lib/grub/i386-pc/cpuid.mod
-#usr/lib/grub/i386-pc/cpuid.module
-#usr/lib/grub/i386-pc/crc64.mod
-#usr/lib/grub/i386-pc/crc64.module
-#usr/lib/grub/i386-pc/crypto.lst
-#usr/lib/grub/i386-pc/crypto.mod
-#usr/lib/grub/i386-pc/crypto.module
-#usr/lib/grub/i386-pc/cryptodisk.mod
-#usr/lib/grub/i386-pc/cryptodisk.module
-#usr/lib/grub/i386-pc/cs5536.mod
-#usr/lib/grub/i386-pc/cs5536.module
-#usr/lib/grub/i386-pc/ctz_test.mod
-#usr/lib/grub/i386-pc/ctz_test.module
-#usr/lib/grub/i386-pc/date.mod
-#usr/lib/grub/i386-pc/date.module
-#usr/lib/grub/i386-pc/datehook.mod
-#usr/lib/grub/i386-pc/datehook.module
-#usr/lib/grub/i386-pc/datetime.mod
-#usr/lib/grub/i386-pc/datetime.module
-#usr/lib/grub/i386-pc/disk.mod
-#usr/lib/grub/i386-pc/disk.module
-#usr/lib/grub/i386-pc/diskboot.image
-#usr/lib/grub/i386-pc/diskboot.img
-#usr/lib/grub/i386-pc/diskfilter.mod
-#usr/lib/grub/i386-pc/diskfilter.module
-#usr/lib/grub/i386-pc/div.mod
-#usr/lib/grub/i386-pc/div.module
-#usr/lib/grub/i386-pc/div_test.mod
-#usr/lib/grub/i386-pc/div_test.module
-#usr/lib/grub/i386-pc/dm_nv.mod
-#usr/lib/grub/i386-pc/dm_nv.module
-#usr/lib/grub/i386-pc/drivemap.mod
-#usr/lib/grub/i386-pc/drivemap.module
-#usr/lib/grub/i386-pc/echo.mod
-#usr/lib/grub/i386-pc/echo.module
-#usr/lib/grub/i386-pc/efiemu.mod
-#usr/lib/grub/i386-pc/efiemu.module
-#usr/lib/grub/i386-pc/ehci.mod
-#usr/lib/grub/i386-pc/ehci.module
-#usr/lib/grub/i386-pc/elf.mod
-#usr/lib/grub/i386-pc/elf.module
-#usr/lib/grub/i386-pc/eval.mod
-#usr/lib/grub/i386-pc/eval.module
-#usr/lib/grub/i386-pc/exfat.mod
-#usr/lib/grub/i386-pc/exfat.module
-#usr/lib/grub/i386-pc/exfctest.mod
-#usr/lib/grub/i386-pc/exfctest.module
-#usr/lib/grub/i386-pc/ext2.mod
-#usr/lib/grub/i386-pc/ext2.module
-#usr/lib/grub/i386-pc/extcmd.mod
-#usr/lib/grub/i386-pc/extcmd.module
-#usr/lib/grub/i386-pc/fat.mod
-#usr/lib/grub/i386-pc/fat.module
-#usr/lib/grub/i386-pc/file.mod
-#usr/lib/grub/i386-pc/file.module
-#usr/lib/grub/i386-pc/font.mod
-#usr/lib/grub/i386-pc/font.module
-#usr/lib/grub/i386-pc/freedos.mod
-#usr/lib/grub/i386-pc/freedos.module
-#usr/lib/grub/i386-pc/fs.lst
-#usr/lib/grub/i386-pc/fshelp.mod
-#usr/lib/grub/i386-pc/fshelp.module
-#usr/lib/grub/i386-pc/functional_test.mod
-#usr/lib/grub/i386-pc/functional_test.module
-#usr/lib/grub/i386-pc/gcry_arcfour.mod
-#usr/lib/grub/i386-pc/gcry_arcfour.module
-#usr/lib/grub/i386-pc/gcry_blowfish.mod
-#usr/lib/grub/i386-pc/gcry_blowfish.module
-#usr/lib/grub/i386-pc/gcry_camellia.mod
-#usr/lib/grub/i386-pc/gcry_camellia.module
-#usr/lib/grub/i386-pc/gcry_cast5.mod
-#usr/lib/grub/i386-pc/gcry_cast5.module
-#usr/lib/grub/i386-pc/gcry_crc.mod
-#usr/lib/grub/i386-pc/gcry_crc.module
-#usr/lib/grub/i386-pc/gcry_des.mod
-#usr/lib/grub/i386-pc/gcry_des.module
-#usr/lib/grub/i386-pc/gcry_dsa.mod
-#usr/lib/grub/i386-pc/gcry_dsa.module
-#usr/lib/grub/i386-pc/gcry_idea.mod
-#usr/lib/grub/i386-pc/gcry_idea.module
-#usr/lib/grub/i386-pc/gcry_md4.mod
-#usr/lib/grub/i386-pc/gcry_md4.module
-#usr/lib/grub/i386-pc/gcry_md5.mod
-#usr/lib/grub/i386-pc/gcry_md5.module
-#usr/lib/grub/i386-pc/gcry_rfc2268.mod
-#usr/lib/grub/i386-pc/gcry_rfc2268.module
-#usr/lib/grub/i386-pc/gcry_rijndael.mod
-#usr/lib/grub/i386-pc/gcry_rijndael.module
-#usr/lib/grub/i386-pc/gcry_rmd160.mod
-#usr/lib/grub/i386-pc/gcry_rmd160.module
-#usr/lib/grub/i386-pc/gcry_rsa.mod
-#usr/lib/grub/i386-pc/gcry_rsa.module
-#usr/lib/grub/i386-pc/gcry_seed.mod
-#usr/lib/grub/i386-pc/gcry_seed.module
-#usr/lib/grub/i386-pc/gcry_serpent.mod
-#usr/lib/grub/i386-pc/gcry_serpent.module
-#usr/lib/grub/i386-pc/gcry_sha1.mod
-#usr/lib/grub/i386-pc/gcry_sha1.module
-#usr/lib/grub/i386-pc/gcry_sha256.mod
-#usr/lib/grub/i386-pc/gcry_sha256.module
-#usr/lib/grub/i386-pc/gcry_sha512.mod
-#usr/lib/grub/i386-pc/gcry_sha512.module
-#usr/lib/grub/i386-pc/gcry_tiger.mod
-#usr/lib/grub/i386-pc/gcry_tiger.module
-#usr/lib/grub/i386-pc/gcry_twofish.mod
-#usr/lib/grub/i386-pc/gcry_twofish.module
-#usr/lib/grub/i386-pc/gcry_whirlpool.mod
-#usr/lib/grub/i386-pc/gcry_whirlpool.module
-#usr/lib/grub/i386-pc/gdb.mod
-#usr/lib/grub/i386-pc/gdb.module
-#usr/lib/grub/i386-pc/gdb_grub
-#usr/lib/grub/i386-pc/geli.mod
-#usr/lib/grub/i386-pc/geli.module
-#usr/lib/grub/i386-pc/gettext.mod
-#usr/lib/grub/i386-pc/gettext.module
-#usr/lib/grub/i386-pc/gfxmenu.mod
-#usr/lib/grub/i386-pc/gfxmenu.module
-#usr/lib/grub/i386-pc/gfxterm.mod
-#usr/lib/grub/i386-pc/gfxterm.module
-#usr/lib/grub/i386-pc/gfxterm_background.mod
-#usr/lib/grub/i386-pc/gfxterm_background.module
-#usr/lib/grub/i386-pc/gfxterm_menu.mod
-#usr/lib/grub/i386-pc/gfxterm_menu.module
-#usr/lib/grub/i386-pc/gmodule.pl
-#usr/lib/grub/i386-pc/gptsync.mod
-#usr/lib/grub/i386-pc/gptsync.module
-#usr/lib/grub/i386-pc/gzio.mod
-#usr/lib/grub/i386-pc/gzio.module
-#usr/lib/grub/i386-pc/halt.mod
-#usr/lib/grub/i386-pc/halt.module
-#usr/lib/grub/i386-pc/hashsum.mod
-#usr/lib/grub/i386-pc/hashsum.module
-#usr/lib/grub/i386-pc/hdparm.mod
-#usr/lib/grub/i386-pc/hdparm.module
-#usr/lib/grub/i386-pc/hello.mod
-#usr/lib/grub/i386-pc/hello.module
-#usr/lib/grub/i386-pc/help.mod
-#usr/lib/grub/i386-pc/help.module
-#usr/lib/grub/i386-pc/hexdump.mod
-#usr/lib/grub/i386-pc/hexdump.module
-#usr/lib/grub/i386-pc/hfs.mod
-#usr/lib/grub/i386-pc/hfs.module
-#usr/lib/grub/i386-pc/hfsplus.mod
-#usr/lib/grub/i386-pc/hfsplus.module
-#usr/lib/grub/i386-pc/hfspluscomp.mod
-#usr/lib/grub/i386-pc/hfspluscomp.module
-#usr/lib/grub/i386-pc/http.mod
-#usr/lib/grub/i386-pc/http.module
-#usr/lib/grub/i386-pc/iorw.mod
-#usr/lib/grub/i386-pc/iorw.module
-#usr/lib/grub/i386-pc/iso9660.mod
-#usr/lib/grub/i386-pc/iso9660.module
-#usr/lib/grub/i386-pc/jfs.mod
-#usr/lib/grub/i386-pc/jfs.module
-#usr/lib/grub/i386-pc/jpeg.mod
-#usr/lib/grub/i386-pc/jpeg.module
-#usr/lib/grub/i386-pc/kernel.exec
-#usr/lib/grub/i386-pc/kernel.img
-#usr/lib/grub/i386-pc/keylayouts.mod
-#usr/lib/grub/i386-pc/keylayouts.module
-#usr/lib/grub/i386-pc/keystatus.mod
-#usr/lib/grub/i386-pc/keystatus.module
-#usr/lib/grub/i386-pc/ldm.mod
-#usr/lib/grub/i386-pc/ldm.module
-#usr/lib/grub/i386-pc/legacy_password_test.mod
-#usr/lib/grub/i386-pc/legacy_password_test.module
-#usr/lib/grub/i386-pc/legacycfg.mod
-#usr/lib/grub/i386-pc/legacycfg.module
-#usr/lib/grub/i386-pc/linux.mod
-#usr/lib/grub/i386-pc/linux.module
-#usr/lib/grub/i386-pc/linux16.mod
-#usr/lib/grub/i386-pc/linux16.module
-#usr/lib/grub/i386-pc/lnxboot.image
-#usr/lib/grub/i386-pc/lnxboot.img
-#usr/lib/grub/i386-pc/loadenv.mod
-#usr/lib/grub/i386-pc/loadenv.module
-#usr/lib/grub/i386-pc/loopback.mod
-#usr/lib/grub/i386-pc/loopback.module
-#usr/lib/grub/i386-pc/ls.mod
-#usr/lib/grub/i386-pc/ls.module
-#usr/lib/grub/i386-pc/lsacpi.mod
-#usr/lib/grub/i386-pc/lsacpi.module
-#usr/lib/grub/i386-pc/lsapm.mod
-#usr/lib/grub/i386-pc/lsapm.module
-#usr/lib/grub/i386-pc/lsmmap.mod
-#usr/lib/grub/i386-pc/lsmmap.module
-#usr/lib/grub/i386-pc/lspci.mod
-#usr/lib/grub/i386-pc/lspci.module
-#usr/lib/grub/i386-pc/luks.mod
-#usr/lib/grub/i386-pc/luks.module
-#usr/lib/grub/i386-pc/lvm.mod
-#usr/lib/grub/i386-pc/lvm.module
-#usr/lib/grub/i386-pc/lzma_decompress.image
-#usr/lib/grub/i386-pc/lzma_decompress.img
-#usr/lib/grub/i386-pc/lzopio.mod
-#usr/lib/grub/i386-pc/lzopio.module
-#usr/lib/grub/i386-pc/macbless.mod
-#usr/lib/grub/i386-pc/macbless.module
-#usr/lib/grub/i386-pc/macho.mod
-#usr/lib/grub/i386-pc/macho.module
-#usr/lib/grub/i386-pc/mda_text.mod
-#usr/lib/grub/i386-pc/mda_text.module
-#usr/lib/grub/i386-pc/mdraid09.mod
-#usr/lib/grub/i386-pc/mdraid09.module
-#usr/lib/grub/i386-pc/mdraid09_be.mod
-#usr/lib/grub/i386-pc/mdraid09_be.module
-#usr/lib/grub/i386-pc/mdraid1x.mod
-#usr/lib/grub/i386-pc/mdraid1x.module
-#usr/lib/grub/i386-pc/memdisk.mod
-#usr/lib/grub/i386-pc/memdisk.module
-#usr/lib/grub/i386-pc/memrw.mod
-#usr/lib/grub/i386-pc/memrw.module
-#usr/lib/grub/i386-pc/minicmd.mod
-#usr/lib/grub/i386-pc/minicmd.module
-#usr/lib/grub/i386-pc/minix.mod
-#usr/lib/grub/i386-pc/minix.module
-#usr/lib/grub/i386-pc/minix2.mod
-#usr/lib/grub/i386-pc/minix2.module
-#usr/lib/grub/i386-pc/minix2_be.mod
-#usr/lib/grub/i386-pc/minix2_be.module
-#usr/lib/grub/i386-pc/minix3.mod
-#usr/lib/grub/i386-pc/minix3.module
-#usr/lib/grub/i386-pc/minix3_be.mod
-#usr/lib/grub/i386-pc/minix3_be.module
-#usr/lib/grub/i386-pc/minix_be.mod
-#usr/lib/grub/i386-pc/minix_be.module
-#usr/lib/grub/i386-pc/mmap.mod
-#usr/lib/grub/i386-pc/mmap.module
-#usr/lib/grub/i386-pc/moddep.lst
-#usr/lib/grub/i386-pc/modinfo.sh
-#usr/lib/grub/i386-pc/morse.mod
-#usr/lib/grub/i386-pc/morse.module
-#usr/lib/grub/i386-pc/mpi.mod
-#usr/lib/grub/i386-pc/mpi.module
-#usr/lib/grub/i386-pc/msdospart.mod
-#usr/lib/grub/i386-pc/msdospart.module
-#usr/lib/grub/i386-pc/mul_test.mod
-#usr/lib/grub/i386-pc/mul_test.module
-#usr/lib/grub/i386-pc/multiboot.mod
-#usr/lib/grub/i386-pc/multiboot.module
-#usr/lib/grub/i386-pc/multiboot2.mod
-#usr/lib/grub/i386-pc/multiboot2.module
-#usr/lib/grub/i386-pc/nativedisk.mod
-#usr/lib/grub/i386-pc/nativedisk.module
-#usr/lib/grub/i386-pc/net.mod
-#usr/lib/grub/i386-pc/net.module
-#usr/lib/grub/i386-pc/newc.mod
-#usr/lib/grub/i386-pc/newc.module
-#usr/lib/grub/i386-pc/nilfs2.mod
-#usr/lib/grub/i386-pc/nilfs2.module
-#usr/lib/grub/i386-pc/normal.mod
-#usr/lib/grub/i386-pc/normal.module
-#usr/lib/grub/i386-pc/ntfs.mod
-#usr/lib/grub/i386-pc/ntfs.module
-#usr/lib/grub/i386-pc/ntfscomp.mod
-#usr/lib/grub/i386-pc/ntfscomp.module
-#usr/lib/grub/i386-pc/ntldr.mod
-#usr/lib/grub/i386-pc/ntldr.module
-#usr/lib/grub/i386-pc/odc.mod
-#usr/lib/grub/i386-pc/odc.module
-#usr/lib/grub/i386-pc/offsetio.mod
-#usr/lib/grub/i386-pc/offsetio.module
-#usr/lib/grub/i386-pc/ohci.mod
-#usr/lib/grub/i386-pc/ohci.module
-#usr/lib/grub/i386-pc/part_acorn.mod
-#usr/lib/grub/i386-pc/part_acorn.module
-#usr/lib/grub/i386-pc/part_amiga.mod
-#usr/lib/grub/i386-pc/part_amiga.module
-#usr/lib/grub/i386-pc/part_apple.mod
-#usr/lib/grub/i386-pc/part_apple.module
-#usr/lib/grub/i386-pc/part_bsd.mod
-#usr/lib/grub/i386-pc/part_bsd.module
-#usr/lib/grub/i386-pc/part_dfly.mod
-#usr/lib/grub/i386-pc/part_dfly.module
-#usr/lib/grub/i386-pc/part_dvh.mod
-#usr/lib/grub/i386-pc/part_dvh.module
-#usr/lib/grub/i386-pc/part_gpt.mod
-#usr/lib/grub/i386-pc/part_gpt.module
-#usr/lib/grub/i386-pc/part_msdos.mod
-#usr/lib/grub/i386-pc/part_msdos.module
-#usr/lib/grub/i386-pc/part_plan.mod
-#usr/lib/grub/i386-pc/part_plan.module
-#usr/lib/grub/i386-pc/part_sun.mod
-#usr/lib/grub/i386-pc/part_sun.module
-#usr/lib/grub/i386-pc/part_sunpc.mod
-#usr/lib/grub/i386-pc/part_sunpc.module
-#usr/lib/grub/i386-pc/partmap.lst
-#usr/lib/grub/i386-pc/parttool.lst
-#usr/lib/grub/i386-pc/parttool.mod
-#usr/lib/grub/i386-pc/parttool.module
-#usr/lib/grub/i386-pc/password.mod
-#usr/lib/grub/i386-pc/password.module
-#usr/lib/grub/i386-pc/password_pbkdf2.mod
-#usr/lib/grub/i386-pc/password_pbkdf2.module
-#usr/lib/grub/i386-pc/pata.mod
-#usr/lib/grub/i386-pc/pata.module
-#usr/lib/grub/i386-pc/pbkdf2.mod
-#usr/lib/grub/i386-pc/pbkdf2.module
-#usr/lib/grub/i386-pc/pbkdf2_test.mod
-#usr/lib/grub/i386-pc/pbkdf2_test.module
-#usr/lib/grub/i386-pc/pci.mod
-#usr/lib/grub/i386-pc/pci.module
-#usr/lib/grub/i386-pc/pcidump.mod
-#usr/lib/grub/i386-pc/pcidump.module
-#usr/lib/grub/i386-pc/plan9.mod
-#usr/lib/grub/i386-pc/plan9.module
-#usr/lib/grub/i386-pc/play.mod
-#usr/lib/grub/i386-pc/play.module
-#usr/lib/grub/i386-pc/png.mod
-#usr/lib/grub/i386-pc/png.module
-#usr/lib/grub/i386-pc/priority_queue.mod
-#usr/lib/grub/i386-pc/priority_queue.module
-#usr/lib/grub/i386-pc/probe.mod
-#usr/lib/grub/i386-pc/probe.module
-#usr/lib/grub/i386-pc/procfs.mod
-#usr/lib/grub/i386-pc/procfs.module
-#usr/lib/grub/i386-pc/progress.mod
-#usr/lib/grub/i386-pc/progress.module
-#usr/lib/grub/i386-pc/pxe.mod
-#usr/lib/grub/i386-pc/pxe.module
-#usr/lib/grub/i386-pc/pxeboot.image
-#usr/lib/grub/i386-pc/pxeboot.img
-#usr/lib/grub/i386-pc/pxechain.mod
-#usr/lib/grub/i386-pc/pxechain.module
-#usr/lib/grub/i386-pc/raid5rec.mod
-#usr/lib/grub/i386-pc/raid5rec.module
-#usr/lib/grub/i386-pc/raid6rec.mod
-#usr/lib/grub/i386-pc/raid6rec.module
-#usr/lib/grub/i386-pc/random.mod
-#usr/lib/grub/i386-pc/random.module
-#usr/lib/grub/i386-pc/read.mod
-#usr/lib/grub/i386-pc/read.module
-#usr/lib/grub/i386-pc/reboot.mod
-#usr/lib/grub/i386-pc/reboot.module
-#usr/lib/grub/i386-pc/regexp.mod
-#usr/lib/grub/i386-pc/regexp.module
-#usr/lib/grub/i386-pc/reiserfs.mod
-#usr/lib/grub/i386-pc/reiserfs.module
-#usr/lib/grub/i386-pc/relocator.mod
-#usr/lib/grub/i386-pc/relocator.module
-#usr/lib/grub/i386-pc/romfs.mod
-#usr/lib/grub/i386-pc/romfs.module
-#usr/lib/grub/i386-pc/scsi.mod
-#usr/lib/grub/i386-pc/scsi.module
-#usr/lib/grub/i386-pc/search.mod
-#usr/lib/grub/i386-pc/search.module
-#usr/lib/grub/i386-pc/search_fs_file.mod
-#usr/lib/grub/i386-pc/search_fs_file.module
-#usr/lib/grub/i386-pc/search_fs_uuid.mod
-#usr/lib/grub/i386-pc/search_fs_uuid.module
-#usr/lib/grub/i386-pc/search_label.mod
-#usr/lib/grub/i386-pc/search_label.module
-#usr/lib/grub/i386-pc/sendkey.mod
-#usr/lib/grub/i386-pc/sendkey.module
-#usr/lib/grub/i386-pc/serial.mod
-#usr/lib/grub/i386-pc/serial.module
-#usr/lib/grub/i386-pc/setjmp.mod
-#usr/lib/grub/i386-pc/setjmp.module
-#usr/lib/grub/i386-pc/setjmp_test.mod
-#usr/lib/grub/i386-pc/setjmp_test.module
-#usr/lib/grub/i386-pc/setpci.mod
-#usr/lib/grub/i386-pc/setpci.module
-#usr/lib/grub/i386-pc/sfs.mod
-#usr/lib/grub/i386-pc/sfs.module
-#usr/lib/grub/i386-pc/shift_test.mod
-#usr/lib/grub/i386-pc/shift_test.module
-#usr/lib/grub/i386-pc/signature_test.mod
-#usr/lib/grub/i386-pc/signature_test.module
-#usr/lib/grub/i386-pc/sleep.mod
-#usr/lib/grub/i386-pc/sleep.module
-#usr/lib/grub/i386-pc/sleep_test.mod
-#usr/lib/grub/i386-pc/sleep_test.module
-#usr/lib/grub/i386-pc/spkmodem.mod
-#usr/lib/grub/i386-pc/spkmodem.module
-#usr/lib/grub/i386-pc/squash4.mod
-#usr/lib/grub/i386-pc/squash4.module
-#usr/lib/grub/i386-pc/syslinuxcfg.mod
-#usr/lib/grub/i386-pc/syslinuxcfg.module
-#usr/lib/grub/i386-pc/tar.mod
-#usr/lib/grub/i386-pc/tar.module
-#usr/lib/grub/i386-pc/terminal.lst
-#usr/lib/grub/i386-pc/terminal.mod
-#usr/lib/grub/i386-pc/terminal.module
-#usr/lib/grub/i386-pc/terminfo.mod
-#usr/lib/grub/i386-pc/terminfo.module
-#usr/lib/grub/i386-pc/test.mod
-#usr/lib/grub/i386-pc/test.module
-#usr/lib/grub/i386-pc/test_blockarg.mod
-#usr/lib/grub/i386-pc/test_blockarg.module
-#usr/lib/grub/i386-pc/testload.mod
-#usr/lib/grub/i386-pc/testload.module
-#usr/lib/grub/i386-pc/testspeed.mod
-#usr/lib/grub/i386-pc/testspeed.module
-#usr/lib/grub/i386-pc/tftp.mod
-#usr/lib/grub/i386-pc/tftp.module
-#usr/lib/grub/i386-pc/tga.mod
-#usr/lib/grub/i386-pc/tga.module
-#usr/lib/grub/i386-pc/time.mod
-#usr/lib/grub/i386-pc/time.module
-#usr/lib/grub/i386-pc/tr.mod
-#usr/lib/grub/i386-pc/tr.module
-#usr/lib/grub/i386-pc/trig.mod
-#usr/lib/grub/i386-pc/trig.module
-#usr/lib/grub/i386-pc/true.mod
-#usr/lib/grub/i386-pc/true.module
-#usr/lib/grub/i386-pc/truecrypt.mod
-#usr/lib/grub/i386-pc/truecrypt.module
-#usr/lib/grub/i386-pc/udf.mod
-#usr/lib/grub/i386-pc/udf.module
-#usr/lib/grub/i386-pc/ufs1.mod
-#usr/lib/grub/i386-pc/ufs1.module
-#usr/lib/grub/i386-pc/ufs1_be.mod
-#usr/lib/grub/i386-pc/ufs1_be.module
-#usr/lib/grub/i386-pc/ufs2.mod
-#usr/lib/grub/i386-pc/ufs2.module
-#usr/lib/grub/i386-pc/uhci.mod
-#usr/lib/grub/i386-pc/uhci.module
-#usr/lib/grub/i386-pc/usb.mod
-#usr/lib/grub/i386-pc/usb.module
-#usr/lib/grub/i386-pc/usb_keyboard.mod
-#usr/lib/grub/i386-pc/usb_keyboard.module
-#usr/lib/grub/i386-pc/usbms.mod
-#usr/lib/grub/i386-pc/usbms.module
-#usr/lib/grub/i386-pc/usbserial_common.mod
-#usr/lib/grub/i386-pc/usbserial_common.module
-#usr/lib/grub/i386-pc/usbserial_ftdi.mod
-#usr/lib/grub/i386-pc/usbserial_ftdi.module
-#usr/lib/grub/i386-pc/usbserial_pl2303.mod
-#usr/lib/grub/i386-pc/usbserial_pl2303.module
-#usr/lib/grub/i386-pc/usbserial_usbdebug.mod
-#usr/lib/grub/i386-pc/usbserial_usbdebug.module
-#usr/lib/grub/i386-pc/usbtest.mod
-#usr/lib/grub/i386-pc/usbtest.module
-#usr/lib/grub/i386-pc/vbe.mod
-#usr/lib/grub/i386-pc/vbe.module
-#usr/lib/grub/i386-pc/verify.mod
-#usr/lib/grub/i386-pc/verify.module
-#usr/lib/grub/i386-pc/vga.mod
-#usr/lib/grub/i386-pc/vga.module
-#usr/lib/grub/i386-pc/vga_text.mod
-#usr/lib/grub/i386-pc/vga_text.module
-#usr/lib/grub/i386-pc/video.lst
-#usr/lib/grub/i386-pc/video.mod
-#usr/lib/grub/i386-pc/video.module
-#usr/lib/grub/i386-pc/video_bochs.mod
-#usr/lib/grub/i386-pc/video_bochs.module
-#usr/lib/grub/i386-pc/video_cirrus.mod
-#usr/lib/grub/i386-pc/video_cirrus.module
-#usr/lib/grub/i386-pc/video_colors.mod
-#usr/lib/grub/i386-pc/video_colors.module
-#usr/lib/grub/i386-pc/video_fb.mod
-#usr/lib/grub/i386-pc/video_fb.module
-#usr/lib/grub/i386-pc/videoinfo.mod
-#usr/lib/grub/i386-pc/videoinfo.module
-#usr/lib/grub/i386-pc/videotest.mod
-#usr/lib/grub/i386-pc/videotest.module
-#usr/lib/grub/i386-pc/videotest_checksum.mod
-#usr/lib/grub/i386-pc/videotest_checksum.module
-#usr/lib/grub/i386-pc/xfs.mod
-#usr/lib/grub/i386-pc/xfs.module
-#usr/lib/grub/i386-pc/xnu.mod
-#usr/lib/grub/i386-pc/xnu.module
-#usr/lib/grub/i386-pc/xnu_uuid.mod
-#usr/lib/grub/i386-pc/xnu_uuid.module
-#usr/lib/grub/i386-pc/xnu_uuid_test.mod
-#usr/lib/grub/i386-pc/xnu_uuid_test.module
-#usr/lib/grub/i386-pc/xzio.mod
-#usr/lib/grub/i386-pc/xzio.module
-#usr/lib/grub/i386-pc/zfs.mod
-#usr/lib/grub/i386-pc/zfs.module
-#usr/lib/grub/i386-pc/zfscrypt.mod
-#usr/lib/grub/i386-pc/zfscrypt.module
-#usr/lib/grub/i386-pc/zfsinfo.mod
-#usr/lib/grub/i386-pc/zfsinfo.module
+#usr/lib/grub/i386-pc
+usr/lib/grub/i386-pc/acpi.mod
+usr/lib/grub/i386-pc/acpi.module
+usr/lib/grub/i386-pc/adler32.mod
+usr/lib/grub/i386-pc/adler32.module
+usr/lib/grub/i386-pc/affs.mod
+usr/lib/grub/i386-pc/affs.module
+usr/lib/grub/i386-pc/afs.mod
+usr/lib/grub/i386-pc/afs.module
+usr/lib/grub/i386-pc/ahci.mod
+usr/lib/grub/i386-pc/ahci.module
+usr/lib/grub/i386-pc/all_video.mod
+usr/lib/grub/i386-pc/all_video.module
+usr/lib/grub/i386-pc/aout.mod
+usr/lib/grub/i386-pc/aout.module
+usr/lib/grub/i386-pc/archelp.mod
+usr/lib/grub/i386-pc/archelp.module
+usr/lib/grub/i386-pc/at_keyboard.mod
+usr/lib/grub/i386-pc/at_keyboard.module
+usr/lib/grub/i386-pc/ata.mod
+usr/lib/grub/i386-pc/ata.module
+usr/lib/grub/i386-pc/backtrace.mod
+usr/lib/grub/i386-pc/backtrace.module
+usr/lib/grub/i386-pc/bfs.mod
+usr/lib/grub/i386-pc/bfs.module
+usr/lib/grub/i386-pc/biosdisk.mod
+usr/lib/grub/i386-pc/biosdisk.module
+usr/lib/grub/i386-pc/bitmap.mod
+usr/lib/grub/i386-pc/bitmap.module
+usr/lib/grub/i386-pc/bitmap_scale.mod
+usr/lib/grub/i386-pc/bitmap_scale.module
+usr/lib/grub/i386-pc/blocklist.mod
+usr/lib/grub/i386-pc/blocklist.module
+usr/lib/grub/i386-pc/boot.image
+usr/lib/grub/i386-pc/boot.img
+usr/lib/grub/i386-pc/boot.mod
+usr/lib/grub/i386-pc/boot.module
+usr/lib/grub/i386-pc/boot_hybrid.image
+usr/lib/grub/i386-pc/boot_hybrid.img
+usr/lib/grub/i386-pc/bsd.mod
+usr/lib/grub/i386-pc/bsd.module
+usr/lib/grub/i386-pc/bswap_test.mod
+usr/lib/grub/i386-pc/bswap_test.module
+usr/lib/grub/i386-pc/btrfs.mod
+usr/lib/grub/i386-pc/btrfs.module
+usr/lib/grub/i386-pc/bufio.mod
+usr/lib/grub/i386-pc/bufio.module
+usr/lib/grub/i386-pc/cat.mod
+usr/lib/grub/i386-pc/cat.module
+usr/lib/grub/i386-pc/cbfs.mod
+usr/lib/grub/i386-pc/cbfs.module
+usr/lib/grub/i386-pc/cbls.mod
+usr/lib/grub/i386-pc/cbls.module
+usr/lib/grub/i386-pc/cbmemc.mod
+usr/lib/grub/i386-pc/cbmemc.module
+usr/lib/grub/i386-pc/cbtable.mod
+usr/lib/grub/i386-pc/cbtable.module
+usr/lib/grub/i386-pc/cbtime.mod
+usr/lib/grub/i386-pc/cbtime.module
+usr/lib/grub/i386-pc/cdboot.image
+usr/lib/grub/i386-pc/cdboot.img
+usr/lib/grub/i386-pc/chain.mod
+usr/lib/grub/i386-pc/chain.module
+usr/lib/grub/i386-pc/cmdline_cat_test.mod
+usr/lib/grub/i386-pc/cmdline_cat_test.module
+usr/lib/grub/i386-pc/cmosdump.mod
+usr/lib/grub/i386-pc/cmosdump.module
+usr/lib/grub/i386-pc/cmostest.mod
+usr/lib/grub/i386-pc/cmostest.module
+usr/lib/grub/i386-pc/cmp.mod
+usr/lib/grub/i386-pc/cmp.module
+usr/lib/grub/i386-pc/cmp_test.mod
+usr/lib/grub/i386-pc/cmp_test.module
+usr/lib/grub/i386-pc/command.lst
+usr/lib/grub/i386-pc/config.h
+usr/lib/grub/i386-pc/configfile.mod
+usr/lib/grub/i386-pc/configfile.module
+usr/lib/grub/i386-pc/cpio.mod
+usr/lib/grub/i386-pc/cpio.module
+usr/lib/grub/i386-pc/cpio_be.mod
+usr/lib/grub/i386-pc/cpio_be.module
+usr/lib/grub/i386-pc/cpuid.mod
+usr/lib/grub/i386-pc/cpuid.module
+usr/lib/grub/i386-pc/crc64.mod
+usr/lib/grub/i386-pc/crc64.module
+usr/lib/grub/i386-pc/crypto.lst
+usr/lib/grub/i386-pc/crypto.mod
+usr/lib/grub/i386-pc/crypto.module
+usr/lib/grub/i386-pc/cryptodisk.mod
+usr/lib/grub/i386-pc/cryptodisk.module
+usr/lib/grub/i386-pc/cs5536.mod
+usr/lib/grub/i386-pc/cs5536.module
+usr/lib/grub/i386-pc/ctz_test.mod
+usr/lib/grub/i386-pc/ctz_test.module
+usr/lib/grub/i386-pc/date.mod
+usr/lib/grub/i386-pc/date.module
+usr/lib/grub/i386-pc/datehook.mod
+usr/lib/grub/i386-pc/datehook.module
+usr/lib/grub/i386-pc/datetime.mod
+usr/lib/grub/i386-pc/datetime.module
+usr/lib/grub/i386-pc/disk.mod
+usr/lib/grub/i386-pc/disk.module
+usr/lib/grub/i386-pc/diskboot.image
+usr/lib/grub/i386-pc/diskboot.img
+usr/lib/grub/i386-pc/diskfilter.mod
+usr/lib/grub/i386-pc/diskfilter.module
+usr/lib/grub/i386-pc/div.mod
+usr/lib/grub/i386-pc/div.module
+usr/lib/grub/i386-pc/div_test.mod
+usr/lib/grub/i386-pc/div_test.module
+usr/lib/grub/i386-pc/dm_nv.mod
+usr/lib/grub/i386-pc/dm_nv.module
+usr/lib/grub/i386-pc/drivemap.mod
+usr/lib/grub/i386-pc/drivemap.module
+usr/lib/grub/i386-pc/echo.mod
+usr/lib/grub/i386-pc/echo.module
+usr/lib/grub/i386-pc/efiemu.mod
+usr/lib/grub/i386-pc/efiemu.module
+usr/lib/grub/i386-pc/ehci.mod
+usr/lib/grub/i386-pc/ehci.module
+usr/lib/grub/i386-pc/elf.mod
+usr/lib/grub/i386-pc/elf.module
+usr/lib/grub/i386-pc/eval.mod
+usr/lib/grub/i386-pc/eval.module
+usr/lib/grub/i386-pc/exfat.mod
+usr/lib/grub/i386-pc/exfat.module
+usr/lib/grub/i386-pc/exfctest.mod
+usr/lib/grub/i386-pc/exfctest.module
+usr/lib/grub/i386-pc/ext2.mod
+usr/lib/grub/i386-pc/ext2.module
+usr/lib/grub/i386-pc/extcmd.mod
+usr/lib/grub/i386-pc/extcmd.module
+usr/lib/grub/i386-pc/f2fs.mod
+usr/lib/grub/i386-pc/f2fs.module
+usr/lib/grub/i386-pc/fat.mod
+usr/lib/grub/i386-pc/fat.module
+usr/lib/grub/i386-pc/fdt.lst
+usr/lib/grub/i386-pc/file.mod
+usr/lib/grub/i386-pc/file.module
+usr/lib/grub/i386-pc/font.mod
+usr/lib/grub/i386-pc/font.module
+usr/lib/grub/i386-pc/freedos.mod
+usr/lib/grub/i386-pc/freedos.module
+usr/lib/grub/i386-pc/fs.lst
+usr/lib/grub/i386-pc/fshelp.mod
+usr/lib/grub/i386-pc/fshelp.module
+usr/lib/grub/i386-pc/functional_test.mod
+usr/lib/grub/i386-pc/functional_test.module
+usr/lib/grub/i386-pc/gcry_arcfour.mod
+usr/lib/grub/i386-pc/gcry_arcfour.module
+usr/lib/grub/i386-pc/gcry_blowfish.mod
+usr/lib/grub/i386-pc/gcry_blowfish.module
+usr/lib/grub/i386-pc/gcry_camellia.mod
+usr/lib/grub/i386-pc/gcry_camellia.module
+usr/lib/grub/i386-pc/gcry_cast5.mod
+usr/lib/grub/i386-pc/gcry_cast5.module
+usr/lib/grub/i386-pc/gcry_crc.mod
+usr/lib/grub/i386-pc/gcry_crc.module
+usr/lib/grub/i386-pc/gcry_des.mod
+usr/lib/grub/i386-pc/gcry_des.module
+usr/lib/grub/i386-pc/gcry_dsa.mod
+usr/lib/grub/i386-pc/gcry_dsa.module
+usr/lib/grub/i386-pc/gcry_idea.mod
+usr/lib/grub/i386-pc/gcry_idea.module
+usr/lib/grub/i386-pc/gcry_md4.mod
+usr/lib/grub/i386-pc/gcry_md4.module
+usr/lib/grub/i386-pc/gcry_md5.mod
+usr/lib/grub/i386-pc/gcry_md5.module
+usr/lib/grub/i386-pc/gcry_rfc2268.mod
+usr/lib/grub/i386-pc/gcry_rfc2268.module
+usr/lib/grub/i386-pc/gcry_rijndael.mod
+usr/lib/grub/i386-pc/gcry_rijndael.module
+usr/lib/grub/i386-pc/gcry_rmd160.mod
+usr/lib/grub/i386-pc/gcry_rmd160.module
+usr/lib/grub/i386-pc/gcry_rsa.mod
+usr/lib/grub/i386-pc/gcry_rsa.module
+usr/lib/grub/i386-pc/gcry_seed.mod
+usr/lib/grub/i386-pc/gcry_seed.module
+usr/lib/grub/i386-pc/gcry_serpent.mod
+usr/lib/grub/i386-pc/gcry_serpent.module
+usr/lib/grub/i386-pc/gcry_sha1.mod
+usr/lib/grub/i386-pc/gcry_sha1.module
+usr/lib/grub/i386-pc/gcry_sha256.mod
+usr/lib/grub/i386-pc/gcry_sha256.module
+usr/lib/grub/i386-pc/gcry_sha512.mod
+usr/lib/grub/i386-pc/gcry_sha512.module
+usr/lib/grub/i386-pc/gcry_tiger.mod
+usr/lib/grub/i386-pc/gcry_tiger.module
+usr/lib/grub/i386-pc/gcry_twofish.mod
+usr/lib/grub/i386-pc/gcry_twofish.module
+usr/lib/grub/i386-pc/gcry_whirlpool.mod
+usr/lib/grub/i386-pc/gcry_whirlpool.module
+usr/lib/grub/i386-pc/gdb.mod
+usr/lib/grub/i386-pc/gdb.module
+usr/lib/grub/i386-pc/gdb_grub
+usr/lib/grub/i386-pc/geli.mod
+usr/lib/grub/i386-pc/geli.module
+usr/lib/grub/i386-pc/gettext.mod
+usr/lib/grub/i386-pc/gettext.module
+usr/lib/grub/i386-pc/gfxmenu.mod
+usr/lib/grub/i386-pc/gfxmenu.module
+usr/lib/grub/i386-pc/gfxterm.mod
+usr/lib/grub/i386-pc/gfxterm.module
+usr/lib/grub/i386-pc/gfxterm_background.mod
+usr/lib/grub/i386-pc/gfxterm_background.module
+usr/lib/grub/i386-pc/gfxterm_menu.mod
+usr/lib/grub/i386-pc/gfxterm_menu.module
+usr/lib/grub/i386-pc/gmodule.pl
+usr/lib/grub/i386-pc/gptsync.mod
+usr/lib/grub/i386-pc/gptsync.module
+usr/lib/grub/i386-pc/gzio.mod
+usr/lib/grub/i386-pc/gzio.module
+usr/lib/grub/i386-pc/halt.mod
+usr/lib/grub/i386-pc/halt.module
+usr/lib/grub/i386-pc/hashsum.mod
+usr/lib/grub/i386-pc/hashsum.module
+usr/lib/grub/i386-pc/hdparm.mod
+usr/lib/grub/i386-pc/hdparm.module
+usr/lib/grub/i386-pc/hello.mod
+usr/lib/grub/i386-pc/hello.module
+usr/lib/grub/i386-pc/help.mod
+usr/lib/grub/i386-pc/help.module
+usr/lib/grub/i386-pc/hexdump.mod
+usr/lib/grub/i386-pc/hexdump.module
+usr/lib/grub/i386-pc/hfs.mod
+usr/lib/grub/i386-pc/hfs.module
+usr/lib/grub/i386-pc/hfsplus.mod
+usr/lib/grub/i386-pc/hfsplus.module
+usr/lib/grub/i386-pc/hfspluscomp.mod
+usr/lib/grub/i386-pc/hfspluscomp.module
+usr/lib/grub/i386-pc/http.mod
+usr/lib/grub/i386-pc/http.module
+usr/lib/grub/i386-pc/iorw.mod
+usr/lib/grub/i386-pc/iorw.module
+usr/lib/grub/i386-pc/iso9660.mod
+usr/lib/grub/i386-pc/iso9660.module
+usr/lib/grub/i386-pc/jfs.mod
+usr/lib/grub/i386-pc/jfs.module
+usr/lib/grub/i386-pc/jpeg.mod
+usr/lib/grub/i386-pc/jpeg.module
+usr/lib/grub/i386-pc/kernel.exec
+usr/lib/grub/i386-pc/kernel.img
+usr/lib/grub/i386-pc/keylayouts.mod
+usr/lib/grub/i386-pc/keylayouts.module
+usr/lib/grub/i386-pc/keystatus.mod
+usr/lib/grub/i386-pc/keystatus.module
+usr/lib/grub/i386-pc/ldm.mod
+usr/lib/grub/i386-pc/ldm.module
+usr/lib/grub/i386-pc/legacy_password_test.mod
+usr/lib/grub/i386-pc/legacy_password_test.module
+usr/lib/grub/i386-pc/legacycfg.mod
+usr/lib/grub/i386-pc/legacycfg.module
+usr/lib/grub/i386-pc/linux.mod
+usr/lib/grub/i386-pc/linux.module
+usr/lib/grub/i386-pc/linux16.mod
+usr/lib/grub/i386-pc/linux16.module
+usr/lib/grub/i386-pc/lnxboot.image
+usr/lib/grub/i386-pc/lnxboot.img
+usr/lib/grub/i386-pc/loadenv.mod
+usr/lib/grub/i386-pc/loadenv.module
+usr/lib/grub/i386-pc/loopback.mod
+usr/lib/grub/i386-pc/loopback.module
+usr/lib/grub/i386-pc/ls.mod
+usr/lib/grub/i386-pc/ls.module
+usr/lib/grub/i386-pc/lsacpi.mod
+usr/lib/grub/i386-pc/lsacpi.module
+usr/lib/grub/i386-pc/lsapm.mod
+usr/lib/grub/i386-pc/lsapm.module
+usr/lib/grub/i386-pc/lsmmap.mod
+usr/lib/grub/i386-pc/lsmmap.module
+usr/lib/grub/i386-pc/lspci.mod
+usr/lib/grub/i386-pc/lspci.module
+usr/lib/grub/i386-pc/luks.mod
+usr/lib/grub/i386-pc/luks.module
+usr/lib/grub/i386-pc/lvm.mod
+usr/lib/grub/i386-pc/lvm.module
+usr/lib/grub/i386-pc/lzma_decompress.image
+usr/lib/grub/i386-pc/lzma_decompress.img
+usr/lib/grub/i386-pc/lzopio.mod
+usr/lib/grub/i386-pc/lzopio.module
+usr/lib/grub/i386-pc/macbless.mod
+usr/lib/grub/i386-pc/macbless.module
+usr/lib/grub/i386-pc/macho.mod
+usr/lib/grub/i386-pc/macho.module
+usr/lib/grub/i386-pc/mda_text.mod
+usr/lib/grub/i386-pc/mda_text.module
+usr/lib/grub/i386-pc/mdraid09.mod
+usr/lib/grub/i386-pc/mdraid09.module
+usr/lib/grub/i386-pc/mdraid09_be.mod
+usr/lib/grub/i386-pc/mdraid09_be.module
+usr/lib/grub/i386-pc/mdraid1x.mod
+usr/lib/grub/i386-pc/mdraid1x.module
+usr/lib/grub/i386-pc/memdisk.mod
+usr/lib/grub/i386-pc/memdisk.module
+usr/lib/grub/i386-pc/memrw.mod
+usr/lib/grub/i386-pc/memrw.module
+usr/lib/grub/i386-pc/minicmd.mod
+usr/lib/grub/i386-pc/minicmd.module
+usr/lib/grub/i386-pc/minix.mod
+usr/lib/grub/i386-pc/minix.module
+usr/lib/grub/i386-pc/minix2.mod
+usr/lib/grub/i386-pc/minix2.module
+usr/lib/grub/i386-pc/minix2_be.mod
+usr/lib/grub/i386-pc/minix2_be.module
+usr/lib/grub/i386-pc/minix3.mod
+usr/lib/grub/i386-pc/minix3.module
+usr/lib/grub/i386-pc/minix3_be.mod
+usr/lib/grub/i386-pc/minix3_be.module
+usr/lib/grub/i386-pc/minix_be.mod
+usr/lib/grub/i386-pc/minix_be.module
+usr/lib/grub/i386-pc/mmap.mod
+usr/lib/grub/i386-pc/mmap.module
+usr/lib/grub/i386-pc/moddep.lst
+usr/lib/grub/i386-pc/modinfo.sh
+usr/lib/grub/i386-pc/morse.mod
+usr/lib/grub/i386-pc/morse.module
+usr/lib/grub/i386-pc/mpi.mod
+usr/lib/grub/i386-pc/mpi.module
+usr/lib/grub/i386-pc/msdospart.mod
+usr/lib/grub/i386-pc/msdospart.module
+usr/lib/grub/i386-pc/mul_test.mod
+usr/lib/grub/i386-pc/mul_test.module
+usr/lib/grub/i386-pc/multiboot.mod
+usr/lib/grub/i386-pc/multiboot.module
+usr/lib/grub/i386-pc/multiboot2.mod
+usr/lib/grub/i386-pc/multiboot2.module
+usr/lib/grub/i386-pc/nativedisk.mod
+usr/lib/grub/i386-pc/nativedisk.module
+usr/lib/grub/i386-pc/net.mod
+usr/lib/grub/i386-pc/net.module
+usr/lib/grub/i386-pc/newc.mod
+usr/lib/grub/i386-pc/newc.module
+usr/lib/grub/i386-pc/nilfs2.mod
+usr/lib/grub/i386-pc/nilfs2.module
+usr/lib/grub/i386-pc/normal.mod
+usr/lib/grub/i386-pc/normal.module
+usr/lib/grub/i386-pc/ntfs.mod
+usr/lib/grub/i386-pc/ntfs.module
+usr/lib/grub/i386-pc/ntfscomp.mod
+usr/lib/grub/i386-pc/ntfscomp.module
+usr/lib/grub/i386-pc/ntldr.mod
+usr/lib/grub/i386-pc/ntldr.module
+usr/lib/grub/i386-pc/odc.mod
+usr/lib/grub/i386-pc/odc.module
+usr/lib/grub/i386-pc/offsetio.mod
+usr/lib/grub/i386-pc/offsetio.module
+usr/lib/grub/i386-pc/ohci.mod
+usr/lib/grub/i386-pc/ohci.module
+usr/lib/grub/i386-pc/part_acorn.mod
+usr/lib/grub/i386-pc/part_acorn.module
+usr/lib/grub/i386-pc/part_amiga.mod
+usr/lib/grub/i386-pc/part_amiga.module
+usr/lib/grub/i386-pc/part_apple.mod
+usr/lib/grub/i386-pc/part_apple.module
+usr/lib/grub/i386-pc/part_bsd.mod
+usr/lib/grub/i386-pc/part_bsd.module
+usr/lib/grub/i386-pc/part_dfly.mod
+usr/lib/grub/i386-pc/part_dfly.module
+usr/lib/grub/i386-pc/part_dvh.mod
+usr/lib/grub/i386-pc/part_dvh.module
+usr/lib/grub/i386-pc/part_gpt.mod
+usr/lib/grub/i386-pc/part_gpt.module
+usr/lib/grub/i386-pc/part_msdos.mod
+usr/lib/grub/i386-pc/part_msdos.module
+usr/lib/grub/i386-pc/part_plan.mod
+usr/lib/grub/i386-pc/part_plan.module
+usr/lib/grub/i386-pc/part_sun.mod
+usr/lib/grub/i386-pc/part_sun.module
+usr/lib/grub/i386-pc/part_sunpc.mod
+usr/lib/grub/i386-pc/part_sunpc.module
+usr/lib/grub/i386-pc/partmap.lst
+usr/lib/grub/i386-pc/parttool.lst
+usr/lib/grub/i386-pc/parttool.mod
+usr/lib/grub/i386-pc/parttool.module
+usr/lib/grub/i386-pc/password.mod
+usr/lib/grub/i386-pc/password.module
+usr/lib/grub/i386-pc/password_pbkdf2.mod
+usr/lib/grub/i386-pc/password_pbkdf2.module
+usr/lib/grub/i386-pc/pata.mod
+usr/lib/grub/i386-pc/pata.module
+usr/lib/grub/i386-pc/pbkdf2.mod
+usr/lib/grub/i386-pc/pbkdf2.module
+usr/lib/grub/i386-pc/pbkdf2_test.mod
+usr/lib/grub/i386-pc/pbkdf2_test.module
+usr/lib/grub/i386-pc/pci.mod
+usr/lib/grub/i386-pc/pci.module
+usr/lib/grub/i386-pc/pcidump.mod
+usr/lib/grub/i386-pc/pcidump.module
+usr/lib/grub/i386-pc/pgp.mod
+usr/lib/grub/i386-pc/pgp.module
+usr/lib/grub/i386-pc/plan9.mod
+usr/lib/grub/i386-pc/plan9.module
+usr/lib/grub/i386-pc/play.mod
+usr/lib/grub/i386-pc/play.module
+usr/lib/grub/i386-pc/png.mod
+usr/lib/grub/i386-pc/png.module
+usr/lib/grub/i386-pc/priority_queue.mod
+usr/lib/grub/i386-pc/priority_queue.module
+usr/lib/grub/i386-pc/probe.mod
+usr/lib/grub/i386-pc/probe.module
+usr/lib/grub/i386-pc/procfs.mod
+usr/lib/grub/i386-pc/procfs.module
+usr/lib/grub/i386-pc/progress.mod
+usr/lib/grub/i386-pc/progress.module
+usr/lib/grub/i386-pc/pxe.mod
+usr/lib/grub/i386-pc/pxe.module
+usr/lib/grub/i386-pc/pxeboot.image
+usr/lib/grub/i386-pc/pxeboot.img
+usr/lib/grub/i386-pc/pxechain.mod
+usr/lib/grub/i386-pc/pxechain.module
+usr/lib/grub/i386-pc/raid5rec.mod
+usr/lib/grub/i386-pc/raid5rec.module
+usr/lib/grub/i386-pc/raid6rec.mod
+usr/lib/grub/i386-pc/raid6rec.module
+usr/lib/grub/i386-pc/random.mod
+usr/lib/grub/i386-pc/random.module
+usr/lib/grub/i386-pc/rdmsr.mod
+usr/lib/grub/i386-pc/rdmsr.module
+usr/lib/grub/i386-pc/read.mod
+usr/lib/grub/i386-pc/read.module
+usr/lib/grub/i386-pc/reboot.mod
+usr/lib/grub/i386-pc/reboot.module
+usr/lib/grub/i386-pc/regexp.mod
+usr/lib/grub/i386-pc/regexp.module
+usr/lib/grub/i386-pc/reiserfs.mod
+usr/lib/grub/i386-pc/reiserfs.module
+usr/lib/grub/i386-pc/relocator.mod
+usr/lib/grub/i386-pc/relocator.module
+usr/lib/grub/i386-pc/romfs.mod
+usr/lib/grub/i386-pc/romfs.module
+usr/lib/grub/i386-pc/scsi.mod
+usr/lib/grub/i386-pc/scsi.module
+usr/lib/grub/i386-pc/search.mod
+usr/lib/grub/i386-pc/search.module
+usr/lib/grub/i386-pc/search_fs_file.mod
+usr/lib/grub/i386-pc/search_fs_file.module
+usr/lib/grub/i386-pc/search_fs_uuid.mod
+usr/lib/grub/i386-pc/search_fs_uuid.module
+usr/lib/grub/i386-pc/search_label.mod
+usr/lib/grub/i386-pc/search_label.module
+usr/lib/grub/i386-pc/sendkey.mod
+usr/lib/grub/i386-pc/sendkey.module
+usr/lib/grub/i386-pc/serial.mod
+usr/lib/grub/i386-pc/serial.module
+usr/lib/grub/i386-pc/setjmp.mod
+usr/lib/grub/i386-pc/setjmp.module
+usr/lib/grub/i386-pc/setjmp_test.mod
+usr/lib/grub/i386-pc/setjmp_test.module
+usr/lib/grub/i386-pc/setpci.mod
+usr/lib/grub/i386-pc/setpci.module
+usr/lib/grub/i386-pc/sfs.mod
+usr/lib/grub/i386-pc/sfs.module
+usr/lib/grub/i386-pc/shift_test.mod
+usr/lib/grub/i386-pc/shift_test.module
+usr/lib/grub/i386-pc/signature_test.mod
+usr/lib/grub/i386-pc/signature_test.module
+usr/lib/grub/i386-pc/sleep.mod
+usr/lib/grub/i386-pc/sleep.module
+usr/lib/grub/i386-pc/sleep_test.mod
+usr/lib/grub/i386-pc/sleep_test.module
+usr/lib/grub/i386-pc/spkmodem.mod
+usr/lib/grub/i386-pc/spkmodem.module
+usr/lib/grub/i386-pc/squash4.mod
+usr/lib/grub/i386-pc/squash4.module
+usr/lib/grub/i386-pc/strtoull_test.mod
+usr/lib/grub/i386-pc/strtoull_test.module
+usr/lib/grub/i386-pc/syslinuxcfg.mod
+usr/lib/grub/i386-pc/syslinuxcfg.module
+usr/lib/grub/i386-pc/tar.mod
+usr/lib/grub/i386-pc/tar.module
+usr/lib/grub/i386-pc/terminal.lst
+usr/lib/grub/i386-pc/terminal.mod
+usr/lib/grub/i386-pc/terminal.module
+usr/lib/grub/i386-pc/terminfo.mod
+usr/lib/grub/i386-pc/terminfo.module
+usr/lib/grub/i386-pc/test.mod
+usr/lib/grub/i386-pc/test.module
+usr/lib/grub/i386-pc/test_blockarg.mod
+usr/lib/grub/i386-pc/test_blockarg.module
+usr/lib/grub/i386-pc/testload.mod
+usr/lib/grub/i386-pc/testload.module
+usr/lib/grub/i386-pc/testspeed.mod
+usr/lib/grub/i386-pc/testspeed.module
+usr/lib/grub/i386-pc/tftp.mod
+usr/lib/grub/i386-pc/tftp.module
+usr/lib/grub/i386-pc/tga.mod
+usr/lib/grub/i386-pc/tga.module
+usr/lib/grub/i386-pc/time.mod
+usr/lib/grub/i386-pc/time.module
+usr/lib/grub/i386-pc/tr.mod
+usr/lib/grub/i386-pc/tr.module
+usr/lib/grub/i386-pc/trig.mod
+usr/lib/grub/i386-pc/trig.module
+usr/lib/grub/i386-pc/true.mod
+usr/lib/grub/i386-pc/true.module
+usr/lib/grub/i386-pc/truecrypt.mod
+usr/lib/grub/i386-pc/truecrypt.module
+usr/lib/grub/i386-pc/udf.mod
+usr/lib/grub/i386-pc/udf.module
+usr/lib/grub/i386-pc/ufs1.mod
+usr/lib/grub/i386-pc/ufs1.module
+usr/lib/grub/i386-pc/ufs1_be.mod
+usr/lib/grub/i386-pc/ufs1_be.module
+usr/lib/grub/i386-pc/ufs2.mod
+usr/lib/grub/i386-pc/ufs2.module
+usr/lib/grub/i386-pc/uhci.mod
+usr/lib/grub/i386-pc/uhci.module
+usr/lib/grub/i386-pc/usb.mod
+usr/lib/grub/i386-pc/usb.module
+usr/lib/grub/i386-pc/usb_keyboard.mod
+usr/lib/grub/i386-pc/usb_keyboard.module
+usr/lib/grub/i386-pc/usbms.mod
+usr/lib/grub/i386-pc/usbms.module
+usr/lib/grub/i386-pc/usbserial_common.mod
+usr/lib/grub/i386-pc/usbserial_common.module
+usr/lib/grub/i386-pc/usbserial_ftdi.mod
+usr/lib/grub/i386-pc/usbserial_ftdi.module
+usr/lib/grub/i386-pc/usbserial_pl2303.mod
+usr/lib/grub/i386-pc/usbserial_pl2303.module
+usr/lib/grub/i386-pc/usbserial_usbdebug.mod
+usr/lib/grub/i386-pc/usbserial_usbdebug.module
+usr/lib/grub/i386-pc/usbtest.mod
+usr/lib/grub/i386-pc/usbtest.module
+usr/lib/grub/i386-pc/vbe.mod
+usr/lib/grub/i386-pc/vbe.module
+usr/lib/grub/i386-pc/verifiers.mod
+usr/lib/grub/i386-pc/verifiers.module
+usr/lib/grub/i386-pc/vga.mod
+usr/lib/grub/i386-pc/vga.module
+usr/lib/grub/i386-pc/vga_text.mod
+usr/lib/grub/i386-pc/vga_text.module
+usr/lib/grub/i386-pc/video.lst
+usr/lib/grub/i386-pc/video.mod
+usr/lib/grub/i386-pc/video.module
+usr/lib/grub/i386-pc/video_bochs.mod
+usr/lib/grub/i386-pc/video_bochs.module
+usr/lib/grub/i386-pc/video_cirrus.mod
+usr/lib/grub/i386-pc/video_cirrus.module
+usr/lib/grub/i386-pc/video_colors.mod
+usr/lib/grub/i386-pc/video_colors.module
+usr/lib/grub/i386-pc/video_fb.mod
+usr/lib/grub/i386-pc/video_fb.module
+usr/lib/grub/i386-pc/videoinfo.mod
+usr/lib/grub/i386-pc/videoinfo.module
+usr/lib/grub/i386-pc/videotest.mod
+usr/lib/grub/i386-pc/videotest.module
+usr/lib/grub/i386-pc/videotest_checksum.mod
+usr/lib/grub/i386-pc/videotest_checksum.module
+usr/lib/grub/i386-pc/wrmsr.mod
+usr/lib/grub/i386-pc/wrmsr.module
+usr/lib/grub/i386-pc/xfs.mod
+usr/lib/grub/i386-pc/xfs.module
+usr/lib/grub/i386-pc/xnu.mod
+usr/lib/grub/i386-pc/xnu.module
+usr/lib/grub/i386-pc/xnu_uuid.mod
+usr/lib/grub/i386-pc/xnu_uuid.module
+usr/lib/grub/i386-pc/xnu_uuid_test.mod
+usr/lib/grub/i386-pc/xnu_uuid_test.module
+usr/lib/grub/i386-pc/xzio.mod
+usr/lib/grub/i386-pc/xzio.module
+usr/lib/grub/i386-pc/zfs.mod
+usr/lib/grub/i386-pc/zfs.module
+usr/lib/grub/i386-pc/zfscrypt.mod
+usr/lib/grub/i386-pc/zfscrypt.module
+usr/lib/grub/i386-pc/zfsinfo.mod
+usr/lib/grub/i386-pc/zfsinfo.module
+usr/lib/grub/i386-pc/zstd.mod
+usr/lib/grub/i386-pc/zstd.module
 usr/sbin/grub-bios-setup
 usr/sbin/grub-install
 usr/sbin/grub-macbless
@@ -647,7 +660,9 @@ usr/share/grub/unicode.pf2
 #usr/share/locale/pa/LC_MESSAGES
 #usr/share/locale/pa/LC_MESSAGES/grub.mo
 #usr/share/locale/pl/LC_MESSAGES/grub.mo
+#usr/share/locale/pt/LC_MESSAGES/grub.mo
 #usr/share/locale/pt_BR/LC_MESSAGES/grub.mo
+#usr/share/locale/ro/LC_MESSAGES/grub.mo
 #usr/share/locale/ru/LC_MESSAGES/grub.mo
 #usr/share/locale/sl/LC_MESSAGES/grub.mo
 #usr/share/locale/sr/LC_MESSAGES/grub.mo
index c6fcfc78f8126c8fbbe36c1f25e0bd27547833d6..38c8a9792fbd640a8cd4d79d29ef190606064f80 100644 (file)
@@ -4,7 +4,7 @@ boot/grub/splash.png
 #etc/bash_completion.d
 #etc/bash_completion.d/grub
 etc/default/grub
-etc/grub.d
+#etc/grub.d
 etc/grub.d/00_header
 etc/grub.d/10_linux
 etc/grub.d/20_linux_xen
@@ -30,7 +30,7 @@ usr/bin/grub-render-label
 usr/bin/grub-script-check
 usr/bin/grub-syslinux2cfg
 #usr/lib/grub
-usr/lib/grub/i386-pc
+#usr/lib/grub/i386-pc
 usr/lib/grub/i386-pc/acpi.mod
 usr/lib/grub/i386-pc/acpi.module
 usr/lib/grub/i386-pc/adler32.mod
@@ -162,8 +162,11 @@ usr/lib/grub/i386-pc/ext2.mod
 usr/lib/grub/i386-pc/ext2.module
 usr/lib/grub/i386-pc/extcmd.mod
 usr/lib/grub/i386-pc/extcmd.module
+usr/lib/grub/i386-pc/f2fs.mod
+usr/lib/grub/i386-pc/f2fs.module
 usr/lib/grub/i386-pc/fat.mod
 usr/lib/grub/i386-pc/fat.module
+usr/lib/grub/i386-pc/fdt.lst
 usr/lib/grub/i386-pc/file.mod
 usr/lib/grub/i386-pc/file.module
 usr/lib/grub/i386-pc/font.mod
@@ -415,6 +418,8 @@ usr/lib/grub/i386-pc/pci.mod
 usr/lib/grub/i386-pc/pci.module
 usr/lib/grub/i386-pc/pcidump.mod
 usr/lib/grub/i386-pc/pcidump.module
+usr/lib/grub/i386-pc/pgp.mod
+usr/lib/grub/i386-pc/pgp.module
 usr/lib/grub/i386-pc/plan9.mod
 usr/lib/grub/i386-pc/plan9.module
 usr/lib/grub/i386-pc/play.mod
@@ -441,6 +446,8 @@ usr/lib/grub/i386-pc/raid6rec.mod
 usr/lib/grub/i386-pc/raid6rec.module
 usr/lib/grub/i386-pc/random.mod
 usr/lib/grub/i386-pc/random.module
+usr/lib/grub/i386-pc/rdmsr.mod
+usr/lib/grub/i386-pc/rdmsr.module
 usr/lib/grub/i386-pc/read.mod
 usr/lib/grub/i386-pc/read.module
 usr/lib/grub/i386-pc/reboot.mod
@@ -487,6 +494,8 @@ usr/lib/grub/i386-pc/spkmodem.mod
 usr/lib/grub/i386-pc/spkmodem.module
 usr/lib/grub/i386-pc/squash4.mod
 usr/lib/grub/i386-pc/squash4.module
+usr/lib/grub/i386-pc/strtoull_test.mod
+usr/lib/grub/i386-pc/strtoull_test.module
 usr/lib/grub/i386-pc/syslinuxcfg.mod
 usr/lib/grub/i386-pc/syslinuxcfg.module
 usr/lib/grub/i386-pc/tar.mod
@@ -546,8 +555,8 @@ usr/lib/grub/i386-pc/usbtest.mod
 usr/lib/grub/i386-pc/usbtest.module
 usr/lib/grub/i386-pc/vbe.mod
 usr/lib/grub/i386-pc/vbe.module
-usr/lib/grub/i386-pc/verify.mod
-usr/lib/grub/i386-pc/verify.module
+usr/lib/grub/i386-pc/verifiers.mod
+usr/lib/grub/i386-pc/verifiers.module
 usr/lib/grub/i386-pc/vga.mod
 usr/lib/grub/i386-pc/vga.module
 usr/lib/grub/i386-pc/vga_text.mod
@@ -569,6 +578,8 @@ usr/lib/grub/i386-pc/videotest.mod
 usr/lib/grub/i386-pc/videotest.module
 usr/lib/grub/i386-pc/videotest_checksum.mod
 usr/lib/grub/i386-pc/videotest_checksum.module
+usr/lib/grub/i386-pc/wrmsr.mod
+usr/lib/grub/i386-pc/wrmsr.module
 usr/lib/grub/i386-pc/xfs.mod
 usr/lib/grub/i386-pc/xfs.module
 usr/lib/grub/i386-pc/xnu.mod
@@ -585,7 +596,9 @@ usr/lib/grub/i386-pc/zfscrypt.mod
 usr/lib/grub/i386-pc/zfscrypt.module
 usr/lib/grub/i386-pc/zfsinfo.mod
 usr/lib/grub/i386-pc/zfsinfo.module
-usr/lib/grub/x86_64-efi
+usr/lib/grub/i386-pc/zstd.mod
+usr/lib/grub/i386-pc/zstd.module
+#usr/lib/grub/x86_64-efi
 usr/lib/grub/x86_64-efi/acpi.mod
 usr/lib/grub/x86_64-efi/acpi.module
 usr/lib/grub/x86_64-efi/adler32.mod
@@ -709,8 +722,11 @@ usr/lib/grub/x86_64-efi/ext2.mod
 usr/lib/grub/x86_64-efi/ext2.module
 usr/lib/grub/x86_64-efi/extcmd.mod
 usr/lib/grub/x86_64-efi/extcmd.module
+usr/lib/grub/x86_64-efi/f2fs.mod
+usr/lib/grub/x86_64-efi/f2fs.module
 usr/lib/grub/x86_64-efi/fat.mod
 usr/lib/grub/x86_64-efi/fat.module
+usr/lib/grub/x86_64-efi/fdt.lst
 usr/lib/grub/x86_64-efi/file.mod
 usr/lib/grub/x86_64-efi/file.module
 usr/lib/grub/x86_64-efi/fixvideo.mod
@@ -958,6 +974,8 @@ usr/lib/grub/x86_64-efi/pbkdf2_test.mod
 usr/lib/grub/x86_64-efi/pbkdf2_test.module
 usr/lib/grub/x86_64-efi/pcidump.mod
 usr/lib/grub/x86_64-efi/pcidump.module
+usr/lib/grub/x86_64-efi/pgp.mod
+usr/lib/grub/x86_64-efi/pgp.module
 usr/lib/grub/x86_64-efi/play.mod
 usr/lib/grub/x86_64-efi/play.module
 usr/lib/grub/x86_64-efi/png.mod
@@ -976,6 +994,8 @@ usr/lib/grub/x86_64-efi/raid6rec.mod
 usr/lib/grub/x86_64-efi/raid6rec.module
 usr/lib/grub/x86_64-efi/random.mod
 usr/lib/grub/x86_64-efi/random.module
+usr/lib/grub/x86_64-efi/rdmsr.mod
+usr/lib/grub/x86_64-efi/rdmsr.module
 usr/lib/grub/x86_64-efi/read.mod
 usr/lib/grub/x86_64-efi/read.module
 usr/lib/grub/x86_64-efi/reboot.mod
@@ -1010,6 +1030,8 @@ usr/lib/grub/x86_64-efi/sfs.mod
 usr/lib/grub/x86_64-efi/sfs.module
 usr/lib/grub/x86_64-efi/shift_test.mod
 usr/lib/grub/x86_64-efi/shift_test.module
+usr/lib/grub/x86_64-efi/shim_lock.mod
+usr/lib/grub/x86_64-efi/shim_lock.module
 usr/lib/grub/x86_64-efi/signature_test.mod
 usr/lib/grub/x86_64-efi/signature_test.module
 usr/lib/grub/x86_64-efi/sleep.mod
@@ -1020,6 +1042,8 @@ usr/lib/grub/x86_64-efi/spkmodem.mod
 usr/lib/grub/x86_64-efi/spkmodem.module
 usr/lib/grub/x86_64-efi/squash4.mod
 usr/lib/grub/x86_64-efi/squash4.module
+usr/lib/grub/x86_64-efi/strtoull_test.mod
+usr/lib/grub/x86_64-efi/strtoull_test.module
 usr/lib/grub/x86_64-efi/syslinuxcfg.mod
 usr/lib/grub/x86_64-efi/syslinuxcfg.module
 usr/lib/grub/x86_64-efi/tar.mod
@@ -1043,6 +1067,8 @@ usr/lib/grub/x86_64-efi/tga.mod
 usr/lib/grub/x86_64-efi/tga.module
 usr/lib/grub/x86_64-efi/time.mod
 usr/lib/grub/x86_64-efi/time.module
+usr/lib/grub/x86_64-efi/tpm.mod
+usr/lib/grub/x86_64-efi/tpm.module
 usr/lib/grub/x86_64-efi/tr.mod
 usr/lib/grub/x86_64-efi/tr.module
 usr/lib/grub/x86_64-efi/trig.mod
@@ -1075,8 +1101,8 @@ usr/lib/grub/x86_64-efi/usbserial_usbdebug.mod
 usr/lib/grub/x86_64-efi/usbserial_usbdebug.module
 usr/lib/grub/x86_64-efi/usbtest.mod
 usr/lib/grub/x86_64-efi/usbtest.module
-usr/lib/grub/x86_64-efi/verify.mod
-usr/lib/grub/x86_64-efi/verify.module
+usr/lib/grub/x86_64-efi/verifiers.mod
+usr/lib/grub/x86_64-efi/verifiers.module
 usr/lib/grub/x86_64-efi/video.lst
 usr/lib/grub/x86_64-efi/video.mod
 usr/lib/grub/x86_64-efi/video.module
@@ -1094,6 +1120,8 @@ usr/lib/grub/x86_64-efi/videotest.mod
 usr/lib/grub/x86_64-efi/videotest.module
 usr/lib/grub/x86_64-efi/videotest_checksum.mod
 usr/lib/grub/x86_64-efi/videotest_checksum.module
+usr/lib/grub/x86_64-efi/wrmsr.mod
+usr/lib/grub/x86_64-efi/wrmsr.module
 usr/lib/grub/x86_64-efi/xfs.mod
 usr/lib/grub/x86_64-efi/xfs.module
 usr/lib/grub/x86_64-efi/xnu.mod
@@ -1110,6 +1138,8 @@ usr/lib/grub/x86_64-efi/zfscrypt.mod
 usr/lib/grub/x86_64-efi/zfscrypt.module
 usr/lib/grub/x86_64-efi/zfsinfo.mod
 usr/lib/grub/x86_64-efi/zfsinfo.module
+usr/lib/grub/x86_64-efi/zstd.mod
+usr/lib/grub/x86_64-efi/zstd.module
 usr/sbin/grub-bios-setup
 usr/sbin/grub-install
 usr/sbin/grub-macbless
@@ -1172,7 +1202,9 @@ usr/share/grub/unicode.pf2
 #usr/share/locale/pa/LC_MESSAGES
 #usr/share/locale/pa/LC_MESSAGES/grub.mo
 #usr/share/locale/pl/LC_MESSAGES/grub.mo
+#usr/share/locale/pt/LC_MESSAGES/grub.mo
 #usr/share/locale/pt_BR/LC_MESSAGES/grub.mo
+#usr/share/locale/ro/LC_MESSAGES/grub.mo
 #usr/share/locale/ru/LC_MESSAGES/grub.mo
 #usr/share/locale/sl/LC_MESSAGES/grub.mo
 #usr/share/locale/sr/LC_MESSAGES/grub.mo
index 67a9e1002ea4630258613f3d4de205ce0de98138..ac6de68a4c4efa5c0d87c63b470d71c5a86f3ddd 100644 (file)
--- a/lfs/grub
+++ b/lfs/grub
@@ -1,7 +1,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2007-2018  IPFire Team  <info@ipfire.org>                     #
+# Copyright (C) 2007-2020  IPFire Team  <info@ipfire.org>                     #
 #                                                                             #
 # This program is free software: you can redistribute it and/or modify        #
 # it under the terms of the GNU General Public License as published by        #
@@ -24,7 +24,7 @@
 
 include Config
 
-VER        = 2.02
+VER        = 2.04
 
 THISAPP    = grub-$(VER)
 DL_FILE    = $(THISAPP).tar.xz
@@ -66,7 +66,7 @@ objects = $(DL_FILE) \
 $(DL_FILE) = $(DL_FROM)/$(DL_FILE)
 unifont-7.0.03.pcf.gz = $(DL_FROM)/unifont-7.0.03.pcf.gz
 
-$(DL_FILE)_MD5 = 8a4a2a95aac551fb0fba860ceabfa1d3
+$(DL_FILE)_MD5 = 5aaca6713b47ca2456d8324a58755ac7
 unifont-7.0.03.pcf.gz_MD5 = f6903ac8c1caeeb30c1e9a2975028401
 
 install : $(TARGET)
@@ -98,10 +98,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @$(PREBUILD)
        @rm -rf $(DIR_APP) $(DIR_APP_EFI) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
 
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grub/grub-2.04-BootHole.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grub-2.02_disable_vga_fallback.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grub-2.02-xfs-accept-filesystem-with-sparse-inodes.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grub-2.02-fix-packed-not-aligned-error-on-gcc-8.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grub-2.02-X86_64_PLT32.patch
 
        # Install unifont
        cp -v $(DIR_DL)/unifont-7.0.03.pcf.gz $(DIR_APP)/unifont.pcf.gz
diff --git a/src/patches/grub-2.02-X86_64_PLT32.patch b/src/patches/grub-2.02-X86_64_PLT32.patch
deleted file mode 100644 (file)
index 2c65cb7..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-From 02702bdfe14d8a04643a45b03715f734ae34dbac Mon Sep 17 00:00:00 2001
-From: "H.J. Lu" <hjl.tools@gmail.com>
-Date: Sat, 17 Feb 2018 06:47:28 -0800
-Subject: x86-64: Treat R_X86_64_PLT32 as R_X86_64_PC32
-
-Starting from binutils commit bd7ab16b4537788ad53521c45469a1bdae84ad4a:
-
-https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=bd7ab16b4537788ad53521c45469a1bdae84ad4a
-
-x86-64 assembler generates R_X86_64_PLT32, instead of R_X86_64_PC32, for
-32-bit PC-relative branches.  Grub2 should treat R_X86_64_PLT32 as
-R_X86_64_PC32.
-
-Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-
-Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=842c390469e2c2e10b5aa36700324cd3bde25875
-Last-Update: 2018-07-30
-
-Patch-Name: R_X86_64_PLT32.patch
----
- grub-core/efiemu/i386/loadcore64.c | 1 +
- grub-core/kern/x86_64/dl.c         | 1 +
- util/grub-mkimagexx.c              | 1 +
- util/grub-module-verifier.c        | 1 +
- 4 files changed, 4 insertions(+)
-
-diff --git a/grub-core/efiemu/i386/loadcore64.c b/grub-core/efiemu/i386/loadcore64.c
-index e49d0b6ff..18facf47f 100644
---- a/grub-core/efiemu/i386/loadcore64.c
-+++ b/grub-core/efiemu/i386/loadcore64.c
-@@ -98,6 +98,7 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
-                   break;
-                 case R_X86_64_PC32:
-+                case R_X86_64_PLT32:
-                   err = grub_efiemu_write_value (addr,
-                                                  *addr32 + rel->r_addend
-                                                  + sym.off
-diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
-index 440690673..3a73e6e6c 100644
---- a/grub-core/kern/x86_64/dl.c
-+++ b/grub-core/kern/x86_64/dl.c
-@@ -70,6 +70,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
-         break;
-       case R_X86_64_PC32:
-+      case R_X86_64_PLT32:
-         {
-           grub_int64_t value;
-           value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
-diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
-index e63f148e4..f20255a28 100644
---- a/util/grub-mkimagexx.c
-+++ b/util/grub-mkimagexx.c
-@@ -832,6 +832,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
-                 break;
-               case R_X86_64_PC32:
-+              case R_X86_64_PLT32:
-                 {
-                   grub_uint32_t *t32 = (grub_uint32_t *) target;
-                   *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
-diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
-index 9179285a5..a79271f66 100644
---- a/util/grub-module-verifier.c
-+++ b/util/grub-module-verifier.c
-@@ -19,6 +19,7 @@ struct grub_module_verifier_arch archs[] = {
-       -1
-     }, (int[]){
-       R_X86_64_PC32,
-+      R_X86_64_PLT32,
-       -1
-     }
-   },
diff --git a/src/patches/grub-2.02-fix-packed-not-aligned-error-on-gcc-8.patch b/src/patches/grub-2.02-fix-packed-not-aligned-error-on-gcc-8.patch
deleted file mode 100644 (file)
index 51ee7dc..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From 563b1da6e6ae7af46cc8354cadb5dab416989f0a Mon Sep 17 00:00:00 2001
-From: Michael Chang <mchang@suse.com>
-Date: Mon, 26 Mar 2018 16:52:34 +0800
-Subject: Fix packed-not-aligned error on GCC 8
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When building with GCC 8, there are several errors regarding packed-not-aligned.
-
-./include/grub/gpt_partition.h:79:1: error: alignment 1 of â€˜struct grub_gpt_partentry’ is less than 8 [-Werror=packed-not-aligned]
-
-This patch fixes the build error by cleaning up the ambiguity of placing
-aligned structure in a packed one. In "struct grub_btrfs_time" and "struct
-grub_gpt_part_type", the aligned attribute seems to be superfluous, and also
-has to be packed, to ensure the structure is bit-to-bit mapped to the format
-laid on disk. I think we could blame to copy and paste error here for the
-mistake. In "struct efi_variable", we have to use grub_efi_packed_guid_t, as
-the name suggests. :)
-
-Signed-off-by: Michael Chang <mchang@suse.com>
-Tested-by: Michael Chang <mchang@suse.com>
-Tested-by: Paul Menzel <paulepanter@users.sourceforge.net>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
----
- grub-core/fs/btrfs.c          | 2 +-
- include/grub/efiemu/runtime.h | 2 +-
- include/grub/gpt_partition.h  | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
-index 4849c1c..be19544 100644
---- a/grub-core/fs/btrfs.c
-+++ b/grub-core/fs/btrfs.c
-@@ -175,7 +175,7 @@ struct grub_btrfs_time
- {
-   grub_int64_t sec;
-   grub_uint32_t nanosec;
--} __attribute__ ((aligned (4)));
-+} GRUB_PACKED;
- struct grub_btrfs_inode
- {
-diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h
-index 9b6b729..36d2ded 100644
---- a/include/grub/efiemu/runtime.h
-+++ b/include/grub/efiemu/runtime.h
-@@ -29,7 +29,7 @@ struct grub_efiemu_ptv_rel
- struct efi_variable
- {
--  grub_efi_guid_t guid;
-+  grub_efi_packed_guid_t guid;
-   grub_uint32_t namelen;
-   grub_uint32_t size;
-   grub_efi_uint32_t attributes;
-diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
-index 1b32f67..9668a68 100644
---- a/include/grub/gpt_partition.h
-+++ b/include/grub/gpt_partition.h
-@@ -28,7 +28,7 @@ struct grub_gpt_part_type
-   grub_uint16_t data2;
-   grub_uint16_t data3;
-   grub_uint8_t data4[8];
--} __attribute__ ((aligned(8)));
-+} GRUB_PACKED;
- typedef struct grub_gpt_part_type grub_gpt_part_type_t;
- #define GRUB_GPT_PARTITION_TYPE_EMPTY \
--- 
-cgit v1.0-41-gc330
-
diff --git a/src/patches/grub-2.02-xfs-accept-filesystem-with-sparse-inodes.patch b/src/patches/grub-2.02-xfs-accept-filesystem-with-sparse-inodes.patch
deleted file mode 100644 (file)
index 6c6a750..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From cda0a857dd7a27cd5d621747464bfe71e8727fff Mon Sep 17 00:00:00 2001
-From: Daniel Kiper <daniel.kiper@oracle.com>
-Date: Tue, 29 May 2018 16:16:02 +0200
-Subject: xfs: Accept filesystem with sparse inodes
-
-The sparse inode metadata format became a mkfs.xfs default in
-xfsprogs-4.16.0, and such filesystems are now rejected by grub as
-containing an incompatible feature.
-
-In essence, this feature allows xfs to allocate inodes into fragmented
-freespace.  (Without this feature, if xfs could not allocate contiguous
-space for 64 new inodes, inode creation would fail.)
-
-In practice, the disk format change is restricted to the inode btree,
-which as far as I can tell is not used by grub.  If all you're doing
-today is parsing a directory, reading an inode number, and converting
-that inode number to a disk location, then ignoring this feature
-should be fine, so I've added it to XFS_SB_FEAT_INCOMPAT_SUPPORTED
-
-I did some brief testing of this patch by hacking up the regression
-tests to completely fragment freespace on the test xfs filesystem, and
-then write a large-ish number of inodes to consume any existing
-contiguous 64-inode chunk.  This way any files the grub tests add and
-traverse would be in such a fragmented inode allocation.  Tests passed,
-but I'm not sure how to cleanly integrate that into the test harness.
-
-Signed-off-by: Eric Sandeen <sandeen@redhat.com>
-Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
-Tested-by: Chris Murphy <lists@colorremedies.com>
----
- grub-core/fs/xfs.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
-index c6031bd..3b00c74 100644
---- a/grub-core/fs/xfs.c
-+++ b/grub-core/fs/xfs.c
-@@ -79,9 +79,18 @@ GRUB_MOD_LICENSE ("GPLv3+");
- #define XFS_SB_FEAT_INCOMPAT_SPINODES   (1 << 1)        /* sparse inode chunks */
- #define XFS_SB_FEAT_INCOMPAT_META_UUID  (1 << 2)        /* metadata UUID */
--/* We do not currently verify metadata UUID so it is safe to read such filesystem */
-+/*
-+ * Directory entries with ftype are explicitly handled by GRUB code.
-+ *
-+ * We do not currently read the inode btrees, so it is safe to read filesystems
-+ * with the XFS_SB_FEAT_INCOMPAT_SPINODES feature.
-+ *
-+ * We do not currently verify metadata UUID, so it is safe to read filesystems
-+ * with the XFS_SB_FEAT_INCOMPAT_META_UUID feature.
-+ */
- #define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
-       (XFS_SB_FEAT_INCOMPAT_FTYPE | \
-+       XFS_SB_FEAT_INCOMPAT_SPINODES | \
-        XFS_SB_FEAT_INCOMPAT_META_UUID)
- struct grub_xfs_sblock
--- 
-cgit v1.0-41-gc330
-
diff --git a/src/patches/grub/grub-2.04-BootHole.patch b/src/patches/grub/grub-2.04-BootHole.patch
new file mode 100644 (file)
index 0000000..a63093b
--- /dev/null
@@ -0,0 +1,5936 @@
+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,
+