Add integ/grub for Trixie

Added packaging support for Trixie under 'debian/trixie/'.

This change brings updates from the 'f/trixie' branch into 'master' to
ensure consistent functionality and packaging structure across both
branches.

grub-efi
grub2
grubby

Story: 2011360
Task: 53245

Change-Id: I596d3af4d23d7e669b72e8a359cc89ee847d1de2
Signed-off-by: pmp1 <preetham.mp@windriver.com>
Signed-off-by: Abhinav Ayyapasetti <ayyapasetti.abhinav@windriver.com>
This commit is contained in:
pmp1
2025-11-19 00:28:34 -05:00
committed by Abhinav Ayyapasetti
parent 7cfa3de2bb
commit 1dfcde98b1
97 changed files with 8155 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
From 8f26fc39497decab3f9a087d18803447a9b9295f Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Wed, 31 Aug 2022 13:53:19 +0800
Subject: [PATCH 1/2] Make series null
Clean the patches from debian release to get a clean grub source.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/patches/series | 61 -------------------------------------------
1 file changed, 61 deletions(-)
diff --git a/debian/patches/series b/debian/patches/series
index 748318a..e69de29 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,61 +0,0 @@
-olpc-prefix-hack.patch
-core-in-fs.patch
-dpkg-version-comparison.patch
-grub-legacy-0-based-partitions.patch
-disable-floppies.patch
-grub.cfg-400.patch
-gfxpayload-keep-default.patch
-install-stage2-confusion.patch
-mkrescue-efi-modules.patch
-mkconfig-loopback.patch
-restore-mkdevicemap.patch
-gettext-quiet.patch
-install-efi-fallback.patch
-mkconfig-ubuntu-recovery.patch
-install-locale-langpack.patch
-mkconfig-nonexistent-loopback.patch
-default-grub-d.patch
-blacklist-1440x900x32.patch
-mkconfig-ubuntu-distributor.patch
-linuxefi.patch
-mkconfig-signed-kernel.patch
-install-signed.patch
-wubi-no-windows.patch
-maybe-quiet.patch
-install-efi-adjust-distributor.patch
-quick-boot.patch
-quick-boot-lvm.patch
-gfxpayload-dynamic.patch
-vt-handoff.patch
-probe-fusionio.patch
-ignore-grub_func_test-failures.patch
-mkconfig-recovery-title.patch
-install-powerpc-machtypes.patch
-ieee1275-clear-reset.patch
-ppc64el-disable-vsx.patch
-grub-install-pvxen-paths.patch
-insmod-xzio-and-lzopio-on-xen.patch
-grub-install-extra-removable.patch
-mkconfig-other-inits.patch
-zpool-full-device-name.patch
-net-read-bracketed-ipv6-addr.patch
-bootp-new-net_bootp6-command.patch
-efinet-uefi-ipv6-pxe-support.patch
-bootp-process-dhcpack-http-boot.patch
-efinet-set-network-from-uefi-devpath.patch
-efinet-set-dns-from-uefi-proto.patch
-fix-lockdown.patch
-skip-grub_cmd_set_date.patch
-bash-completion-drop-have-checks.patch
-at_keyboard-module-init.patch
-uefi-secure-boot-cryptomount.patch
-efi-variable-storage-minimise-writes.patch
-grub-install-removable-shim.patch
-dejavu-font-path.patch
-xen-no-xsm-policy-in-non-xsm-options.patch
-pc-verifiers-module.patch
-debug_verifiers.patch
-mkimage-fix-section-sizes.patch
-tpm-unknown-error-non-fatal.patch
-xfs-fix-v4-superblock.patch
-tests-ahci-update-qemu-device-name.patch
--
2.17.1

View File

@@ -0,0 +1,760 @@
From a26ab5dfcde0a92011bb5422e745d92d79ba4630 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Thu, 15 Sep 2022 09:55:13 +0800
Subject: [PATCH 2/2] grub-efi: build packages related with grub-efi
Grub-efi is ported from layers meta-lat\meta-secure-core of yocto,
so that it can be compiled out of lat.
What are done for this purpose:
(1) Build grub-efi using debian grub2 source code.
Change the source name "grub2" to "grub-efi" to set up grub-efi recipe;
Remove all the packages in control file except those related to
grub-efi.
(2) Remove any build about grub-pc because it is used for the
traditional PC/BIOS and some patches for secure boot can cause failure
when building grub-pc;
(3) Patches for secure boot can cause warnings for ia32 platform, so
remove it because ia32 isn't in use here;
(4) Those unmet dependencies happen because we separate grub-efi's
build from grub2:
[
The following packages have unmet dependencies:
grub-efi-amd64 :
Depends: grub2-common (= 2.06-1.stx.27) but 2.06-1.stx.6 is to be
installed
Conflicts: grub-pc but 2.06-1.stx.6 is to be installed
grub-efi-amd64-bin :
Depends: grub-common (= 2.06-1.stx.27) but 2.06-1.stx.6 is to be
installed
]
Remove grub-efi-amd64's conflict with grub-pc to make them install
to rootfs together;
Remove the limit that grub-efi-amd64(-bin) and grub2-common should
be compiled from the same module.
(5) Create and install customized images according to yocto layers.
Remove linuxefi because it belongs to debian specific patches, which
have been removed;
Customize files under /boot/efi/EFI/BOOT for package grub-efi-amd64.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/build-efi-images | 1 -
debian/changelog | 2 +-
debian/control | 520 +---------------------------------------
debian/rules | 58 +++--
4 files changed, 51 insertions(+), 530 deletions(-)
diff --git a/debian/build-efi-images b/debian/build-efi-images
index 5ac6676..1c5df95 100755
--- a/debian/build-efi-images
+++ b/debian/build-efi-images
@@ -148,7 +148,6 @@ case $platform in
x86_64-efi|i386-efi)
CD_MODULES="$CD_MODULES
cpuid
- linuxefi
play
tpm
"
diff --git a/debian/changelog b/debian/changelog
index 519a692..1663a8a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-grub2 (2.06-1) unstable; urgency=medium
+grub-efi (2.06-1) unstable; urgency=medium
* Use "command -v" in maintainer scripts rather than "which".
* New upstream release.
diff --git a/debian/control b/debian/control
index 591394f..caea0c3 100644
--- a/debian/control
+++ b/debian/control
@@ -1,4 +1,4 @@
-Source: grub2
+Source: grub-efi
Section: admin
Priority: optional
Maintainer: GRUB Maintainers <pkg-grub-devel@alioth-lists.debian.net>
@@ -41,274 +41,18 @@ Vcs-Git: https://salsa.debian.org/grub-team/grub.git
Vcs-Browser: https://salsa.debian.org/grub-team/grub
Rules-Requires-Root: no
-Package: grub2
-Section: oldlibs
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: grub-pc (= ${binary:Version}) [any-i386 any-amd64] | grub-ieee1275 (= ${binary:Version}) [any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64], ${misc:Depends}
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (dummy package)
- This is a dummy transitional package to handle GRUB 2 upgrades. It can be
- safely removed.
-
-Package: grub-linuxbios
-Section: oldlibs
-Architecture: any-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: grub-coreboot (= ${binary:Version}), ${misc:Depends}
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (dummy package)
- This is a dummy transitional package that depends on grub-coreboot.
-
Package: grub-efi
Architecture: any-i386 any-amd64 any-arm64 any-ia64 any-arm
Pre-Depends: ${misc:Pre-Depends}
-Depends: ${misc:Depends}, grub-efi-ia32 (= ${binary:Version}) [any-i386], grub-efi-amd64 (= ${binary:Version}) [any-amd64], grub-efi-arm64 (= ${binary:Version}) [any-arm64], grub-efi-ia64 (= ${binary:Version}) [any-ia64], grub-efi-arm (= ${binary:Version}) [any-arm]
+Depends: ${misc:Depends}, grub-efi-amd64 (= ${binary:Version}) [any-amd64], grub-efi-arm64 (= ${binary:Version}) [any-arm64], grub-efi-ia64 (= ${binary:Version}) [any-ia64], grub-efi-arm (= ${binary:Version}) [any-arm]
Multi-Arch: foreign
Description: GRand Unified Bootloader, version 2 (dummy package)
This is a dummy package that depends on the grub-efi-$ARCH package most likely
to be appropriate for each architecture.
-Package: grub-common
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, gettext-base, ${lsb-base-depends}
-Replaces: grub-pc (<< 2.00-4), grub-ieee1275 (<< 2.00-4), grub-efi (<< 1.99-1), grub-coreboot (<< 2.00-4), grub-linuxbios (<< 1.96+20080831-1), grub-efi-ia32 (<< 2.00-4), grub-efi-amd64 (<< 2.00-4), grub-efi-ia64 (<< 2.00-4), grub-yeeloong (<< 2.00-4), init-select
-Recommends: os-prober (>= 1.33)
-Suggests: multiboot-doc, grub-emu [any-i386 any-amd64 any-powerpc], mtools [any-i386 any-amd64 any-ia64 any-arm any-arm64], xorriso (>= 0.5.6.pl00), desktop-base (>= 4.0.6), console-setup
-Conflicts: init-select
-# mdadm: See bugs #435983 and #455746
-Breaks: mdadm (<< 2.6.7-2), lupin-support (<< 0.55), friendly-recovery (<< 0.2.13), apport (<< 2.1.1)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader (common files)
- This package contains common files shared by the distinct flavours of GRUB.
- It is shared between GRUB Legacy and GRUB 2, although a number of files
- specific to GRUB 2 are here as long as they do not break GRUB Legacy.
- .
- grub-mkrescue needs the suggested packages mtools (for UEFI targets) and
- xorriso.
-
-Package: grub2-common
-# Not Architecture: any because this package contains some things which are
-# only built when there is a real platform (e.g. grub-install), and the rest
-# of the package is not very useful in a utilities-only build.
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64
-Depends: grub-common (= ${binary:Version}), dpkg (>= 1.15.4) | install-info, ${shlibs:Depends}, ${misc:Depends}
-Replaces: grub, grub-legacy, ${legacy-doc-br}, grub-common (<< 1.99-1), grub-pc (<< 2.02+dfsg1-7), grub-coreboot (<< 2.02+dfsg1-7), grub-efi-ia32 (<< 2.02+dfsg1-7), grub-efi-amd64 (<< 2.02+dfsg1-7), grub-efi-ia64 (<< 2.02+dfsg1-7), grub-efi-arm (<< 2.02+dfsg1-7), grub-efi-arm64 (<< 2.02+dfsg1-7), grub-ieee1275 (<< 2.02+dfsg1-7), grub-uboot (<< 2.02+dfsg1-7), grub-xen (<< 2.02+dfsg1-7), grub-yeeloong (<< 2.02+dfsg1-7), grub-cloud-amd64 (<< 0.0.4)
-Conflicts: grub-legacy
-Breaks: grub (<< 0.97-54), ${legacy-doc-br}, shim (<< 0.9+1474479173.6c180c6-0ubuntu1~), grub-pc (<< 2.02+dfsg1-7), grub-coreboot (<< 2.02+dfsg1-7), grub-efi-ia32 (<< 2.02+dfsg1-7), grub-efi-amd64 (<< 2.02+dfsg1-7), grub-efi-ia64 (<< 2.02+dfsg1-7), grub-efi-arm (<< 2.02+dfsg1-7), grub-efi-arm64 (<< 2.02+dfsg1-7), grub-ieee1275 (<< 2.02+dfsg1-7), grub-uboot (<< 2.02+dfsg1-7), grub-xen (<< 2.02+dfsg1-7), grub-yeeloong (<< 2.02+dfsg1-7), grub-cloud-amd64 (<< 0.0.4)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader (common files for version 2)
- This package contains common files shared by the distinct flavours of GRUB.
- The files in this package are specific to GRUB 2, and would break GRUB
- Legacy if installed on the same system.
-
-Package: grub-emu
-Architecture: any-i386 any-amd64 any-powerpc
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Replaces: grub-common (<= 1.97~beta3-1)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (emulated version)
- This package contains grub-emu, an emulated version of GRUB. It is only
- provided for debugging purposes.
-
-Package: grub-emu-dbg
-Section: debug
-Architecture: any-i386 any-amd64 any-powerpc
-Depends: ${misc:Depends}, grub-emu (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (emulated debug files)
- This package contains debugging files for grub-emu. You only need these if
- you are trying to debug GRUB using its GDB stub.
-
-Package: grub-pc-bin
-Architecture: any-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc (<< 1.99-1)
-Suggests: desktop-base (>= 4.0.6)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (PC/BIOS modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- - VESA-based graphical mode with background image support and complete 24-bit
- color set.
- - Support for extended charsets. Users can write UTF-8 text to their menu
- entries.
- .
- This package contains GRUB modules that have been built for use with the
- traditional PC/BIOS architecture. It can be installed in parallel with
- other flavours, but will not automatically install GRUB as the active boot
- loader nor automatically update grub.cfg on upgrade unless grub-pc is also
- installed.
-
-Package: grub-pc-dbg
-Section: debug
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}, grub-pc-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (PC/BIOS debug files)
- This package contains debugging files for grub-pc-bin. You only need these
- if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-pc
-Architecture: any-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-pc-bin (= ${binary:Version}), ucf, freebsd-utils (>= 8.0-4) [kfreebsd-any], ${gfxpayload-depends}
-Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-xen
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (PC/BIOS version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- - VESA-based graphical mode with background image support and complete 24-bit
- color set.
- - Support for extended charsets. Users can write UTF-8 text to their menu
- entries.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the traditional PC/BIOS architecture. Installing this package
- indicates that this version of GRUB should be the active boot loader.
-
-Package: grub-rescue-pc
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}
-Multi-Arch: foreign
-Description: GRUB bootable rescue images, version 2 (PC/BIOS version)
- This package contains three GRUB rescue images that have been built for use
- with the traditional PC/BIOS architecture:
- .
- - grub-rescue-floppy.img: floppy image.
- - grub-rescue-cdrom.iso: El Torito CDROM image.
- - grub-rescue-usb.img: USB image.
-
-Package: grub-coreboot-bin
-Architecture: any-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-linuxbios, grub-coreboot (<< 1.99-1)
-Conflicts: grub-linuxbios (<< ${source:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Coreboot modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with
- platforms running the Coreboot firmware. It can be installed in parallel
- with other flavours, but will not automatically install GRUB as the active
- boot loader nor automatically update grub.cfg on upgrade unless
- grub-coreboot is also installed.
-
-Package: grub-coreboot-dbg
-Section: debug
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}, grub-coreboot-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Coreboot debug files)
- This package contains debugging files for grub-coreboot-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-coreboot
-Architecture: any-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-coreboot-bin (= ${binary:Version}), ucf
-Replaces: grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-linuxbios, grub-efi-amd64, grub-efi-ia32, grub-pc, grub-ieee1275
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-linuxbios (<< ${source:Version}), grub-efi-amd64, grub-efi-ia32, grub-pc, grub-ieee1275, grub-xen
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Coreboot version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with platforms running the Coreboot firmware. Installing this package
- indicates that this version of GRUB should be the active boot loader.
-
-Package: grub-efi-ia32-bin
-Architecture: any-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Recommends: grub-efi-ia32-signed [i386], efibootmgr [linux-any]
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-ia32 (<< 1.99-1)
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with the
- EFI-IA32 architecture, as used by Intel Macs (unless a BIOS interface has
- been activated). It can be installed in parallel with other flavours, but
- will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-efi-ia32 is also
- installed.
-
-Package: grub-efi-ia32-dbg
-Section: debug
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}, grub-efi-ia32-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 debug files)
- This package contains debugging files for grub-efi-ia32-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-ia32
-Architecture: any-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-ia32-bin (= ${binary:Version}), ucf
-Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the EFI-IA32 architecture, as used by Intel Macs (unless a BIOS
- interface has been activated). Installing this package indicates that this
- version of GRUB should be the active boot loader.
-
-Package: grub-efi-ia32-signed-template
-Architecture: i386
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 signing template)
- This package contains template files for grub-efi-ia32-signed.
- This is only needed for Secure Boot signing.
-
Package: grub-efi-amd64-bin
Architecture: i386 kopensolaris-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
+Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common
Recommends: grub-efi-amd64-signed [amd64], efibootmgr [linux-any]
Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64 (<< 1.99-1)
Multi-Arch: foreign
@@ -342,9 +86,9 @@ Description: GRand Unified Bootloader, version 2 (EFI-AMD64 debug files)
Package: grub-efi-amd64
Architecture: i386 kopensolaris-i386 any-amd64
Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-amd64-bin (= ${binary:Version}), ucf
-Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc, grub-efi-ia32, grub-coreboot, grub-ieee1275
-Conflicts: grub, grub-legacy, grub-efi-ia32, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo
+Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common, grub-efi-amd64-bin, ucf
+Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc, grub-coreboot, grub-ieee1275
+Conflicts: grub, grub-legacy, grub-coreboot, grub-ieee1275, grub-xen, elilo
Multi-Arch: foreign
Description: GRand Unified Bootloader, version 2 (EFI-AMD64 version)
GRUB is a portable, powerful bootloader. This version of GRUB is based on a
@@ -522,255 +266,3 @@ Architecture: arm64
Description: GRand Unified Bootloader, version 2 (ARM64 UEFI signing template)
This package contains template files for grub-efi-arm64-signed.
This is only needed for Secure Boot signing.
-
-Package: grub-ieee1275-bin
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-ieee1275 (<< 1.99-1)
-Suggests: genisoimage [any-powerpc any-ppc64 any-ppc64el]
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Open Firmware modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with Open
- Firmware implementations. It can be installed in parallel with other
- flavours, but will not automatically install GRUB as the active boot loader
- nor automatically update grub.cfg on upgrade unless grub-ieee1275 is also
- installed.
-
-Package: grub-ieee1275-dbg
-Section: debug
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
-Depends: ${misc:Depends}, grub-ieee1275-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Open Firmware debug files)
- This package contains debugging files for grub-ieee1275-bin. You only
- need these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-ieee1275
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-ieee1275-bin (= ${binary:Version}), ucf, powerpc-ibm-utils (>= 1.2.12-1) [any-powerpc any-ppc64 any-ppc64el], powerpc-utils [any-powerpc any-ppc64 any-ppc64el]
-Replaces: grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-pc
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-pc, grub-xen
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Open Firmware version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with Open Firmware implementations. Installing this package indicates
- that this version of GRUB should be the active boot loader.
-
-Package: grub-firmware-qemu
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}
-Recommends: qemu-system-x86
-Enhances: qemu-system-x86
-Multi-Arch: foreign
-Description: GRUB firmware image for QEMU
- This package contains a binary of GRUB that has been built for use as
- firmware for QEMU. It can be used as a replacement for other PC BIOS
- images provided by seabios, bochsbios, and so on.
- .
- In order to make QEMU use this firmware, simply add `-bios grub.bin' when
- invoking it.
- .
- This package behaves in the same way as GRUB for coreboot, but doesn't
- contain any code from coreboot itself, and is only suitable for QEMU. If
- you want to install GRUB as firmware on real hardware, you need to use the
- grub-coreboot package, and manually combine that with coreboot.
-
-Package: grub-uboot-bin
-Architecture: any-arm
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM U-Boot modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with ARM
- systems with U-Boot. It can be installed in parallel with other flavours,
- but will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-uboot is also
- installed.
-
-Package: grub-uboot-dbg
-Section: debug
-Architecture: any-arm
-Depends: ${misc:Depends}, grub-uboot-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM U-Boot debug files)
- This package contains debugging files for grub-uboot-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-uboot
-Architecture: any-arm
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-uboot-bin (= ${binary:Version}), ucf
-Conflicts: grub-efi-arm
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM U-Boot version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with ARM systems with U-Boot. Installing this package indicates that
- this version of GRUB should be the active boot loader.
-
-Package: grub-xen-bin
-Architecture: i386 amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Xen modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with the
- Xen hypervisor (i.e. PV-GRUB). It can be installed in parallel with other
- flavours, but will not automatically install GRUB as the active boot loader
- nor automatically update grub.cfg on upgrade unless grub-xen is also
- installed.
-
-Package: grub-xen-dbg
-Section: debug
-Architecture: i386 amd64
-Depends: ${misc:Depends}, grub-xen-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Xen debug files)
- This package contains debugging files for grub-xen-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-xen
-Architecture: i386 amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-xen-bin (= ${binary:Version}), ucf
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-pc
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Xen version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the Xen hypervisor (i.e. PV-GRUB). Installing this package
- indicates that this version of GRUB should be the active boot loader.
-
-Package: grub-xen-host
-Architecture: i386 amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-xen-bin (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Xen host version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package arranges for GRUB binary images which can be used to boot a Xen
- guest (i.e. PV-GRUB) to be present in the control domain filesystem.
-
-Package: grub-yeeloong-bin
-Architecture: any-mipsel
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Replaces: grub-common (<< 1.98+20100617-2), grub-yeeloong (<< 1.99-1)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Yeeloong modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with the
- Lemote Yeeloong laptop. It can be installed in parallel with other
- flavours, but will not automatically install GRUB as the active boot loader
- nor automatically update grub.cfg on upgrade unless grub-yeeloong is also
- installed.
-
-Package: grub-yeeloong-dbg
-Section: debug
-Architecture: any-mipsel
-Depends: ${misc:Depends}, grub-yeeloong-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Yeeloong debug files)
- This package contains debugging files for grub-yeeloong-bin. You only
- need these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-yeeloong
-Architecture: any-mipsel
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-yeeloong-bin (= ${binary:Version}), ucf
-Replaces: grub-common (<< 1.98+20100617-2)
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (Yeeloong version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the Lemote Yeeloong laptop. Installing this package indicates
- that this version of GRUB should be the active boot loader.
-
-Package: grub-theme-starfield
-# Could be Architecture: any, but in practice this package is useless in a
-# utilities-only build.
-Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64 any-mipsel any-ia64 any-arm any-arm64
-Depends: ${misc:Depends}, grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (starfield theme)
- This is the default theme for GRUB's graphical menu.
-
-Package: grub-mount-udeb
-Package-Type: udeb
-Section: debian-installer
-Architecture: linux-any kfreebsd-any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: export GRUB filesystems using FUSE
diff --git a/debian/rules b/debian/rules
index be8f870..c22ba5a 100755
--- a/debian/rules
+++ b/debian/rules
@@ -55,7 +55,7 @@ BUILD_PACKAGES := $(strip $(shell dh_listpackages))
# REAL_PACKAGES build an actual grub variant (and therefore have both configure
# and build stages). EXTRA_PACKAGES do not build grub but may depend on a
# REAL_PACKAGE (and therefore only have a build stage)
-REAL_PACKAGES = grub-common grub-emu grub-pc grub-coreboot grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-firmware-qemu grub-uboot grub-xen grub-yeeloong
+REAL_PACKAGES = grub-common grub-emu grub-pc grub-coreboot grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-firmware-qemu grub-uboot grub-xen grub-yeeloong
EXTRA_PACKAGES = grub-rescue-pc grub-xen-host
ifneq (,$(filter i386 amd64,$(DEB_HOST_ARCH_CPU)))
@@ -111,8 +111,6 @@ DEFAULT_HIDDEN_TIMEOUT_BOOL := false
endif
# Secure Boot
-debian/stamps/build-grub-efi-ia32 install/grub-efi-ia32: export SB_PLATFORM := i386-efi
-debian/stamps/build-grub-efi-ia32 install/grub-efi-ia32: export SB_EFI_NAME := ia32
debian/stamps/build-grub-efi-amd64 install/grub-efi-amd64: export SB_PLATFORM := x86_64-efi
debian/stamps/build-grub-efi-amd64 install/grub-efi-amd64: export SB_EFI_NAME := x64
debian/stamps/build-grub-efi-arm64 install/grub-efi-arm64: export SB_PLATFORM := arm64-efi
@@ -169,10 +167,10 @@ override_dh_autoreconf:
PYTHON=python3 \
dh_autoreconf -- ./autogen.sh
-debian/stamps/configure-grub-common: debian/stamps/configure-grub-$(COMMON_PLATFORM)
+debian/stamps/configure-grub-common:
touch $@
-debian/stamps/build-grub-common: debian/stamps/build-grub-$(COMMON_PLATFORM)
+debian/stamps/build-grub-common:
touch $@
debian/stamps/configure-grub-none debian/stamps/configure-grub-pc debian/stamps/configure-grub-ieee1275 debian/stamps/configure-grub-coreboot debian/stamps/configure-grub-emu debian/stamps/configure-grub-uboot debian/stamps/configure-grub-yeeloong:
@@ -181,10 +179,6 @@ debian/stamps/configure-grub-none debian/stamps/configure-grub-pc debian/stamps/
touch $@
# This name scheme leaves room for things like amd32 someday
-debian/stamps/configure-grub-efi-ia32:
- mkdir -p debian/stamps obj/$(package)
- dh_auto_configure -- $(confflags) --with-platform=efi --target=i386-pe --program-prefix=""
- touch $@
debian/stamps/configure-grub-efi-amd64:
mkdir -p debian/stamps $(subst debian/stamps/configure-,obj/,$@)
dh_auto_configure -- $(confflags) --with-platform=efi --target=amd64-pe --program-prefix=""
@@ -214,7 +208,7 @@ debian/stamps/build-grub-none debian/stamps/build-grub-efi-ia64 debian/stamps/bu
dh_auto_build
touch $@
-debian/stamps/build-grub-efi-ia32 debian/stamps/build-grub-efi-amd64 debian/stamps/build-grub-efi-arm64: debian/stamps/build-%: debian/stamps/configure-% debian/stamps/build-grub-$(COMMON_PLATFORM)
+debian/stamps/build-grub-efi-amd64 debian/stamps/build-grub-efi-arm64: debian/stamps/build-%: debian/stamps/configure-%
dh_auto_build
grub_dir=`mktemp -d` ; \
sed -e "s/@DEB_VERSION@/$(deb_version)/g" \
@@ -222,7 +216,7 @@ debian/stamps/build-grub-efi-ia32 debian/stamps/build-grub-efi-amd64 debian/stam
<debian/sbat.$(SB_EFI_VENDOR).csv.in \
>$${grub_dir}/sbat.$(SB_EFI_VENDOR).csv; \
debian/build-efi-images \
- obj/grub-$(COMMON_PLATFORM)/grub-mkimage \
+ obj/$(package)/grub-mkimage \
obj/$(package)/grub-core \
obj/monolithic/$(package) \
$(DEB_HOST_ARCH) $(SB_PLATFORM) $(SB_EFI_NAME) \
@@ -350,7 +344,20 @@ install/grub-none:
# files.
mkdir -p debian/tmp-$(package)/usr/share/locale
-install/grub-pc install/grub-efi-ia32 install/grub-efi-amd64 install/grub-efi-ia64 install/grub-efi-arm install/grub-efi-arm64 install/grub-ieee1275 install/grub-coreboot install/grub-emu install/grub-uboot install/grub-xen install/grub-yeeloong:
+D_PACKAGE := debian/grub-efi-amd64/
+EFI_BOOT_PATH := /boot/efi/EFI/BOOT
+DISTRO_NAME := StarlingX
+DISTRO_VERSION :=
+OSTREE_GRUB_PW_FILE := ./boot_cfg_pw
+OSTREE_GRUB_USER := root
+OSTREE_CONSOLE := console=ttyS0,115200
+GRUB_BUILDIN := boot linux ext2 fat serial part_msdos part_gpt normal efi_gop iso9660 configfile search loadenv test tftp efinet reboot chain regexp efivar
+GRUB_SECURE_BUILDIN := tftp reboot chain efivar password_pbkdf2 pgp gcry_rsa gcry_sha256 gcry_sha512 --pubkey ./boot_pub_key
+GRUB_TARGET := x86_64
+GRUB_PREFIX_DIR := /EFI/BOOT
+OBJ_DIR := ./obj/grub-efi-amd64
+
+install/grub-efi-amd64 install/grub-efi-ia64 install/grub-efi-arm install/grub-efi-arm64 install/grub-ieee1275 install/grub-coreboot install/grub-emu install/grub-uboot install/grub-xen install/grub-yeeloong:
set -e ; \
if [ "$@" = "install/grub-xen" ] ; then \
dh_auto_install -Bobj/grub-xen-i386 --destdir=debian/tmp-$(package); \
@@ -470,6 +477,30 @@ install/grub-pc install/grub-efi-ia32 install/grub-efi-amd64 install/grub-efi-ia
# files.
mkdir -p debian/tmp-$(package)/usr/share/locale
+ if [ "$@" = "install/grub-efi-amd64" ] ; then \
+ install -d $(D_PACKAGE)/$(EFI_BOOT_PATH) ; \
+ install -m 0600 ./grub-runtime.cfg $(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg ; \
+ sed -i "s#%DISTRO_NAME%#$(DISTRO_NAME)#g" "$(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg" ; \
+ sed -i "s#%DISTRO_VERSION%#$(DISTRO_VERSION)#g" "$(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg" ; \
+ echo -n "password_pbkdf2 $(OSTREE_GRUB_USER) " > ./pw ; \
+ cat "$(OSTREE_GRUB_PW_FILE)" >> ./pw ; \
+ sed -i "s#%OSTREE_GRUB_USER%#$(OSTREE_GRUB_USER)#g" "$(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg" ; \
+ str_pw=`cat ./pw` ; \
+ sed -i "s#%OSTREE_GRUB_PW%#$${str_pw}#g" "$(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg" ; \
+ sed -i "s#%OSTREE_CONSOLE%#$(OSTREE_CONSOLE)#g" "$(D_PACKAGE)$(EFI_BOOT_PATH)/grub.cfg" ; \
+ $(OBJ_DIR)/grub-mkimage -c ./cfg_nosecure -p "$(GRUB_PREFIX_DIR)" -d "$(OBJ_DIR)/grub-core" \
+ -O "$(GRUB_TARGET)-efi" -o "./bootx64-nosig.efi" \
+ $(GRUB_BUILDIN) ; \
+ install -m 0644 ./bootx64-nosig.efi $(D_PACKAGE)$(EFI_BOOT_PATH)/bootx64-nosig.efi ; \
+ $(OBJ_DIR)/grub-editenv "$(D_PACKAGE)$(EFI_BOOT_PATH)/grubenv" create ; \
+ install -d $(D_PACKAGE)$(EFI_BOOT_PATH)/$(GRUB_TARGET)-efi ; \
+ $(OBJ_DIR)/grub-mkimage -c ./cfg -p "$(GRUB_PREFIX_DIR)" -d "$(OBJ_DIR)/grub-core" \
+ -O "$(GRUB_TARGET)-efi" -o "./grubx64.efi" \
+ $(GRUB_BUILDIN) $(GRUB_SECURE_BUILDIN) ; \
+ install -m 0644 ./grubx64.efi $(D_PACKAGE)$(EFI_BOOT_PATH)/grubx64.efi ; \
+ install -m 0644 $(OBJ_DIR)/grub-core/*.mod $(D_PACKAGE)$(EFI_BOOT_PATH)/$(GRUB_TARGET)-efi ; \
+ fi
+
common_subst = \
if [ -e debian/grub-common.$(1) ]; then \
sed 's/@COMMON_PLATFORM@/$(COMMON_PLATFORM)/g' \
@@ -495,13 +526,12 @@ endif
NON_PLATFORM_PACKAGES = $(filter grub2 grub-linuxbios grub-efi grub-rescue-pc grub-firmware-qemu grub-xen-host,$(BUILD_PACKAGES))
COMMON_PLATFORM_PACKAGES = $(filter grub-common grub2-common grub-theme-starfield grub-mount-udeb,$(BUILD_PACKAGES))
-PLATFORM_PACKAGES = $(filter grub-pc grub-efi-ia32 grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-coreboot grub-uboot grub-xen grub-yeeloong,$(BUILD_PACKAGES))
+PLATFORM_PACKAGES = $(filter grub-pc grub-efi-amd64 grub-efi-ia64 grub-efi-arm grub-efi-arm64 grub-ieee1275 grub-coreboot grub-uboot grub-xen grub-yeeloong,$(BUILD_PACKAGES))
override_dh_install:
ifneq (,$(NON_PLATFORM_PACKAGES))
dh_install $(patsubst %,-p%,$(NON_PLATFORM_PACKAGES))
endif
- dh_install $(patsubst %,-p%,$(COMMON_PLATFORM_PACKAGES)) --sourcedir=debian/tmp-grub-$(COMMON_PLATFORM)
rm -f debian/grub2-common/usr/share/info/dir*
rm -f debian/grub-theme-starfield/usr/share/grub/themes/starfield/COPYING.CC-BY-SA-3.0
ifneq (,$(PLATFORM_PACKAGES))
--
2.17.1

View File

@@ -0,0 +1,2 @@
0001-Make-series-null.patch
0002-grub-efi-build-packages-related-with-grub-efi.patch

View File

@@ -0,0 +1,42 @@
#!/bin/bash
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# The only parameter is the name of the folder where the source code
# is extracted to. Pay attention to that the extracted package should
# be put at the same path where this script is located.
# Tools needed: tar
tar xvf grub2_2.06.orig.tar.xz
if [ $? -ne 0 ]
then
echo "tar failed: orig source!"
exit 1
fi
mv grub-2.06 $1
cd $1
tar xvf ../grub2_2.06-1.debian.tar.xz
if [ $? -ne 0 ]
then
echo "tar failed: debian folder!"
exit 1
fi
cp ../local_debian/files/* ./
cp ${MY_REPO}/public-keys/boot_pub_key ./

View File

@@ -0,0 +1 @@
grub.pbkdf2.sha512.10000.7C392DD2FFEA15F1E050CF88DB414F128724C55039614BFCF22D9F3AA775E534BEC0A0A2E6C49FE3CBBC7A1A9CE7546D11FD198197A375044EF96D189EC22141.712E252EC3009DD64C5157615DF84F46B3D4A7C6F40DF941CB62C8965B25AA3D62B0D2080545FCB7801A62A72244F87DC13FF26D740A32D96D5F85017BB4AB03

View File

@@ -0,0 +1,4 @@
set strict_security=1
search.file ($cmdpath)/EFI/BOOT/grub.cfg root
set prefix=($root)/EFI/BOOT
set skip_check_cfg=1

View File

@@ -0,0 +1,2 @@
search.file ($cmdpath)/EFI/BOOT/grub.cfg root
set prefix=($root)/EFI/BOOT

View File

@@ -0,0 +1,123 @@
set default="0"
set timeout=3
set color_normal='light-gray/black'
set color_highlight='light-green/blue'
set boot_part="otaboot"
set root_part="otaroot"
set flux_part="fluxdata"
set rollback_part="_b"
set ab="1"
set ostree_console="%OSTREE_CONSOLE%"
set kernel=vmlinuz
set kernel_rollback=vmlinuz
set kernel_params=""
set kernel_params_ext=""
if [ "${legacy_bios}" != "1" ]; then
set boot_env_path=${prefix}
fi
if [ -e ${boot_env_path}/boot.env ]; then
load_env -s -f ${boot_env_path}/boot.env
if [ "${boot_tried_count}" -eq "0" ]; then
set boot_tried_count="1"
elif [ "${boot_tried_count}" -eq "1" ]; then
set boot_tried_count="2"
elif [ "${boot_tried_count}" -eq "2" ]; then
set boot_tried_count="3"
elif [ "${boot_tried_count}" -eq "3" ]; then
if [ "${default}" -eq "1" ]; then
set default="0"
else
set default="1"
fi
save_env -f ${boot_env_path}/boot.env default
set boot_tried_count="0"
fi
save_env -f ${boot_env_path}/boot.env boot_tried_count
fi
search --no-floppy --label --set=avol ${boot_part}${boot_mode}
if [ -e ($avol)/1/kernel.env ] ; then
load_env -s -f ($avol)/1/kernel.env kernel
fi
if [ "$ab" = "1" ] ; then
search --no-floppy --label --set=bvol ${boot_part}${rollback_part}
if [ -e ($avol)/1/kernel.env ] ; then
load_env -s -f ($avol)/1/kernel.env kernel_rollback
fi
else
if [ -e ($avol)/2/kernel.env ] ; then
load_env -s -f ($avol)/2/kernel.env kernel_rollback
fi
fi
get_efivar -f uint8 -s secured SecureBoot
if [ "${secured}" = "1" ]; then
# Enable user authentication to make grub unlockable
set superusers="%OSTREE_GRUB_USER%"
%OSTREE_GRUB_PW%
else
get_efivar -f uint8 -s unprovisioned SetupMode
if [ "${unprovisioned}" = "1" ]; then
set timeout=0
menuentry "Automatic Certificate Provision" --unrestricted {
chainloader ${prefix}/LockDown.efi
}
fi
fi
menuentry "%DISTRO_NAME% %DISTRO_VERSION% ostree${boot_mode} ${kernel}" --unrestricted {
set fallback=1
if [ "${legacy_bios}" != "1" ]; then
efi-watchdog enable 0 180
fi
search --no-floppy --label --set=root ${boot_part}${boot_mode}
if [ -e /1/kernel.env ] ; then
load_env -s -f /1/kernel.env kernel_params_ext
fi
linux /1/${kernel} rw rootwait ostree_boot=LABEL=${boot_part}${boot_mode} ostree_root=LABEL=${root_part}${boot_mode} flux=${flux_part} ostree=/ostree/1 $ostree_console $kernel_params $kernel_params_ext
initrd /1/initramfs
}
if [ "$ab" = "1" ] ; then
menuentry "%DISTRO_NAME% %DISTRO_VERSION% ostree ${kernel_rollback} rollback${rollback_part}" --unrestricted {
search --no-floppy --label --set=root ${boot_part}${rollback_part}
if [ -e /1/kernel.env ] ; then
load_env -s -f /1/kernel.env kernel_params_ext
fi
linux /1/${kernel_rollback} rw rootwait ostree_boot=LABEL=${boot_part}${rollback_part} ostree_root=LABEL=${root_part}${rollback_part} flux=${flux_part} ostree=/ostree/1 $ostree_console $kernel_params $kernel_params_ext
initrd /1/initramfs
}
else
menuentry "%DISTRO_NAME% %DISTRO_VERSION% ostree${boot_mode} ${kernel_rollback} rollback" --unrestricted {
set fallback=1
if [ "${legacy_bios}" != "1" ]; then
efi-watchdog enable 0 180
fi
search --no-floppy --label --set=root ${boot_part}${boot_mode}
if [ -e /2/kernel.env ] ; then
load_env -s -f /2/kernel.env kernel_params_ext
fi
linux /2/${kernel_rollback} rw rootwait ostree_boot=LABEL=${boot_part}${boot_mode} ostree_root=LABEL=${root_part}${boot_mode} flux=${flux_part} ostree=/ostree/2 $ostree_console $kernel_params $kernel_params_ext
initrd /2/initramfs
}
fi
if [ -s ${prefix}/igrub.cfg ] ; then
source ${prefix}/igrub.cfg
search --no-floppy --label --set=avol ${boot_part}${boot_mode}
if [ "$ab" = "1" ] ; then
search --no-floppy --label --set=bvol ${boot_part}${rollback_part}
if [ ! -s ($avol)/1/${kernel} -a ! -s ($bvol)/1/${kernel_rollback} ] ; then
set default="2"
fi
else
if [ ! -s ($avol)/1/${kernel} -a ! -s ($avol)/2/${kernel_rollback} ] ; then
set default="2"
fi
fi
fi

View File

@@ -0,0 +1,21 @@
---
debver: 2.06-1
debname: grub-efi
serial: true
dl_hook: dl_hook
dl_files:
grub2_2.06.orig.tar.xz:
topdir: null
url:
"https://snapshot.debian.org/archive/debian/20211128T160803Z/\
pool/main/g/grub2/grub2_2.06.orig.tar.xz"
sha256sum: b79ea44af91b93d17cd3fe80bdae6ed43770678a9a5ae192ccea803ebb657ee1
grub2_2.06-1.debian.tar.xz:
topdir: null
url:
"https://snapshot.debian.org/archive/debian/20211128T160803Z/\
pool/main/g/grub2/grub2_2.06-1.debian.tar.xz"
sha256sum: 16a1a89d93abf8beb148dc30738be1bda05ed3c09cfffd4a1f5e1a0328c74b26
revision:
dist: $STX_DIST
PKG_GITREVCOUNT: true

View File

@@ -0,0 +1,32 @@
From be38cbc51f89493c46e299950937b85893ca05e8 Mon Sep 17 00:00:00 2001
From: Bin Qian <bin.qian@windriver.com>
Date: Tue, 21 Nov 2017 15:36:42 -0500
Subject: [PATCH] grub2: add tboot
Original patch is 1001-add-tboot.patch
Signed-off-by: Bin Qian <bin.qian@windriver.com>
Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
---
util/grub.d/10_linux.in | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 0cd4cf5..81435a8 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -28,6 +28,11 @@ vt_handoff="@VT_HANDOFF@"
. "$pkgdatadir/grub-mkconfig_lib"
+tboot=`cat /proc/cmdline | xargs -n1 | grep '^tboot=true$'` || true
+if [ -n "$tboot" ]; then
+ exit 0
+fi
+
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
--
2.25.1

View File

@@ -0,0 +1,48 @@
From bbd8d33b8646785ee31b435e9decf4271d6ecb68 Mon Sep 17 00:00:00 2001
From: Yue Tao <Yue.Tao@windriver.com>
Date: Sun, 5 Dec 2021 10:01:05 +0800
Subject: [PATCH] grub2: checking if loop devices are available
Building in a chroot environment, may not have loop device.
Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
---
tests/ext234_test.in | 5 +++++
tests/fat_test.in | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/tests/ext234_test.in b/tests/ext234_test.in
index 4f1eb52..380850e 100644
--- a/tests/ext234_test.in
+++ b/tests/ext234_test.in
@@ -25,6 +25,11 @@ if ! which mkfs.ext4 >/dev/null 2>&1; then
exit 77
fi
+if ! losetup -f >/dev/null 2>&1; then
+ echo "No loop device, cannot test."
+ exit 77
+fi
+
"@builddir@/grub-fs-tester" ext2_old
"@builddir@/grub-fs-tester" ext2
"@builddir@/grub-fs-tester" ext3
diff --git a/tests/fat_test.in b/tests/fat_test.in
index b6b4748..ab5348a 100644
--- a/tests/fat_test.in
+++ b/tests/fat_test.in
@@ -15,6 +15,11 @@ if ! which mkfs.vfat >/dev/null 2>&1; then
exit 77
fi
+if ! losetup -f >/dev/null 2>&1; then
+ echo "No loop device, cannot test."
+ exit 77
+fi
+
"@builddir@/grub-fs-tester" vfat16a
"@builddir@/grub-fs-tester" vfat12a
"@builddir@/grub-fs-tester" vfat12
--
2.25.1

View File

@@ -0,0 +1,99 @@
From 24e6d59ac676791507ff5267bf3bef6cbaff6aef Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Thu, 2 Dec 2021 15:03:53 +0100
Subject: kern/efi/sb: Reject non-kernel files in the shim_lock verifier
We must not allow other verifiers to pass things like the GRUB modules.
Instead of maintaining a blocklist, maintain an allowlist of things
that we do not care about.
This allowlist really should be made reusable, and shared by the
lockdown verifier, but this is the minimal patch addressing
security concerns where the TPM verifier was able to mark modules
as verified (or the OpenPGP verifier for that matter), when it
should not do so on shim-powered secure boot systems.
Fixes: CVE-2022-28735
Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/sb.c | 39 ++++++++++++++++++++++++++++++++++++---
include/grub/verify.h | 1 +
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index c52ec6226..89c4bb3fd 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -119,10 +119,11 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
void **context __attribute__ ((unused)),
enum grub_verify_flags *flags)
{
- *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ *flags = GRUB_VERIFY_FLAGS_NONE;
switch (type & GRUB_FILE_TYPE_MASK)
{
+ /* Files we check. */
case GRUB_FILE_TYPE_LINUX_KERNEL:
case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
case GRUB_FILE_TYPE_BSD_KERNEL:
@@ -130,11 +131,43 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_PLAN9_KERNEL:
case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
*flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
- /* Fall through. */
+ /* Files that do not affect secureboot state. */
+ case GRUB_FILE_TYPE_NONE:
+ case GRUB_FILE_TYPE_LOOPBACK:
+ case GRUB_FILE_TYPE_LINUX_INITRD:
+ case GRUB_FILE_TYPE_OPENBSD_RAMDISK:
+ case GRUB_FILE_TYPE_XNU_RAMDISK:
+ case GRUB_FILE_TYPE_SIGNATURE:
+ case GRUB_FILE_TYPE_PUBLIC_KEY:
+ case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST:
+ case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
+ case GRUB_FILE_TYPE_TESTLOAD:
+ case GRUB_FILE_TYPE_GET_SIZE:
+ case GRUB_FILE_TYPE_FONT:
+ case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
+ case GRUB_FILE_TYPE_CAT:
+ case GRUB_FILE_TYPE_HEXCAT:
+ case GRUB_FILE_TYPE_CMP:
+ case GRUB_FILE_TYPE_HASHLIST:
+ case GRUB_FILE_TYPE_TO_HASH:
+ case GRUB_FILE_TYPE_KEYBOARD_LAYOUT:
+ case GRUB_FILE_TYPE_PIXMAP:
+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST:
+ case GRUB_FILE_TYPE_CONFIG:
+ case GRUB_FILE_TYPE_THEME:
+ case GRUB_FILE_TYPE_GETTEXT_CATALOG:
+ case GRUB_FILE_TYPE_FS_SEARCH:
+ case GRUB_FILE_TYPE_LOADENV:
+ case GRUB_FILE_TYPE_SAVEENV:
+ case GRUB_FILE_TYPE_VERIFY_SIGNATURE:
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ /* Other files. */
default:
- return GRUB_ERR_NONE;
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy"));
}
}
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 6fde244fc..67448165f 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -24,6 +24,7 @@
enum grub_verify_flags
{
+ GRUB_VERIFY_FLAGS_NONE = 0,
GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1,
GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2,
/* Defer verification to another authority. */

View File

@@ -0,0 +1,109 @@
From a85714545fe57a86d14ee231a4cd312158101d43 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Wed, 26 Oct 2022 20:16:44 -0400
Subject: [PATCH 01/14] video/readers: Add artificial limit to image dimensions
In grub-core/video/readers/jpeg.c, the height and width of a JPEG image don't
have an upper limit for how big the JPEG image can be. In Coverity, this is
getting flagged as an untrusted loop bound. This issue can also seen in PNG and
TGA format images as well but Coverity isn't flagging it. To prevent this, the
constant IMAGE_HW_MAX_PX is being added to include/grub/bitmap.h, which has
a value of 16384, to act as an artificial limit and restrict the height and
width of images. This value was picked as it is double the current max
resolution size, which is 8K.
Fixes: CID 292450
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 3 ++-
grub-core/video/readers/jpeg.c | 6 +++++-
grub-core/video/readers/png.c | 6 +++++-
grub-core/video/readers/tga.c | 7 +++++++
include/grub/bitmap.h | 2 ++
5 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 0dbbdc374..2d6cd8358 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1515,7 +1515,8 @@ resolution. @xref{gfxmode}.
Set a background image for use with the @samp{gfxterm} graphical terminal.
The value of this option must be a file readable by GRUB at boot time, and
it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}.
-The image will be scaled if necessary to fit the screen.
+The image will be scaled if necessary to fit the screen. Image height and
+width will be restricted by an artificial limit of 16384.
@item GRUB_THEME
Set a theme for use with the @samp{gfxterm} graphical terminal.
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 09596fbf5..ae634fd41 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -346,7 +346,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
data->image_height = grub_jpeg_get_word (data);
data->image_width = grub_jpeg_get_word (data);
- if ((!data->image_height) || (!data->image_width))
+ grub_dprintf ("jpeg", "image height: %d\n", data->image_height);
+ grub_dprintf ("jpeg", "image width: %d\n", data->image_width);
+
+ if ((!data->image_height) || (!data->image_width) ||
+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
cc = grub_jpeg_get_byte (data);
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 7f2ba7849..3163e97bf 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -264,7 +264,11 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->image_width = grub_png_get_dword (data);
data->image_height = grub_png_get_dword (data);
- if ((!data->image_height) || (!data->image_width))
+ grub_dprintf ("png", "image height: %d\n", data->image_height);
+ grub_dprintf ("png", "image width: %d\n", data->image_width);
+
+ if ((!data->image_height) || (!data->image_width) ||
+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
color_bits = grub_png_get_byte (data);
diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c
index a9ec3a1b6..9c35bf29d 100644
--- a/grub-core/video/readers/tga.c
+++ b/grub-core/video/readers/tga.c
@@ -340,6 +340,13 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap,
data.image_width = grub_le_to_cpu16 (data.hdr.image_width);
data.image_height = grub_le_to_cpu16 (data.hdr.image_height);
+ grub_dprintf ("tga", "image height: %d\n", data.image_height);
+ grub_dprintf ("tga", "image width: %d\n", data.image_width);
+
+ /* Check image height and width are within restrictions. */
+ if ((data.image_height > IMAGE_HW_MAX_PX) || (data.image_width > IMAGE_HW_MAX_PX))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "tga: invalid image size");
+
/* Check that bitmap encoding is supported. */
switch (data.hdr.image_type)
{
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
index 5728f8ca3..149d37bfe 100644
--- a/include/grub/bitmap.h
+++ b/include/grub/bitmap.h
@@ -24,6 +24,8 @@
#include <grub/types.h>
#include <grub/video.h>
+#define IMAGE_HW_MAX_PX 16384
+
struct grub_video_bitmap
{
/* Bitmap format description. */
--
2.30.2

View File

@@ -0,0 +1,33 @@
From 5760fcfd466cc757540ea0d591bad6a08caeaa16 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Wed, 3 Aug 2022 19:45:33 +0800
Subject: [PATCH 02/14] font: Reject glyphs exceeds font->max_glyph_width or
font->max_glyph_height
Check glyph's width and height against limits specified in font's
metadata. Reject the glyph (and font) if such limits are exceeded.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 42189c325..756ca0abf 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|| read_be_uint16 (font->file, &height) != 0
|| read_be_int16 (font->file, &xoff) != 0
|| read_be_int16 (font->file, &yoff) != 0
- || read_be_int16 (font->file, &dwidth) != 0)
+ || read_be_int16 (font->file, &dwidth) != 0
+ || width > font->max_char_width
+ || height > font->max_char_height)
{
remove_font (font);
return 0;
--
2.30.2

View File

@@ -0,0 +1,110 @@
From 941d10ad6f1dcbd12fb613002249e29ba035f985 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 00:51:20 +0800
Subject: [PATCH 03/14] font: Fix size overflow in
grub_font_get_glyph_internal()
The length of memory allocation and file read may overflow. This patch
fixes the problem by using safemath macros.
There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe
if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz().
It is safe replacement for such code. It has safemath-like prototype.
This patch also introduces grub_cast(value, pointer), it casts value to
typeof(*pointer) then store the value to *pointer. It returns true when
overflow occurs or false if there is no overflow. The semantics of arguments
and return value are designed to be consistent with other safemath macros.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 17 +++++++++++++----
include/grub/bitmap.h | 18 ++++++++++++++++++
include/grub/safemath.h | 2 ++
3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 2f09a4a55..6a3fbebbd 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
grub_int16_t xoff;
grub_int16_t yoff;
grub_int16_t dwidth;
- int len;
+ grub_ssize_t len;
+ grub_size_t sz;
if (index_entry->glyph)
/* Return cached glyph. */
@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
return 0;
}
- len = (width * height + 7) / 8;
- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
- if (!glyph)
+ /* Calculate real struct size of current glyph. */
+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) ||
+ grub_add (sizeof (struct grub_font_glyph), len, &sz))
+ {
+ remove_font (font);
+ return 0;
+ }
+
+ /* Allocate and initialize the glyph struct. */
+ glyph = grub_malloc (sz);
+ if (glyph == NULL)
{
remove_font (font);
return 0;
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
index 149d37bfe..431048936 100644
--- a/include/grub/bitmap.h
+++ b/include/grub/bitmap.h
@@ -23,6 +23,7 @@
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/video.h>
+#include <grub/safemath.h>
#define IMAGE_HW_MAX_PX 16384
@@ -81,6 +82,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
return bitmap->mode_info.height;
}
+/*
+ * Calculate and store the size of data buffer of 1bit bitmap in result.
+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs.
+ * Return true when overflow occurs or false if there is no overflow.
+ * This function is intentionally implemented as a macro instead of
+ * an inline function. Although a bit awkward, it preserves data types for
+ * safemath macros and reduces macro side effects as much as possible.
+ *
+ * XXX: Will report false overflow if width * height > UINT64_MAX.
+ */
+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \
+({ \
+ grub_uint64_t _bitmap_pixels; \
+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \
+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \
+})
+
void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
struct grub_video_mode_info *mode_info);
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
index c17b89bba..bb0f826de 100644
--- a/include/grub/safemath.h
+++ b/include/grub/safemath.h
@@ -30,6 +30,8 @@
#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
+#define grub_cast(a, res) grub_add ((a), 0, (res))
+
#else
#error gcc 5.1 or newer or clang 3.8 or newer is required
#endif

View File

@@ -0,0 +1,81 @@
From b1805f251b31a9d3cfae5c3572ddfa630145dbbf Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 01:58:27 +0800
Subject: [PATCH 04/14] font: Fix several integer overflows in
grub_font_construct_glyph()
This patch fixes several integer overflows in grub_font_construct_glyph().
Glyphs of invalid size, zero or leading to an overflow, are rejected.
The inconsistency between "glyph" and "max_glyph_size" when grub_malloc()
returns NULL is fixed too.
Fixes: CVE-2022-2601
Reported-by: Zhang Boyang <zhangboyang.id@gmail.com>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e781521a7..e6548892f 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
struct grub_video_signed_rect bounds;
static struct grub_font_glyph *glyph = 0;
static grub_size_t max_glyph_size = 0;
+ grub_size_t cur_glyph_size;
ensure_comb_space (glyph_id);
@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font,
if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph;
- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) ||
+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size))
+ return main_glyph;
+
+ if (max_glyph_size < cur_glyph_size)
{
grub_free (glyph);
- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
- if (max_glyph_size < 8)
- max_glyph_size = 8;
- glyph = grub_malloc (max_glyph_size);
+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size))
+ max_glyph_size = 0;
+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL;
}
if (!glyph)
{
+ max_glyph_size = 0;
grub_errno = GRUB_ERR_NONE;
return main_glyph;
}
- grub_memset (glyph, 0, sizeof (*glyph)
- + (bounds.width * bounds.height
- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
+ grub_memset (glyph, 0, cur_glyph_size);
glyph->font = main_glyph->font;
- glyph->width = bounds.width;
- glyph->height = bounds.height;
- glyph->offset_x = bounds.x;
- glyph->offset_y = bounds.y;
+ if (bounds.width == 0 || bounds.height == 0 ||
+ grub_cast (bounds.width, &glyph->width) ||
+ grub_cast (bounds.height, &glyph->height) ||
+ grub_cast (bounds.x, &glyph->offset_x) ||
+ grub_cast (bounds.y, &glyph->offset_y))
+ return main_glyph;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
grub_font_blit_glyph_mirror (glyph, main_glyph,
--
2.30.2

View File

@@ -0,0 +1,42 @@
From 25ad31c19c331aaa2dbd9bd2b2e2655de5766a9d Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 02:13:29 +0800
Subject: [PATCH 05/14] font: Remove grub_font_dup_glyph()
Remove grub_font_dup_glyph() since nobody is using it since 2013, and
I'm too lazy to fix the integer overflow problem in it.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e6548892f..a8576ffec 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
return best_glyph;
}
-#if 0
-static struct grub_font_glyph *
-grub_font_dup_glyph (struct grub_font_glyph *glyph)
-{
- static struct grub_font_glyph *ret;
- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
- if (!ret)
- return NULL;
- grub_memcpy (ret, glyph, sizeof (*ret)
- + (glyph->width * glyph->height + 7) / 8);
- return ret;
-}
-#endif
-
/* FIXME: suboptimal. */
static void
grub_font_blit_glyph (struct grub_font_glyph *target,
--
2.30.2

View File

@@ -0,0 +1,48 @@
From b2740b7e4a03bb8331d48b54b119afea76bb9d5f Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 02:27:05 +0800
Subject: [PATCH 06/14] font: Fix integer overflow in ensure_comb_space()
In fact it can't overflow at all because glyph_id->ncomb is only 8-bit
wide. But let's keep safe if somebody changes the width of glyph_id->ncomb
in the future. This patch also fixes the inconsistency between
render_max_comb_glyphs and render_combining_glyphs when grub_malloc()
returns NULL.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index a8576ffec..9e3e0a94e 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
if (glyph_id->ncomb <= render_max_comb_glyphs)
return;
- render_max_comb_glyphs = 2 * glyph_id->ncomb;
- if (render_max_comb_glyphs < 8)
+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs))
+ render_max_comb_glyphs = 0;
+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8)
render_max_comb_glyphs = 8;
grub_free (render_combining_glyphs);
- render_combining_glyphs = grub_malloc (render_max_comb_glyphs
- * sizeof (render_combining_glyphs[0]));
+ render_combining_glyphs = (render_max_comb_glyphs > 0) ?
+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL;
if (!render_combining_glyphs)
- grub_errno = 0;
+ {
+ render_max_comb_glyphs = 0;
+ grub_errno = GRUB_ERR_NONE;
+ }
}
int
--
2.30.2

View File

@@ -0,0 +1,65 @@
From afda8b60ba0712abe01ae1e64c5f7a067a0e6492 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 15 Aug 2022 02:04:58 +0800
Subject: [PATCH 07/14] font: Fix integer overflow in BMP index
The BMP index (font->bmp_idx) is designed as a reverse lookup table of
char entries (font->char_index), in order to speed up lookups for BMP
chars (i.e. code < 0x10000). The values in BMP index are the subscripts
of the corresponding char entries, stored in grub_uint16_t, while 0xffff
means not found.
This patch fixes the problem of large subscript truncated to grub_uint16_t,
leading BMP index to return wrong char entry or report false miss. The
code now checks for bounds and uses BMP index as a hint, and fallbacks
to binary-search if necessary.
On the occasion add a comment about BMP index is initialized to 0xffff.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 9e3e0a94e..e4cb0d867 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
if (!font->bmp_idx)
return 1;
+
+ /* Init the BMP index array to 0xffff. */
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
return 1;
}
- if (entry->code < 0x10000)
+ if (entry->code < 0x10000 && i < 0xffff)
font->bmp_idx[entry->code] = i;
last_code = entry->code;
@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
/* Use BMP index if possible. */
if (code < 0x10000 && font->bmp_idx)
{
- if (font->bmp_idx[code] == 0xffff)
- return 0;
- return &table[font->bmp_idx[code]];
+ if (font->bmp_idx[code] < 0xffff)
+ return &table[font->bmp_idx[code]];
+ /*
+ * When we are here then lookup in BMP index result in miss,
+ * fallthough to binary-search.
+ */
}
/* Do a binary search in `char_index', which is ordered by code point. */
--
2.30.2

View File

@@ -0,0 +1,86 @@
From c140a086838e7c9af87842036f891b8393a8c4bc Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Sun, 14 Aug 2022 18:09:38 +0800
Subject: [PATCH 08/14] font: Fix integer underflow in binary search of char
index
If search target is less than all entries in font->index then "hi"
variable is set to -1, which translates to SIZE_MAX and leads to errors.
This patch fixes the problem by replacing the entire binary search code
with the libstdc++'s std::lower_bound() implementation.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e4cb0d867..abd412a5e 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
static inline struct char_index_entry *
find_glyph (const grub_font_t font, grub_uint32_t code)
{
- struct char_index_entry *table;
- grub_size_t lo;
- grub_size_t hi;
- grub_size_t mid;
+ struct char_index_entry *table, *first, *end;
+ grub_size_t len;
table = font->char_index;
+ if (table == NULL)
+ return NULL;
/* Use BMP index if possible. */
if (code < 0x10000 && font->bmp_idx)
@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
*/
}
- /* Do a binary search in `char_index', which is ordered by code point. */
- lo = 0;
- hi = font->num_chars - 1;
-
- if (!table)
- return 0;
+ /*
+ * Do a binary search in char_index which is ordered by code point.
+ * The code below is the same as libstdc++'s std::lower_bound().
+ */
+ first = table;
+ len = font->num_chars;
+ end = first + len;
- while (lo <= hi)
+ while (len > 0)
{
- mid = lo + (hi - lo) / 2;
- if (code < table[mid].code)
- hi = mid - 1;
- else if (code > table[mid].code)
- lo = mid + 1;
+ grub_size_t half = len >> 1;
+ struct char_index_entry *middle = first + half;
+
+ if (middle->code < code)
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
else
- return &table[mid];
+ len = half;
}
- return 0;
+ return (first < end && first->code == code) ? first : NULL;
}
/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded
--
2.30.2

View File

@@ -0,0 +1,54 @@
From 630deb8c0d8b02b670ced4b7030414bcf17aa080 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Sun, 14 Aug 2022 15:51:54 +0800
Subject: [PATCH 09/14] kern/efi/sb: Enforce verification of font files
As a mitigation and hardening measure enforce verification of font
files. Then only trusted font files can be load. This will reduce the
attack surface at cost of losing the ability of end-users to customize
fonts if e.g. UEFI Secure Boot is enabled. Vendors can always customize
fonts because they have ability to pack fonts into their GRUB bundles.
This goal is achieved by:
* Removing GRUB_FILE_TYPE_FONT from shim lock verifier's
skip-verification list.
* Adding GRUB_FILE_TYPE_FONT to lockdown verifier's defer-auth list,
so font files must be verified by a verifier before they can be loaded.
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/sb.c | 1 -
grub-core/kern/lockdown.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index 89c4bb3fd..db42c2539 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -145,7 +145,6 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
case GRUB_FILE_TYPE_TESTLOAD:
case GRUB_FILE_TYPE_GET_SIZE:
- case GRUB_FILE_TYPE_FONT:
case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
case GRUB_FILE_TYPE_CAT:
case GRUB_FILE_TYPE_HEXCAT:
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
index 0bc70fd42..af6d493cd 100644
--- a/grub-core/kern/lockdown.c
+++ b/grub-core/kern/lockdown.c
@@ -51,6 +51,7 @@ lockdown_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
case GRUB_FILE_TYPE_ACPI_TABLE:
case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+ case GRUB_FILE_TYPE_FONT:
*flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
/* Fall through. */
--
2.30.2

View File

@@ -0,0 +1,85 @@
From 50a11a81bc842c58962244a2dc86bbd31a426e12 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Tue, 6 Sep 2022 03:03:21 +0800
Subject: [PATCH 10/14] fbutil: Fix integer overflow
Expressions like u64 = u32 * u32 are unsafe because their products are
truncated to u32 even if left hand side is u64. This patch fixes all
problems like that one in fbutil.
To get right result not only left hand side have to be u64 but it's also
necessary to cast at least one of the operands of all leaf operators of
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
u64 = (u64)u32 * u32 + (u64)u32 * u32.
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
not overflow grub_uint64_t.
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
This patch also adds a comment to grub_video_fb_get_video_ptr() which
says it's arguments must be valid and no sanity check is performed
(like its siblings in grub-core/video/fb/fbutil.c).
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/fb/fbutil.c | 4 ++--
include/grub/fbutil.h | 13 +++++++++----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
index b98bb51fe..25ef39f47 100644
--- a/grub-core/video/fb/fbutil.c
+++ b/grub-core/video/fb/fbutil.c
@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source,
case 1:
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
{
- int bit_index = y * source->mode_info->width + x;
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
grub_uint8_t *ptr = source->data + bit_index / 8;
int bit_pos = 7 - bit_index % 8;
color = (*ptr >> bit_pos) & 0x01;
@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source,
case 1:
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
{
- int bit_index = y * source->mode_info->width + x;
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
grub_uint8_t *ptr = source->data + bit_index / 8;
int bit_pos = 7 - bit_index % 8;
*ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
index 4205eb917..78a1ab3b4 100644
--- a/include/grub/fbutil.h
+++ b/include/grub/fbutil.h
@@ -31,14 +31,19 @@ struct grub_video_fbblit_info
grub_uint8_t *data;
};
-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
- and it doesn't make sense, in general, to ask for a pointer
- to a particular pixel's data. */
+/*
+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
+ * and it doesn't make sense, in general, to ask for a pointer
+ * to a particular pixel's data.
+ *
+ * This function assumes that bounds checking has been done in previous phase
+ * and they are opted out in here.
+ */
static inline void *
grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
unsigned int x, unsigned int y)
{
- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel;
+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel;
}
/* Advance pointer by VAL bytes. If there is no unaligned access available,
--
2.30.2

View File

@@ -0,0 +1,91 @@
From 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 24 Oct 2022 08:05:35 +0800
Subject: [PATCH 11/14] font: Fix an integer underflow in blit_comb()
The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
evaluate to a very big invalid value even if both ctx.bounds.height and
combining_glyphs[i]->height are small integers. For example, if
ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
expression evaluates to 2147483647 (expected -1). This is because
coordinates are allowed to be negative but ctx.bounds.height is an
unsigned int. So, the subtraction operates on unsigned ints and
underflows to a very big value. The division makes things even worse.
The quotient is still an invalid value even if converted back to int.
This patch fixes the problem by casting ctx.bounds.height to int. As
a result the subtraction will operate on int and grub_uint16_t which
will be promoted to an int. So, the underflow will no longer happen. Other
uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
to ensure coordinates are always calculated on signed integers.
Fixes: CVE-2022-3775
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index abd412a5e..3d3d803e8 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
ctx.bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
- above_righty = ctx.bounds.y + ctx.bounds.height;
+ above_righty = ctx.bounds.y + (int) ctx.bounds.height;
above_leftx = main_glyph->offset_x;
- above_lefty = ctx.bounds.y + ctx.bounds.height;
+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
- below_rightx = ctx.bounds.x + ctx.bounds.width;
+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
below_righty = ctx.bounds.y;
comb = grub_unicode_get_comb (glyph_id);
@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
if (!combining_glyphs[i])
continue;
- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (comb[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
- (ctx.bounds.height - combining_glyphs[i]->height) / 2
- - (ctx.bounds.height + ctx.bounds.y), &ctx);
+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
/* Fallthrough. */
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
- -(ctx.bounds.height + ctx.bounds.y + space
+ -((int) ctx.bounds.height + ctx.bounds.y + space
+ combining_glyphs[i]->height), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_COMB_HEBREW_DAGESH:
do_blit (combining_glyphs[i], targetx,
- -(ctx.bounds.height / 2 + ctx.bounds.y
+ -((int) ctx.bounds.height / 2 + ctx.bounds.y
+ combining_glyphs[i]->height / 2), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
--
2.30.2

View File

@@ -0,0 +1,75 @@
From fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 24 Oct 2022 07:15:41 +0800
Subject: [PATCH 12/14] font: Harden grub_font_blit_glyph() and
grub_font_blit_glyph_mirror()
As a mitigation and hardening measure add sanity checks to
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
makes these two functions do nothing if target blitting area isn't fully
contained in target bitmap. Therefore, if complex calculations in caller
overflows and malicious coordinates are given, we are still safe because
any coordinates which result in out-of-bound-write are rejected. However,
this patch only checks for invalid coordinates, and doesn't provide any
protection against invalid source glyph or destination glyph, e.g.
mismatch between glyph size and buffer size.
This hardening measure is designed to mitigate possible overflows in
blit_comb(). If overflow occurs, it may return invalid bounding box
during dry run and call grub_font_blit_glyph() with malicious
coordinates during actual blitting. However, we are still safe because
the scratch glyph itself is valid, although its size makes no sense, and
any invalid coordinates are rejected.
It would be better to call grub_fatal() if illegal parameter is detected.
However, doing this may end up in a dangerous recursion because grub_fatal()
would print messages to the screen and we are in the progress of drawing
characters on the screen.
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 3d3d803e8..cf15dc2f9 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1069,8 +1069,15 @@ static void
grub_font_blit_glyph (struct grub_font_glyph *target,
struct grub_font_glyph *src, unsigned dx, unsigned dy)
{
+ grub_uint16_t max_x, max_y;
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
unsigned i, j;
+
+ /* Harden against out-of-bound writes. */
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
+ return;
+
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i) % 8;
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
struct grub_font_glyph *src,
unsigned dx, unsigned dy)
{
+ grub_uint16_t max_x, max_y;
unsigned tgt_bit, src_byte, tgt_byte;
signed src_bit;
unsigned i, j;
+
+ /* Harden against out-of-bound writes. */
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
+ return;
+
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i + src->width - 1) % 8;
--
2.30.2

View File

@@ -0,0 +1,36 @@
From dd539d695482069d28b40f2d3821f710cdcf6ee6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 28 Oct 2022 17:29:16 +0800
Subject: [PATCH 13/14] font: Assign null_font to glyphs in ascii_font_glyph[]
The calculations in blit_comb() need information from glyph's font, e.g.
grub_font_get_xheight(main_glyph->font). However, main_glyph->font is
NULL if main_glyph comes from ascii_font_glyph[]. Therefore
grub_font_get_*() crashes because of NULL pointer.
There is already a solution, the null_font. So, assign it to those glyphs
in ascii_font_glyph[].
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index cf15dc2f9..3821937e6 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code)
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
- ascii_font_glyph[current]->font = NULL;
+ ascii_font_glyph[current]->font = &null_font;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
--
2.30.2

View File

@@ -0,0 +1,55 @@
From da90d62316a3b105d2fbd7334d6521936bd6dcf6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 28 Oct 2022 21:31:39 +0800
Subject: [PATCH 14/14] normal/charset: Fix an integer overflow in
grub_unicode_aglomerate_comb()
The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255.
However, code in grub_unicode_aglomerate_comb() doesn't check for an
overflow when incrementing out->ncomb. If out->ncomb is already 255,
after incrementing it will get 0 instead of 256, and cause illegal
memory access in subsequent processing.
This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max
acceptable value of ncomb. The code now checks for this limit and
ignores additional combining characters when limit is reached.
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/normal/charset.c | 3 +++
include/grub/unicode.h | 2 ++
2 files changed, 5 insertions(+)
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
index 000e687bd..4f6647116 100644
--- a/grub-core/normal/charset.c
+++ b/grub-core/normal/charset.c
@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
if (!haveout)
continue;
+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX)
+ continue;
+
if (comb_type == GRUB_UNICODE_COMB_MC
|| comb_type == GRUB_UNICODE_COMB_ME
|| comb_type == GRUB_UNICODE_COMB_MN)
diff --git a/include/grub/unicode.h b/include/grub/unicode.h
index 71a4d1a54..9360b0b97 100644
--- a/include/grub/unicode.h
+++ b/include/grub/unicode.h
@@ -147,7 +147,9 @@ struct grub_unicode_glyph
grub_uint8_t bidi_level:6; /* minimum: 6 */
enum grub_bidi_type bidi_type:5; /* minimum: :5 */
+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1)
unsigned ncomb:8;
+
/* Hint by unicode subsystem how wide this character usually is.
Real width is determined by font. Set only in UTF-8 stream. */
int estimated_width:8;
--
2.30.2

View File

@@ -0,0 +1,171 @@
From 157486f818ecbe26b7962f5795a8f48393ba5169 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 18:51:35 +1000
Subject: [PATCH 1/6] video/readers/png: Drop greyscale support to fix heap
out-of-bounds write
A 16-bit greyscale PNG without alpha is processed in the following loop:
for (i = 0; i < (data->image_width * data->image_height);
i++, d1 += 4, d2 += 2)
{
d1[R3] = d2[1];
d1[G3] = d2[1];
d1[B3] = d2[1];
}
The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
but there are only 3 bytes allocated for storage. This means that image
data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
out of every 4 following the end of the image.
This has existed since greyscale support was added in 2013 in commit
3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
and attempting to load it causes grub-emu to crash - I don't think this code
has ever worked.
Delete all PNG greyscale support.
Fixes: CVE-2021-3695
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 87 +++--------------------------------
1 file changed, 7 insertions(+), 80 deletions(-)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 4827b9c..1e35eae 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -100,7 +100,7 @@ struct grub_png_data
unsigned image_width, image_height;
int bpp, is_16bit;
- int raw_bytes, is_gray, is_alpha, is_palette;
+ int raw_bytes, is_alpha, is_palette;
int row_bytes, color_bits;
grub_uint8_t *image_data;
@@ -284,13 +284,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->bpp = 3;
else
{
- data->is_gray = 1;
- data->bpp = 1;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: color type not supported");
}
if ((color_bits != 8) && (color_bits != 16)
&& (color_bits != 4
- || !(data->is_gray || data->is_palette)))
+ || !data->is_palette))
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"png: bit depth must be 8 or 16");
@@ -319,7 +319,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
}
#ifndef GRUB_CPU_WORDS_BIGENDIAN
- if (data->is_16bit || data->is_gray || data->is_palette)
+ if (data->is_16bit || data->is_palette)
#endif
{
data->image_data = grub_calloc (data->image_height, data->row_bytes);
@@ -863,27 +863,8 @@ grub_png_convert_image (struct grub_png_data *data)
int shift;
int mask = (1 << data->color_bits) - 1;
unsigned j;
- if (data->is_gray)
- {
- /* Generic formula is
- (0xff * i) / ((1U << data->color_bits) - 1)
- but for allowed bit depth of 1, 2 and for it's
- equivalent to
- (0xff / ((1U << data->color_bits) - 1)) * i
- Precompute the multipliers to avoid division.
- */
-
- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
- for (i = 0; i < (1U << data->color_bits); i++)
- {
- grub_uint8_t col = multipliers[data->color_bits] * i;
- palette[i][0] = col;
- palette[i][1] = col;
- palette[i][2] = col;
- }
- }
- else
- grub_memcpy (palette, data->palette, 3 << data->color_bits);
+
+ grub_memcpy (palette, data->palette, 3 << data->color_bits);
d1c = d1;
d2c = d2;
for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
@@ -920,60 +901,6 @@ grub_png_convert_image (struct grub_png_data *data)
}
return;
}
-
- if (data->is_gray)
- {
- switch (data->bpp)
- {
- case 4:
- /* 16-bit gray with alpha. */
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 4)
- {
- d1[R4] = d2[3];
- d1[G4] = d2[3];
- d1[B4] = d2[3];
- d1[A4] = d2[1];
- }
- break;
- case 2:
- if (data->is_16bit)
- /* 16-bit gray without alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R3] = d2[1];
- d1[G3] = d2[1];
- d1[B3] = d2[1];
- }
- }
- else
- /* 8-bit gray with alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R4] = d2[1];
- d1[G4] = d2[1];
- d1[B4] = d2[1];
- d1[A4] = d2[0];
- }
- }
- break;
- /* 8-bit gray without alpha. */
- case 1:
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 3, d2++)
- {
- d1[R3] = d2[0];
- d1[G3] = d2[0];
- d1[B3] = d2[0];
- }
- break;
- }
- return;
- }
{
/* Only copy the upper 8 bit. */
--
2.17.1

View File

@@ -0,0 +1,42 @@
From b54f7505732ad5c6237a133c0a1cf00774f13508 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 23:25:07 +1000
Subject: [PATCH 2/6] video/readers/png: Avoid heap OOB R/W inserting huff
table items
In fuzzing we observed crashes where a code would attempt to be inserted
into a huffman table before the start, leading to a set of heap OOB reads
and writes as table entries with negative indices were shifted around and
the new code written in.
Catch the case where we would underflow the array and bail.
Fixes: CVE-2021-3696
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 1e35eae..0356f91 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -420,6 +420,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
for (i = len; i < ht->max_length; i++)
n += ht->maxval[i];
+ if (n > ht->num_values)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: out of range inserting huffman table item");
+ return;
+ }
+
for (i = 0; i < n; i++)
ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
--
2.17.1

View File

@@ -0,0 +1,79 @@
From a10c2350a766f9b315735931a49499a7e2c77bf3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 4 Sep 2023 16:32:43 +0800
Subject: [PATCH 3/6] video/readers/jpeg: Block int underflow -> wild pointer
write
Certain 1 px wide images caused a wild pointer write in
grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
we have the following loop:
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
We did not check if vb * width >= hb * nc1.
On a 64-bit platform, if that turns out to be negative, it will underflow,
be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
we see data->bitmap_ptr jump, e.g.:
0x6180_0000_0480 to
0x6181_0000_0498
^
~--- carry has occurred and this pointer is now far away from
any object.
On a 32-bit platform, it will decrement the pointer, creating a pointer
that won't crash but will overwrite random data.
Catch the underflow and error out.
Fixes: CVE-2021-3697
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
[lz: Adapt the patch for context changes]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/video/readers/jpeg.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 0eeea0e..fdaef18 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.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+");
@@ -643,6 +644,7 @@ static grub_err_t
grub_jpeg_decode_data (struct grub_jpeg_data *data)
{
unsigned c1, vb, hb, nr1, nc1;
+ unsigned stride_a, stride_b, stride;
int rst = data->dri;
vb = 8 << data->log_vs;
@@ -654,8 +656,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
return grub_error(GRUB_ERR_BAD_FILE_TYPE,
"jpeg: attempted to decode data before start of stream");
+ if (grub_mul(vb, data->image_width, &stride_a) ||
+ grub_mul(hb, nc1, &stride_b) ||
+ grub_sub(stride_a, stride_b, &stride))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: cannot decode image with these dimensions");
+
for (; data->r1 < nr1 && (!data->dri || rst);
- data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+ data->r1++, data->bitmap_ptr += stride * 3)
for (c1 = 0; c1 < nc1 && (!data->dri || rst);
c1++, rst--, data->bitmap_ptr += hb * 3)
{
--
2.17.1

View File

@@ -0,0 +1,46 @@
From 5d2f1e350e39677938a70c17a163f1a9cde36a18 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 20 Dec 2021 19:41:21 +1100
Subject: [PATCH 4/6] net/ip: Do IP fragment maths safely
This avoids an underflow and subsequent unpleasantness.
Fixes: CVE-2022-28733
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/ip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index ea5edf8..74e4e8b 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -25,6 +25,7 @@
#include <grub/net/netbuff.h>
#include <grub/mm.h>
#include <grub/priority_queue.h>
+#include <grub/safemath.h>
#include <grub/time.h>
struct iphdr {
@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
{
rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
+ (nb->tail - nb->data));
- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
+
+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
+ &rsm->total_len))
+ {
+ grub_dprintf ("net", "IP reassembly size underflow\n");
+ return GRUB_ERR_NONE;
+ }
+
rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
if (!rsm->asm_netbuff)
{
--
2.17.1

View File

@@ -0,0 +1,48 @@
From f37943427c5bf16a0003d3049221da698006f6f3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 18:17:03 +1100
Subject: [PATCH 5/6] net/http: Fix OOB write for split http headers
GRUB has special code for handling an http header that is split
across two packets.
The code tracks the end of line by looking for a "\n" byte. The
code for split headers has always advanced the pointer just past the
end of the line, whereas the code that handles unsplit headers does
not advance the pointer. This extra advance causes the length to be
one greater, which breaks an assumption in parse_line(), leading to
it writing a NUL byte one byte past the end of the buffer where we
reconstruct the line from the two packets.
It's conceivable that an attacker controlled set of packets could
cause this to zero out the first byte of the "next" pointer of the
grub_mm_region structure following the current_line buffer.
Do not advance the pointer in the split header case.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index b616cf4..a19b0a2 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -190,9 +190,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
int have_line = 1;
char *t;
ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
- if (ptr)
- ptr++;
- else
+ if (ptr == NULL)
{
have_line = 0;
ptr = (char *) nb->tail;
--
2.17.1

View File

@@ -0,0 +1,50 @@
From c96929e9eea455b07e0c2e06bc401eea6bf2be11 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 19:04:40 +1100
Subject: [PATCH 6/6] net/http: Error out on headers with LF without CR
In a similar vein to the previous patch, parse_line() would write
a NUL byte past the end of the buffer if there was an HTTP header
with a LF rather than a CRLF.
RFC-2616 says:
Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value (as defined in section 3.6).
We don't support quoted sections or continuation lines, etc.
If we see an LF that's not part of a CRLF, bail out.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index a19b0a2..1fa62b5 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
char *end = ptr + len;
while (end > ptr && *(end - 1) == '\r')
end--;
+
+ /* LF without CR. */
+ if (end == ptr + len)
+ {
+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
+ return GRUB_ERR_NONE;
+ }
*end = 0;
+
/* Trailing CRLF. */
if (data->in_chunk_len == 1)
{
--
2.17.1

View File

@@ -0,0 +1,129 @@
From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:02:04 +0100
Subject: [PATCH] loader/efi/chainloader: Simplify the loader state
The chainloader command retains the source buffer and device path passed
to LoadImage(), requiring the unload hook passed to grub_loader_set() to
free them. It isn't required to retain this state though - they aren't
required by StartImage() or anything else in the boot hook, so clean them
up before grub_cmd_chainloader() finishes.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2bd80f4db..d1602c89b 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,25 +44,20 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_physical_address_t address;
-static grub_efi_uintn_t pages;
-static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
static grub_err_t
grub_chainloader_unload (void)
{
+ grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
+ loaded_image = grub_efi_get_loaded_image (image_handle);
+ if (loaded_image != NULL)
+ grub_free (loaded_image->load_options);
+
b = grub_efi_system_table->boot_services;
efi_call_1 (b->unload_image, image_handle);
- efi_call_2 (b->free_pages, address, pages);
-
- grub_free (file_path);
- grub_free (cmdline);
- cmdline = 0;
- file_path = 0;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -140,7 +135,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
char *dir_start;
char *dir_end;
grub_size_t size;
- grub_efi_device_path_t *d;
+ grub_efi_device_path_t *d, *file_path;
dir_start = grub_strchr (filename, ')');
if (! dir_start)
@@ -222,11 +217,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_device_t dev = 0;
- grub_efi_device_path_t *dp = 0;
+ grub_efi_device_path_t *dp = NULL, *file_path = NULL;
grub_efi_loaded_image_t *loaded_image;
char *filename;
void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
+ grub_efi_physical_address_t address = 0;
+ grub_efi_uintn_t pages = 0;
+ grub_efi_char16_t *cmdline = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -234,11 +232,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_dl_ref (my_mod);
- /* Initialize some global variables. */
- address = 0;
- image_handle = 0;
- file_path = 0;
-
b = grub_efi_system_table->boot_services;
file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_file_close (file);
grub_device_close (dev);
+ /* We're finished with the source image buffer and file path now. */
+ efi_call_2 (b->free_pages, address, pages);
+ grub_free (file_path);
+
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
return 0;
@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (file)
grub_file_close (file);
+ grub_free (cmdline);
grub_free (file_path);
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (image_handle != NULL)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ image_handle = NULL;
+ }
+
grub_dl_unref (my_mod);
return grub_errno;
--
2.34.1

View File

@@ -0,0 +1,168 @@
From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:58:28 +0100
Subject: [PATCH] commands/boot: Add API to pass context to loader
Loaders rely on global variables for saving context which is consumed
in the boot hook and freed in the unload hook. In the case where a loader
command is executed twice, calling grub_loader_set() a second time executes
the unload hook, but in some cases this runs when the loader's global
context has already been updated, resulting in the updated context being
freed and potential use-after-free bugs when the boot hook is subsequently
called.
This adds a new API, grub_loader_set_ex(), which allows a loader to specify
context that is passed to its boot and unload hooks. This is an alternative
to requiring that loaders call grub_loader_unset() before mutating their
global context.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/commands/boot.c | 66 ++++++++++++++++++++++++++++++++++-----
include/grub/loader.h | 5 +++
2 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
index bbca81e94..61514788e 100644
--- a/grub-core/commands/boot.c
+++ b/grub-core/commands/boot.c
@@ -27,10 +27,20 @@
GRUB_MOD_LICENSE ("GPLv3+");
-static grub_err_t (*grub_loader_boot_func) (void);
-static grub_err_t (*grub_loader_unload_func) (void);
+static grub_err_t (*grub_loader_boot_func) (void *context);
+static grub_err_t (*grub_loader_unload_func) (void *context);
+static void *grub_loader_context;
static int grub_loader_flags;
+struct grub_simple_loader_hooks
+{
+ grub_err_t (*boot) (void);
+ grub_err_t (*unload) (void);
+};
+
+/* Don't heap allocate this to avoid making grub_loader_set() fallible. */
+static struct grub_simple_loader_hooks simple_loader_hooks;
+
struct grub_preboot
{
grub_err_t (*preboot_func) (int);
@@ -44,6 +54,29 @@ static int grub_loader_loaded;
static struct grub_preboot *preboots_head = 0,
*preboots_tail = 0;
+static grub_err_t
+grub_simple_boot_hook (void *context)
+{
+ struct grub_simple_loader_hooks *hooks;
+
+ hooks = (struct grub_simple_loader_hooks *) context;
+ return hooks->boot ();
+}
+
+static grub_err_t
+grub_simple_unload_hook (void *context)
+{
+ struct grub_simple_loader_hooks *hooks;
+ grub_err_t ret;
+
+ hooks = (struct grub_simple_loader_hooks *) context;
+
+ ret = hooks->unload ();
+ grub_memset (hooks, 0, sizeof (*hooks));
+
+ return ret;
+}
+
int
grub_loader_is_loaded (void)
{
@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
}
void
-grub_loader_set (grub_err_t (*boot) (void),
- grub_err_t (*unload) (void),
- int flags)
+grub_loader_set_ex (grub_err_t (*boot) (void *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags)
{
if (grub_loader_loaded && grub_loader_unload_func)
- grub_loader_unload_func ();
+ grub_loader_unload_func (grub_loader_context);
grub_loader_boot_func = boot;
grub_loader_unload_func = unload;
+ grub_loader_context = context;
grub_loader_flags = flags;
grub_loader_loaded = 1;
}
+void
+grub_loader_set (grub_err_t (*boot) (void),
+ grub_err_t (*unload) (void),
+ int flags)
+{
+ grub_loader_set_ex (grub_simple_boot_hook,
+ grub_simple_unload_hook,
+ &simple_loader_hooks,
+ flags);
+
+ simple_loader_hooks.boot = boot;
+ simple_loader_hooks.unload = unload;
+}
+
void
grub_loader_unset(void)
{
if (grub_loader_loaded && grub_loader_unload_func)
- grub_loader_unload_func ();
+ grub_loader_unload_func (grub_loader_context);
grub_loader_boot_func = 0;
grub_loader_unload_func = 0;
+ grub_loader_context = 0;
grub_loader_loaded = 0;
}
@@ -158,7 +208,7 @@ grub_loader_boot (void)
return err;
}
}
- err = (grub_loader_boot_func) ();
+ err = (grub_loader_boot_func) (grub_loader_context);
for (cur = preboots_tail; cur; cur = cur->prev)
if (! err)
diff --git a/include/grub/loader.h b/include/grub/loader.h
index b20864282..97f231054 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
grub_err_t (*unload) (void),
int flags);
+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags);
+
/* Unset current loader, if any. */
void EXPORT_FUNC (grub_loader_unset) (void);
--
2.34.1

View File

@@ -0,0 +1,86 @@
From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 11:48:58 +0100
Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex()
This ports the EFI chainloader to use grub_loader_set_ex() in order to fix
a use-after-free bug that occurs when grub_cmd_chainloader() is executed
more than once before a boot attempt is performed.
Fixes: CVE-2022-28736
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
CVE: CVE-2022-28736
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index d1602c89b..7557eb269 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_handle_t image_handle;
-
static grub_err_t
-grub_chainloader_unload (void)
+grub_chainloader_unload (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
@@ -64,8 +63,9 @@ grub_chainloader_unload (void)
}
static grub_err_t
-grub_chainloader_boot (void)
+grub_chainloader_boot (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
@@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_physical_address_t address = 0;
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
+ grub_efi_handle_t image_handle = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -405,7 +406,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
grub_free (file_path);
- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
return 0;
fail:
@@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
if (image_handle != NULL)
- {
- efi_call_1 (b->unload_image, image_handle);
- image_handle = NULL;
- }
+ efi_call_1 (b->unload_image, image_handle);
grub_dl_unref (my_mod);
--
2.34.1

View File

@@ -0,0 +1,89 @@
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:31:57 +0300
Subject: fs/ntfs: Fix an OOB write when parsing the $ATTRIBUTE_LIST attribute
for the $MFT file
When parsing an extremely fragmented $MFT file, i.e., the file described
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
containing bytes read from the underlying drive to store sector numbers,
which are consumed later to read data from these sectors into another buffer.
These sectors numbers, two 32-bit integers, are always stored at predefined
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
However, when parsing a specially-crafted file system image, this may cause
the NTFS code to write these integers beyond the buffer boundary, likely
causing the GRUB memory allocator to misbehave or fail. These integers contain
values which are controlled by on-disk structures of the NTFS file system.
Such modification and resulting misbehavior may touch a memory range not
assigned to the GRUB and owned by firmware or another EFI application/driver.
This fix introduces checks to ensure that these sector numbers are never
written beyond the boundary.
Fixes: CVE-2023-4692
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index bbdbe24..c3c4db1 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
if (at->attr_end)
{
- grub_uint8_t *pa;
+ grub_uint8_t *pa, *pa_end;
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
if (at->emft_buf == NULL)
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
at->attr_nxt = at->edat_buf;
at->attr_end = at->edat_buf + u32at (pa, 0x30);
+ pa_end = at->edat_buf + n;
}
else
{
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
at->attr_end = at->attr_end + u32at (pa, 4);
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
}
at->flags |= GRUB_NTFS_AF_ALST;
while (at->attr_nxt < at->attr_end)
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
at->flags |= GRUB_NTFS_AF_GPOS;
at->attr_cur = at->attr_nxt;
pa = at->attr_cur;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
grub_set_unaligned32 ((char *) pa + 0x10,
grub_cpu_to_le32 (at->mft->data->mft_start));
grub_set_unaligned32 ((char *) pa + 0x14,
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
{
if (*pa != attr)
break;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
if (read_attr
(at, pa + 0x10,
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),

View File

@@ -0,0 +1,54 @@
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:32:33 +0300
Subject: fs/ntfs: Fix an OOB read when reading data from the resident $DATA
attribute
When reading a file containing resident data, i.e., the file data is stored in
the $DATA attribute within the NTFS file record, not in external clusters,
there are no checks that this resident data actually fits the corresponding
file record segment.
When parsing a specially-crafted file system image, the current NTFS code will
read the file data from an arbitrary, attacker-chosen memory offset and of
arbitrary, attacker-chosen length.
This allows an attacker to display arbitrary chunks of memory, which could
contain sensitive information like password hashes or even plain-text,
obfuscated passwords from BS EFI variables.
This fix implements a check to ensure that resident data is read from the
corresponding file record segment only.
Fixes: CVE-2023-4693
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index c3c4db1..a68e173 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
{
if (ofs + len > u32at (pa, 0x10))
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
+
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
+
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
return 0;
}

View File

@@ -0,0 +1,153 @@
From d8d9c3ce2441be42fc65d2bde5d0fb299de39ad0 Mon Sep 17 00:00:00 2001
From: Jiang Lu <lu.jiang@windriver.com>
Date: Thu, 31 Jan 2019 15:27:03 +0800
Subject: [PATCH] Make UEFI watchdog behaviour configurable
Starting with d9a0c9413e81d3c0affc6383693bdd28dc863a5c, GRUB unconditionally
disables watchdog on EFI platforms. This opens up a window (starting at GRUB's
grub_efi_init(), until OS re-enables it) when EFI system operates w/o watchdog.
If an EFI system gets stuck in that window, the chipset will never reset the
system.
Create a command line interface to enable/disable watchdog:
efi-watchdog (enable|disable) <code> <timeout>
Signed-off-by: Jiang Lu <lu.jiang@windriver.com>
Rebase for grub 2.06
Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
---
docs/grub.texi | 11 +++++++
grub-core/kern/efi/init.c | 68 +++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/docs/grub.texi b/docs/grub.texi
index f8b4b3b..95e8367 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3991,6 +3991,7 @@ you forget a command, you can run the command @command{help}
* distrust:: Remove a pubkey from trusted keys
* drivemap:: Map a drive to another
* echo:: Display a line of text
+* efi-watchdog:: Manipulate EFI watchdog
* eval:: Evaluate agruments as GRUB commands
* export:: Export an environment variable
* false:: Do nothing, unsuccessfully
@@ -4442,6 +4443,16 @@ When interpreting backslash escapes, backslash followed by any other
character will print that character.
@end deffn
+@node efi-watchdog
+@subsection efi-watchdog
+
+@deffn Command efi-watchdog enable|disable <code> <timeout>
+Enable or disable the system's watchdog timer. Only available in EFI targeted
+GRUB.
+The <code> is logged upon watchdog timeout event. The UEFI BIOS reserves codes
+0x0000 to 0xFFFF.
+The <timeout> represents number of seconds to set the watchdog timeout to.
+@end deffn
@node eval
@subsection eval
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 7facacf..4a88397 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -28,6 +28,8 @@
#include <grub/mm.h>
#include <grub/kernel.h>
#include <grub/stack_protector.h>
+#include <grub/extcmd.h>
+#include <grub/command.h>
#ifdef GRUB_STACK_PROTECTOR
@@ -82,6 +84,68 @@ stack_protector_init (void)
grub_addr_t grub_modbase;
+static grub_command_t cmd_list;
+
+static grub_err_t
+grub_cmd_efi_watchdog (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ long input;
+ grub_efi_status_t status;
+ grub_efi_uintn_t timeout;
+ grub_efi_uint64_t code;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("usage: efi-watchdog (enable|disable) <code> <timeout>"));
+
+ if (grub_strcasecmp (args[0], "enable") == 0) {
+
+ if (argc != 3)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("usage: efi-watchdog enable <code> <timeout>"));
+
+ input = grub_strtol (args[1], 0, 0);
+
+ if (input >= 0) {
+ code = input;
+ } else {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("<code> must be non-negative"));
+ }
+
+ input = grub_strtol (args[2], 0, 0);
+
+ if (input >= 0) {
+ timeout = (grub_efi_uintn_t) input;
+ } else {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("<timeout> must be non-negative"));
+ }
+
+ } else if (grub_strcasecmp (args[0], "disable") == 0) {
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("usage: efi-watchdog disable"));
+ timeout = 0;
+ code = 0;
+
+ } else {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("usage: efi-watchdog (enable|disable) <code> <timeout>"));
+ }
+
+ status = efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
+ timeout, code, sizeof(L"GRUB"), L"GRUB");
+
+ if (status != GRUB_EFI_SUCCESS)
+ return grub_error (GRUB_ERR_BUG,
+ N_("Unexpected UEFI SetWatchdogTimer() error"));
+ else
+ return GRUB_ERR_NONE;
+}
+
void
grub_efi_init (void)
{
@@ -109,6 +173,9 @@ grub_efi_init (void)
0, 0, 0, NULL);
grub_efidisk_init ();
+
+ cmd_list = grub_register_command ("efi-watchdog", grub_cmd_efi_watchdog, 0,
+ N_("Enable/Disable system's watchdog timer."));
}
void (*grub_efi_net_config) (grub_efi_handle_t hnd,
@@ -146,4 +213,5 @@ grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_console_fini ();
+ grub_unregister_command (cmd_list);
}
--
2.17.1

View File

@@ -0,0 +1,45 @@
From fcab9daa2e62bcf2f6165fca4378d0e8a919a276 Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Sat, 19 Mar 2022 20:01:58 +0800
Subject: [PATCH] correct grub_errno
Correct grub_errno if allocate memory at preferred address success.
Usually allocate memory at preferred address will fail and then
allocate to another address. During second time allocate, it reset
grub_errno = GRUB_ERR_NONE.
While grub efi working on a server with huge memory, allocate memory at
preferred address will succeed, no need to allocate again, and no change
to correct grub_errno. It caused load kernel image fail in this
situation.
Set grub_errno = GRUB_ERR_NONE if first allocate success
Upstream-Status: Inappropriate [oe specific]
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
[lz: Adapt the git shortlog.]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/loader/i386/linux.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 9f74a96..747cfe0 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -179,6 +179,10 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align,
prot_size, 1,
GRUB_RELOCATOR_PREFERENCE_LOW,
1);
+
+ if (!err)
+ grub_errno = GRUB_ERR_NONE;
+
for (; err && *align + 1 > min_align; (*align)--)
{
grub_errno = GRUB_ERR_NONE;
--
2.17.1

View File

@@ -0,0 +1,98 @@
From 01120b5ec61ae7bbe550b1e2fe0f75c2d2073b1f Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Fri, 6 May 2022 15:44:14 +0800
Subject: [PATCH] grub verify: Add skip_check_cfg variable
While check_signatures enabled, with skip_check_cfg set to 1
- Do not verify the signature on the file that has suffix `.cfg'
- Do not authenticate user and password if cfg is changed
Implement function grub_strendswith to find cfg file
Upstream-Status: Pending
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
grub-core/commands/pgp.c | 12 ++++++++++++
grub-core/kern/misc.c | 12 ++++++++++++
grub-core/normal/auth.c | 5 +++++
include/grub/misc.h | 1 +
4 files changed, 30 insertions(+)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 5daa1e9..e60a29a 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -873,6 +873,18 @@ grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unuse
char *fsuf, *ptr;
grub_err_t err;
struct grub_pubkey_context *ctxt;
+ const char *val;
+
+ /* SKip to check the signature of cfg */
+ val = grub_env_get ("skip_check_cfg");
+ if (val && (val[0] == '1'))
+ {
+ if (grub_strendswith (io->name, ".cfg"))
+ {
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ }
+ }
if (!sec)
{
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index 3af336e..8bf1d90 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -280,6 +280,18 @@ grub_strncmp (const char *s1, const char *s2, grub_size_t n)
return (int) (grub_uint8_t) *s1 - (int) (grub_uint8_t) *s2;
}
+int
+grub_strendswith (const char *str, const char *suffix)
+{
+ if (!str || !suffix)
+ return 0;
+ grub_size_t lenstr = grub_strlen(str);
+ grub_size_t lensuffix = grub_strlen(suffix);
+ if (lensuffix > lenstr)
+ return 0;
+ return grub_strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
+}
+
char *
grub_strchr (const char *s, int c)
{
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
index 6be678c..57a1a42 100644
--- a/grub-core/normal/auth.c
+++ b/grub-core/normal/auth.c
@@ -136,6 +136,11 @@ is_authenticated (const char *userlist)
const char *superusers;
struct grub_auth_user *user;
+ /* SKip to authenticate grub cfg */
+ const char *val = grub_env_get ("skip_check_cfg");
+ if (val && (val[0] == '1'))
+ return 1;
+
superusers = grub_env_get ("superusers");
if (!superusers)
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 7d2b551..cce29d7 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -82,6 +82,7 @@ grub_memcpy (void *dest, const void *src, grub_size_t n)
int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
+int EXPORT_FUNC(grub_strendswith) (const char *str, const char *suffix);
char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
--
2.17.1

View File

@@ -0,0 +1,82 @@
From 3d9946f69f5ec17da747aa683ff7b5ccf9c31252 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:01:41 -0700
Subject: [PATCH] pe32.h: add header structures for TE and DOS executables
Upstream-Status: Inappropriate [embedded specific]
Add header structures to describe the Terse Executable format and
the DOS header format for executable images.
These definitions are needed in subsequent commits to parse and
verify the identity of the executable image when utilizing a shim
to boot LUV.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Add definitions of macros IMAGE_FILE_MACHINE_* which is involved by
0004-efi-chainloader-port-shim-to-grub.patch.
Signed-off-by: Kai Kang <kai.kang@windriver.com>
---
include/grub/efi/pe32.h | 46 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 0ed8781..de3a720 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -331,4 +331,50 @@ struct grub_pe32_reloc
#define GRUB_PE32_REL_I386_DIR32 0x6
#define GRUB_PE32_REL_I386_REL32 0x14
+//
+// PE32+ Machine type for EFI images
+//
+#define IMAGE_FILE_MACHINE_I386 0x014c
+#define IMAGE_FILE_MACHINE_IA64 0x0200
+#define IMAGE_FILE_MACHINE_EBC 0x0EBC
+#define IMAGE_FILE_MACHINE_X64 0x8664
+#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64
+
+struct grub_te_header
+{
+ grub_uint16_t signature;
+ grub_uint16_t machine;
+ grub_uint8_t num_sections;
+ grub_uint8_t subsystem;
+ grub_uint16_t stripped_size;
+ grub_uint32_t entry_point;
+ grub_uint32_t code_base;
+ grub_uint64_t image_base;
+ struct grub_pe32_data_directory data_directory[2];
+};
+
+struct grub_dos_header
+{
+ grub_uint16_t magic;
+ grub_uint16_t cblp;
+ grub_uint16_t cp;
+ grub_uint16_t crlc;
+ grub_uint16_t cparhdr;
+ grub_uint16_t minalloc;
+ grub_uint16_t maxalloc;
+ grub_uint16_t ss;
+ grub_uint16_t sp;
+ grub_uint16_t csum;
+ grub_uint16_t ip;
+ grub_uint16_t cs;
+ grub_uint16_t lfarlc;
+ grub_uint16_t ovno;
+ grub_uint16_t res[4];
+ grub_uint16_t oemid;
+ grub_uint16_t oeminfo;
+ grub_uint16_t res2[10];
+ grub_uint32_t lfanew;
+};
+
#endif /* ! GRUB_EFI_PE32_HEADER */
--
2.17.1

View File

@@ -0,0 +1,161 @@
From 1b807419bd99382cfeb9584ab7e8c10a0e416c5d Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:09:58 -0700
Subject: [PATCH] shim: add needed data structures
Upstream-Status: Inappropriate [embedded specific]
Add the needed data structures for shim to load, parse, relocate and
execute a binary. This includes file-parsing structures, an identifier for
the UEFI protocol for image verification under secure boot provided by shim.
Shim is thin loader developed by Matthew Garret
(https://github.com/rhinstaller/shim). This code was ported from such project.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
include/grub/efi/shim.h | 132 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)
create mode 100644 include/grub/efi/shim.h
diff --git a/include/grub/efi/shim.h b/include/grub/efi/shim.h
new file mode 100644
index 0000000..4b92a00
--- /dev/null
+++ b/include/grub/efi/shim.h
@@ -0,0 +1,132 @@
+/*
+ * shim.h - interface to shim: UEFI first-stage bootloader
+ *
+ * Copyright 2015 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Significant portions of this code are derived from Red Hat shim: UEFI
+ * first-stage bootloader.
+ * (https://github.com/rhinstaller/shim) and are Copyright 2012 Red Hat, Inc
+ */
+
+#ifndef GRUB_SHIM_HEADER
+#define GRUB_SHIM_HEADER 1
+
+#include <grub/efi/pe32.h>
+
+struct grub_nt_headers32
+{
+ grub_efi_uint32_t signature;
+ struct grub_pe32_coff_header file_hdr;
+ struct grub_pe32_optional_header opt_hdr;
+};
+
+struct grub_nt_headers64
+{
+ grub_efi_uint32_t signature;
+ struct grub_pe32_coff_header file_hdr;
+ struct grub_pe64_optional_header opt_hdr;
+};
+
+struct grub_image_base_relocation
+{
+ grub_efi_uint32_t virtual_address;
+ grub_efi_uint32_t block_size;
+};
+
+struct grub_shim_pe_coff_loader_image_context {
+ grub_efi_uint64_t image_address;
+ grub_efi_uint64_t image_size;
+ grub_efi_uint64_t entry_point;
+ grub_efi_uintn_t header_size;
+ grub_efi_uint16_t image_type;
+ grub_efi_uint16_t num_sections;
+ struct grub_pe32_section_table *first_section;
+ struct grub_pe32_data_directory *reloc_dir;
+ struct grub_pe32_data_directory *sec_dir;
+ grub_efi_uint64_t number_of_rva_and_sizes;
+ union grub_shim_optional_header_union *pe_hdr;
+};
+
+struct grub_shim_lock
+{
+ grub_efi_status_t
+ (*verify) (void *buffer,
+ grub_uint32_t size);
+
+ grub_efi_status_t
+ (*hash) (grub_int8_t *data,
+ grub_int32_t datasize,
+ struct grub_shim_pe_coff_loader_image_context *context,
+ grub_uint8_t sha256hash,
+ grub_uint8_t sha1hash);
+
+ grub_efi_status_t
+ (*context) (void *data,
+ grub_uint32_t datasize,
+ struct grub_shim_pe_coff_loader_image_context *context);
+};
+
+union grub_shim_optional_header_union
+{
+ struct grub_nt_headers32 pe32;
+ struct grub_nt_headers64 pe32plus;
+ struct grub_te_header te;
+};
+
+#define GRUB_EFI_SHIM_PROTOCOL_GUID \
+ { 0x605dab50, 0xe046, 0x4300, \
+ { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
+ }
+
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+
+#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z')
+#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0')
+
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) & ((Alignment) - 1)))
+#define ALIGN_POINTER(Pointer, Alignment) ((void *) (ALIGN_VALUE ((grub_efi_uintn_t)(Pointer), (Alignment))))
+
+/* Based relocation types. */
+
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
+#define EFI_IMAGE_REL_BASED_HIGH 1
+#define EFI_IMAGE_REL_BASED_LOW 2
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
+#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9
+#define EFI_IMAGE_REL_BASED_DIR64 10
+
+
+#endif /* ! GRUB_SHIM_HEADER */
--
2.17.1

View File

@@ -0,0 +1,83 @@
From a210b02b15d68bfe38651295f35edb1a21cef475 Mon Sep 17 00:00:00 2001
From: Matt Fleming <matt.fleming@intel.com>
Date: Fri, 27 Mar 2015 08:11:19 -0700
Subject: [PATCH] efi: chainloader: implement an UEFI Exit service
Upstream-Status: Inappropriate [embedded specific]
Implement an UEFI Exit service for shim in grub.
When exiting, grub will call the UEFI boot-time service Exit. The
effect of this is that UEFI will jump to the entry point of the
UEFI started image. If we execute an image using shim within grub,
shim takes care of loading/parsing/relocating/executing the image.
Under this scenario, we also need to take care of the Exit call. Thus,
we need to reimplement the function to make sure we perform a jump
to the instruction after which shim executed the image.
Once we have taken care of the exit of the shim-executed image
the system Exit call is restored.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
[lz: Adapt git shortlog.]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/kern/x86_64/efi/callwrap.S | 23 +++++++++++++++++++++++
include/grub/efi/api.h | 4 ++++
2 files changed, 27 insertions(+)
diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S
index 1337fd9..b849c2c 100644
--- a/grub-core/kern/x86_64/efi/callwrap.S
+++ b/grub-core/kern/x86_64/efi/callwrap.S
@@ -48,6 +48,26 @@ FUNCTION(efi_wrap_1)
addq $40, %rsp
ret
+FUNCTION(efi_call_foo)
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ movq %rsp, saved_sp(%rip)
+ subq $48, %rsp
+ mov %rsi, %rcx
+ call *%rdi
+
+FUNCTION(efi_shim_exit)
+ movq saved_sp(%rip), %rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ ret
+
FUNCTION(efi_wrap_2)
subq $40, %rsp
mov %rsi, %rcx
@@ -127,3 +147,6 @@ FUNCTION(efi_wrap_10)
call *%rdi
addq $88, %rsp
ret
+
+ .data
+saved_sp: .quad 0
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index f1a5221..de3bbbd 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1776,6 +1776,10 @@ typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func);
grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1);
+grub_efi_status_t EXPORT_FUNC(efi_shim_exit) (grub_efi_handle_t handle, grub_efi_status_t exit_status,
+ grub_efi_uintn_t exit_data_size, grub_efi_char16_t *exit_data) __attribute__((noreturn));
+grub_uint64_t EXPORT_FUNC(efi_call_foo) (void *func, grub_uint64_t arg1,
+ grub_uint64_t arg2);
grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1,
grub_uint64_t arg2);
grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1,
--
2.17.1

View File

@@ -0,0 +1,582 @@
From 061a1200d52bdfc6160cfad5fbe1cef125f8d3a2 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:19:21 -0700
Subject: [PATCH 4/7] efi: chainloader: port shim to grub
Upstream-Status: Inappropriate [embedded specific]
Shim is a thin loader to execute signed binaries under the
chain of trust of UEFI secure boot. Before executing the image,
shim verifies that such image is signed with any of the Machine
Owner Keys (MOKs). If the verification is successful, shim will
load, parse, relocate and execute the image.
Shim is useful in case the user does not want to modify the UEFI
database of valid certificates (DB).
This commit ports Matthew Garret's code from shim to grub in order
to provide to grub the capability of load and execute trusted
binaries. This is useful in case we need to chainload two bootloaders.
Shim can be found here: https://github.com/rhinstaller/shim
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 534 +++++++++++++++++++++++++++++
1 file changed, 534 insertions(+)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 7557eb2..74c84a7 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -32,6 +32,7 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
+#include <grub/efi/shim.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/net.h>
@@ -43,6 +44,539 @@
GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
+static grub_int32_t shim_used;
+static grub_efi_physical_address_t shim_buffer;
+static grub_efi_uintn_t shim_pages;
+static grub_efi_loaded_image_t shim_li_bak;
+static grub_efi_status_t (*shim_entry_point) (grub_efi_handle_t image_handle,
+ grub_efi_system_table_t *systab);
+
+static const grub_uint16_t
+grub_shim_machine_type =
+#if defined(__x86_64__)
+ GRUB_PE32_MACHINE_X86_64;
+#elif defined(__aarch64__)
+ IMAGE_FILE_MACHINE_ARM64;
+#elif defined(__arm__)
+ IMAGE_FILE_MACHINE_ARMTHUMB_MIXED;
+#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
+ GRUB_PE32_MACHINE_I386;
+#elif defined(__ia64__)
+ GRUB_PE32_MACHINE_IA64;
+#else
+#error this architecture is not supported by shim chainloader
+#endif
+
+static grub_efi_guid_t grub_shim_protocol_guid = GRUB_EFI_SHIM_PROTOCOL_GUID;
+
+static grub_int32_t
+grub_shim_allow_64_bit (void)
+{
+/* TODO: what is the definition for aarch64? */
+#if defined(__x86_64__)
+ return 1;
+#elif defined(__i386__) || defined(__i686__)
+/* TODO: find out what to do with in_protocol */
+ return 0;
+#else /* assuming everything else is 32-bit... */
+ return 0;
+#endif
+}
+
+static grub_int32_t
+grub_shim_allow_32_bit (void)
+{
+/* TODO: what is the definition for aarch64? */
+#if defined(__x86_64__)
+/* TODO: find out what to do with in_protocol */
+ return 0;
+#elif defined(__i386__) || defined(__i686__)
+ return 1;
+#else /* assuming everything else is 32-bit... */
+ return 1;
+#endif
+}
+
+static grub_int32_t
+grub_shim_image_is_64_bit (union grub_shim_optional_header_union *pe_hdr)
+{
+ /* .Magic is the same offset in all cases */
+ if (pe_hdr->pe32plus.opt_hdr.magic == GRUB_PE32_PE64_MAGIC)
+ return 1;
+ return 0;
+}
+
+static grub_int32_t
+grub_shim_image_is_loadable (union grub_shim_optional_header_union *pe_hdr)
+{
+ /* If the machine type doesn't match the binary, bail, unless
+ * we're in an allowed 64-on-32 scenario
+ */
+ if (pe_hdr->pe32.file_hdr.machine != grub_shim_machine_type)
+ {
+ if (!(grub_shim_machine_type == GRUB_PE32_MACHINE_I386
+ && pe_hdr->pe32.file_hdr.machine == GRUB_PE32_MACHINE_X86_64
+ && grub_shim_allow_64_bit ()))
+ return 0;
+ }
+
+ /* If it's not a header type we recognize at all, bail */
+ switch (pe_hdr->pe32plus.opt_hdr.magic)
+ {
+ case GRUB_PE32_PE64_MAGIC:
+ case GRUB_PE32_PE32_MAGIC:
+ break;
+ default:
+ return 0;
+ }
+
+ /* and now just check for general 64-vs-32 compatibility */
+ if (grub_shim_image_is_64_bit(pe_hdr))
+ {
+ if (grub_shim_allow_64_bit ())
+ return 1;
+ }
+ else
+ {
+ if (grub_shim_allow_32_bit ())
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Perform basic bounds checking of the intra-image pointers
+ */
+static grub_efi_uint64_t
+grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t addr)
+{
+ if (addr > size)
+ return 0;
+ return image + addr;
+}
+
+/*
+ * Perform the actual relocation
+ */
+static grub_err_t
+grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
+ void *orig, void *data)
+{
+ struct grub_image_base_relocation *reloc_base, *reloc_base_end;
+ grub_efi_uint64_t adjust;
+ grub_efi_uint16_t *reloc, *reloc_end;
+ grub_uint8_t *fixup, *fixup_base, *fixup_data = NULL;
+ grub_efi_uint16_t *fixup16;
+ grub_efi_uint32_t *fixup32;
+ grub_efi_uint64_t *fixup64;
+ grub_int32_t size = context->image_size;
+ void *image_end = (char *)orig + size;
+
+ if (grub_shim_image_is_64_bit(context->pe_hdr))
+ context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data;
+ else
+ context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data;
+
+ reloc_base = (struct grub_image_base_relocation *)
+ grub_shim_image_address ((grub_efi_uint64_t)orig, size,
+ context->reloc_dir->rva);
+ reloc_base_end = (struct grub_image_base_relocation *)
+ grub_shim_image_address ((grub_efi_uint64_t)orig, size,
+ context->reloc_dir->rva
+ + context->reloc_dir->size - 1);
+
+ if (!reloc_base || !reloc_base_end)
+ {
+ grub_printf("Reloc table overflows binary\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ adjust = (grub_efi_uintn_t)data - context->image_address;
+
+ if (adjust == 0)
+ return GRUB_EFI_SUCCESS;
+
+ while (reloc_base < reloc_base_end)
+ {
+ reloc = (grub_efi_uint16_t *) ((grub_int8_t *) reloc_base
+ + sizeof (struct grub_image_base_relocation));
+
+ if ((reloc_base->block_size == 0)
+ || (reloc_base->block_size > context->reloc_dir->size))
+ {
+ grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size);
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ reloc_end = (grub_efi_uint16_t *)
+ ((grub_uint8_t *) reloc_base + reloc_base->block_size);
+ if ((void *)reloc_end < orig || (void *)reloc_end > image_end)
+ {
+ grub_printf("Reloc entry overflows binary\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ fixup_base = (grub_uint8_t *)
+ grub_shim_image_address ((grub_efi_uint64_t)data,
+ size,
+ reloc_base->virtual_address);
+ if (!fixup_base)
+ {
+ grub_printf("Invalid fixup_base\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ while (reloc < reloc_end)
+ {
+ fixup = fixup_base + (*reloc & 0xFFF);
+ switch ((*reloc) >> 12)
+ {
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGH:
+ fixup16 = (grub_efi_uint16_t *) fixup;
+ *fixup16 = (grub_efi_uint16_t)
+ (*fixup16
+ + ((grub_efi_uint16_t) ((grub_efi_uint32_t) adjust >> 16)));
+ if (fixup_data != NULL)
+ {
+ *(grub_efi_uint16_t *) fixup_data = *fixup16;
+ fixup_data = fixup_data + sizeof (grub_efi_uint16_t);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_LOW:
+ fixup16 = (grub_efi_uint16_t *) fixup;
+ *fixup16 = (grub_efi_uint16_t)
+ (*fixup16 + (grub_efi_uint16_t) adjust);
+ if (fixup_data != NULL)
+ {
+ *(grub_efi_uint16_t *) fixup_data = *fixup16;
+ fixup_data = fixup_data + sizeof (grub_efi_uint16_t);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHLOW:
+ fixup32 = (grub_efi_uint32_t *) fixup;
+ *fixup32 = *fixup32 + (grub_efi_uint32_t) adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = ALIGN_POINTER (fixup_data, sizeof (grub_efi_uint32_t));
+ *(grub_efi_uint32_t *)fixup_data = *fixup32;
+ fixup_data = fixup_data + sizeof (grub_efi_uint32_t);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_DIR64:
+ fixup64 = (grub_efi_uint64_t *) fixup;
+ *fixup64 = *fixup64 + (grub_efi_uint64_t) adjust;
+ if (fixup_data != NULL)
+ {
+ fixup_data = ALIGN_POINTER (fixup_data, sizeof(grub_efi_uint64_t));
+ *(grub_efi_uint64_t *)(fixup_data) = *fixup64;
+ fixup_data = fixup_data + sizeof(grub_efi_uint64_t);
+ }
+ break;
+
+ default:
+ grub_printf("Unknown relocation\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+ reloc += 1;
+ }
+ reloc_base = (struct grub_image_base_relocation *) reloc_end;
+ }
+
+ return GRUB_EFI_SUCCESS;
+}
+
+/*
+ * Read the binary header and grab appropriate information from it
+ */
+static grub_err_t
+grub_shim_read_header(grub_efi_physical_address_t data, grub_uint32_t datasize,
+ struct grub_shim_pe_coff_loader_image_context *context)
+{
+ struct grub_dos_header *dos_hdr = (struct grub_dos_header *)data;
+ union grub_shim_optional_header_union *pe_hdr = (union grub_shim_optional_header_union *)data;
+ grub_uint64_t header_without_data_dir, section_header_offset, opt_hdr_size;
+
+ if (datasize < sizeof (pe_hdr->pe32))
+ {
+ grub_printf("Invalid image\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if (dos_hdr->magic == EFI_IMAGE_DOS_SIGNATURE)
+ pe_hdr = (union grub_shim_optional_header_union *)((grub_uint8_t *)data
+ + dos_hdr->lfanew);
+
+ if (!grub_shim_image_is_loadable(pe_hdr))
+ {
+ grub_printf("Platform does not support this image\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if (grub_shim_image_is_64_bit(pe_hdr))
+ {
+ context->number_of_rva_and_sizes = pe_hdr->pe32plus.opt_hdr.num_data_directories;
+ context->header_size = pe_hdr->pe32plus.opt_hdr.header_size;
+ context->image_size = pe_hdr->pe32plus.opt_hdr.image_size;
+ opt_hdr_size = sizeof(struct grub_pe64_optional_header);
+ } else
+ {
+ context->number_of_rva_and_sizes = pe_hdr->pe32.opt_hdr.num_data_directories;
+ context->header_size = pe_hdr->pe32.opt_hdr.header_size;
+ context->image_size = (grub_efi_uint64_t)pe_hdr->pe32.opt_hdr.header_size;
+ opt_hdr_size = sizeof(struct grub_pe32_optional_header);
+ }
+
+ context->num_sections = pe_hdr->pe32.file_hdr.num_sections;
+
+ if (GRUB_PE32_NUM_DATA_DIRECTORIES < context->number_of_rva_and_sizes)
+ {
+ grub_printf("Image header too small\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ header_without_data_dir = opt_hdr_size
+ - sizeof (struct grub_pe32_data_directory)
+ * GRUB_PE32_NUM_DATA_DIRECTORIES;
+ if (((grub_efi_uint32_t)pe_hdr->pe32.file_hdr.optional_header_size
+ - header_without_data_dir) !=
+ context->number_of_rva_and_sizes * sizeof (struct grub_pe32_data_directory))
+ {
+ grub_printf("Image header overflows data directory\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ section_header_offset = dos_hdr->lfanew
+ + sizeof (grub_efi_uint32_t)
+ + sizeof (struct grub_pe32_coff_header)
+ + pe_hdr->pe32.file_hdr.optional_header_size;
+ if (((grub_efi_uint32_t)context->image_size - section_header_offset)
+ / sizeof (struct grub_pe32_section_table)
+ <= context->num_sections)
+ {
+ grub_printf("Image sections overflow image size\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ if ((context->header_size - section_header_offset)
+ / sizeof (struct grub_pe32_section_table)
+ < (grub_efi_uint32_t)context->num_sections)
+ {
+ grub_printf("Image sections overflow section headers\n");
+ return GRUB_ERR_FILE_READ_ERROR;
+ }
+
+ if ((((grub_efi_uint8_t *)pe_hdr
+ - (grub_efi_uint8_t *)data)
+ + sizeof(union grub_shim_optional_header_union )) > datasize)
+ {
+ grub_printf("Invalid image\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if (pe_hdr->te.signature != EFI_IMAGE_NT_SIGNATURE)
+ {
+ grub_printf("Unsupported image type\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if (pe_hdr->pe32.file_hdr.characteristics & GRUB_PE32_RELOCS_STRIPPED)
+ {
+ grub_printf("Unsupported image - Relocations have been stripped\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ context->pe_hdr = pe_hdr;
+
+ if (grub_shim_image_is_64_bit(pe_hdr))
+ {
+ context->image_address = pe_hdr->pe32plus.opt_hdr.image_base;
+ context->entry_point = pe_hdr->pe32plus.opt_hdr.entry_addr;
+ context->reloc_dir = &pe_hdr->pe32plus.opt_hdr.base_relocation_table;
+ context->sec_dir = &pe_hdr->pe32plus.opt_hdr.certificate_table;
+ } else
+ {
+ context->image_address = pe_hdr->pe32.opt_hdr.image_base;
+ context->entry_point = pe_hdr->pe32.opt_hdr.entry_addr;
+ context->reloc_dir = &pe_hdr->pe32.opt_hdr.base_relocation_table;
+ context->sec_dir = &pe_hdr->pe32.opt_hdr.certificate_table;
+ }
+
+ context->first_section = (struct grub_pe32_section_table *)
+ ((char *)pe_hdr
+ + pe_hdr->pe32.file_hdr.optional_header_size
+ + sizeof(grub_efi_uint32_t)
+ + sizeof(struct grub_pe32_coff_header));
+
+ if (context->image_size < context->header_size)
+ {
+ grub_printf("Invalid image\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if ((unsigned long)((grub_efi_uint8_t *)context->sec_dir - (grub_efi_uint8_t *)data) >
+ (datasize - sizeof(struct grub_pe32_data_directory)))
+ {
+ grub_printf("Invalid image\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+
+ if (context->sec_dir->rva >= datasize)
+ {
+ grub_printf("Malformed security header\n");
+ return GRUB_ERR_BAD_FILE_TYPE;
+ }
+ return GRUB_ERR_NONE;
+}
+
+static grub_efi_status_t
+grub_shim_verify (grub_addr_t addr, grub_ssize_t size)
+{
+ struct grub_shim_lock *shim_lock;
+ shim_lock = grub_efi_locate_protocol (&grub_shim_protocol_guid, 0);
+ if (!shim_lock)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "could not load shim protocol");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ return shim_lock->verify((void *) addr, size);
+}
+
+static grub_err_t
+grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
+ struct grub_shim_pe_coff_loader_image_context *context)
+{
+ grub_err_t status;
+ grub_efi_status_t efi_status;
+ grub_uint32_t sect_size;
+ /* TODO: can they be unsigned? */
+ grub_int8_t *base, *end;
+ grub_int32_t i;
+ struct grub_pe32_section_table *section;
+ grub_efi_boot_services_t *b;
+
+ shim_used = 0;
+ shim_buffer = 0;
+
+ status = grub_shim_verify (addr, size);
+ if (status != GRUB_ERR_NONE)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "shim verification failed");
+ return GRUB_ERR_BAD_OS;
+ }
+
+ grub_memset(context, 0, sizeof(*context));
+ status = grub_shim_read_header (addr, size, context);
+ if (status != GRUB_ERR_NONE)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "read header failed");
+ return GRUB_ERR_BAD_OS;
+ }
+
+ /* TODO: do we need to do this with efi_allocate? */
+ shim_pages = (((grub_efi_uintn_t) context->image_size + ((1 << 12) - 1)) >> 12);
+
+ b = grub_efi_system_table->boot_services;
+ efi_status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
+ GRUB_EFI_LOADER_CODE, shim_pages, &shim_buffer);
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory for shim buffer"));
+ return GRUB_ERR_OUT_OF_MEMORY;
+ }
+
+ /* TODO: do we need the double cast? */
+ grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer),
+ (void *) ((grub_addr_t) addr), context->header_size);
+ /*
+ * Copy the executable's sections to their desired offsets
+ */
+ section = context->first_section;
+ for (i = 0; i < context->num_sections; i++, section++)
+ {
+ if (section->characteristics & 0x02000000)
+ /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */
+ continue;
+
+ sect_size = section->virtual_size;
+
+ if (sect_size > section->raw_data_size)
+ sect_size = section->raw_data_size;
+
+ base = (grub_int8_t *)
+ grub_shim_image_address (shim_buffer, context->image_size,
+ section->virtual_address);
+ end = (grub_int8_t *)
+ grub_shim_image_address (shim_buffer, context->image_size,
+ section->virtual_address
+ + sect_size - 1);
+ if (!base || !end)
+ {
+ grub_printf("Invalid section base\n");
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+
+ if (section->virtual_address < context->header_size
+ || section->raw_data_offset < context->header_size)
+ {
+ grub_printf("Section is inside image headers\n");
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+
+ if (section->raw_data_size > 0)
+ /* TODO: do we need the double cast? */
+ grub_memcpy ((void *)base,
+ (void *) (((grub_addr_t) addr)
+ + section->raw_data_offset), sect_size);
+
+ if (sect_size < section->virtual_size)
+ grub_memset ((void *)(base + sect_size), 0,
+ section->virtual_size - sect_size);
+ }
+
+ if (context->number_of_rva_and_sizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)
+ {
+ grub_printf("Image has no relocation entry\n");
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+
+ if (context->reloc_dir->size)
+ {
+ status = grub_shim_relocate_coff (context, (void *) addr,
+ (void *) shim_buffer);
+ if (status != GRUB_ERR_NONE)
+ {
+ grub_printf("Relocation failed: [%u]\n", status);
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+ }
+ shim_entry_point = (void *)grub_shim_image_address (shim_buffer,
+ context->image_size,
+ context->entry_point);
+ if (!shim_entry_point)
+ {
+ grub_printf("Invalid entry point\n");
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+
+ shim_used = 1;
+ return GRUB_ERR_NONE;
+fail:
+ efi_call_2 (b->free_pages, shim_buffer, shim_pages);
+ shim_buffer = 0;
+ return status;
+}
static grub_err_t
grub_chainloader_unload (void *context)
--
2.25.1

View File

@@ -0,0 +1,98 @@
From a99c7ea281b02f14abd0911886cabbea9fc81649 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:26:08 -0700
Subject: [PATCH 5/7] efi: chainloader: use shim to load and verify an image
Upstream-Status: Inappropriate [embedded specific]
The grub chainloader module uses the UEFI LoadImage service
to load a chainloaded binary. However, if such binary is not
signed by the UEFI certification authority, LoadImage will fail.
Under shim, we can use Machine-Owned Keys (MOKs) to verify an
image. Thus, in case LoadImage fails due to a security violation
we rely on the shim verification service. If successful, the
image is parsed and loaded.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 49 ++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 74c84a7..667b4c3 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -760,6 +760,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
grub_efi_handle_t image_handle = NULL;
+ struct grub_shim_pe_coff_loader_image_context context;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -886,23 +887,53 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
+ goto fail;
+ }
+ /* try with shim */
+ else if (status == GRUB_EFI_SECURITY_VIOLATION)
+ {
+ status = grub_shim_load_image (address, size, &context);
+ if (status != GRUB_EFI_SUCCESS)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "shim cannot load image");
+ goto fail;
+ }
+ }
else
- grub_error (GRUB_ERR_BAD_OS, "cannot load image");
-
- goto fail;
+ {
+ grub_error (GRUB_ERR_BAD_OS, "cannot load image");
+ goto fail;
+ }
}
- /* LoadImage does not set a device handler when the image is
- loaded from memory, so it is necessary to set it explicitly here.
- This is a mess. */
- loaded_image = grub_efi_get_loaded_image (image_handle);
+ /* if we use shim, the UEFI load_image failed, thus, we borrow
+ * grub_efi_image_handle and restore it later
+ */
+ if (shim_used)
+ /* if we use shim, the UEFI load_image failed, thus, we borrow
+ grub_efi_image_handle and restore it later */
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+ else
+ /* LoadImage does not set a device handler when the image is
+ loaded from memory, so it is necessary to set it explicitly here.
+ This is a mess. */
+ loaded_image = grub_efi_get_loaded_image (image_handle);
+
if (! loaded_image)
{
grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
goto fail;
}
- loaded_image->device_handle = dev_handle;
+ if (shim_used)
+ {
+ grub_memcpy(&shim_li_bak, loaded_image, sizeof(shim_li_bak));
+ loaded_image->image_base = (void *)shim_buffer;
+ loaded_image->image_size = context.image_size;
+ }
+ else
+ loaded_image->device_handle = dev_handle;
if (argc > 1)
{
--
2.25.1

View File

@@ -0,0 +1,63 @@
From 9645bb29a0ffb93c854cbeed175c62775ba38bb7 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:29:13 -0700
Subject: [PATCH] efi: chainloader: boot the image using shim
Upstream-Status: Inappropriate [embedded specific]
If the image was loaded using shim, boot the image. Given that
shim loaded the image, the UEFI firmware will not know where to
jump after the execution completes. Thus, replace the UEFI boot
service Exit with our own implementation to make sure we jump
to the instruction after the call to the entry point.
Replace the system Exit service when done.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 121af25..adaf3c9 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -609,9 +609,34 @@ grub_chainloader_boot (void)
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
grub_efi_char16_t *exit_data = NULL;
+ grub_efi_loaded_image_t *loaded_image = NULL;
+ grub_efi_status_t
+ (*saved_exit) (grub_efi_handle_t image_handle,
+ grub_efi_status_t exit_status,
+ grub_efi_uintn_t exit_data_size,
+ grub_efi_char16_t *exit_data) __attribute__((noreturn));
b = grub_efi_system_table->boot_services;
- status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
+
+ if (!shim_used)
+ status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
+ else
+ {
+ saved_exit = grub_efi_system_table->boot_services->exit;
+ grub_efi_system_table->boot_services->exit = efi_shim_exit;
+ status = efi_call_foo(shim_entry_point,
+ (grub_efi_uint64_t)grub_efi_image_handle,
+ (grub_efi_uint64_t)grub_efi_system_table);
+ grub_efi_system_table->boot_services->exit = saved_exit;
+
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
+ if (!loaded_image)
+ /* TODO: this is serious, what to do? */
+ grub_error (GRUB_ERR_BAD_OS, "GRUB loaded image not found");
+ else
+ /* restore loaded image */
+ grub_memcpy(loaded_image, &shim_li_bak, sizeof(shim_li_bak));
+ }
if (status != GRUB_EFI_SUCCESS)
{
if (exit_data)
--
2.17.1

View File

@@ -0,0 +1,41 @@
From c2b23e972b657cdb5e0794c93d342f167fffb3e3 Mon Sep 17 00:00:00 2001
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Date: Fri, 27 Mar 2015 08:31:27 -0700
Subject: [PATCH 7/7] efi: chainloader: take care of unload undershim
Upstream-Status: Inappropriate [embedded specific]
Under shim, we use a custom buffer to put the relocated image, make
sure we free that memory when unloading.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
grub-core/loader/efi/chainloader.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index baa85be..7b733a7 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -590,7 +590,17 @@ grub_chainloader_unload (void *context)
grub_free (loaded_image->load_options);
b = grub_efi_system_table->boot_services;
- efi_call_1 (b->unload_image, image_handle);
+ if (!shim_used)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ }
+ else
+ {
+ if (shim_buffer)
+ {
+ efi_call_2 (b->free_pages, shim_buffer, shim_pages);
+ }
+ }
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
--
2.25.1

View File

@@ -0,0 +1,32 @@
From d06de03facd9a330a2085450abeecb1b7e637f9c Mon Sep 17 00:00:00 2001
From: Lans Zhang <jia.zhang@windriver.com>
Date: Sun, 24 Apr 2016 12:58:10 +0800
Subject: [PATCH] chainloader: handle the unauthenticated image by shim
Upstream-Status: Pending
EFI_ACCESS_DENIED is another case whenever an unauthenticated image is loaded
by UEFI LoadImage() boot service. Shim verification protocol should handle
this case as EFI_SECURITY_VIOLATION.
Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
---
grub-core/loader/efi/chainloader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 285271d..9ff4faf 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -933,7 +933,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
/* try with shim */
- else if (status == GRUB_EFI_SECURITY_VIOLATION)
+ else if ((status == GRUB_EFI_ACCESS_DENIED) || (status == GRUB_EFI_SECURITY_VIOLATION))
{
status = grub_shim_load_image (address, size, &context);
if (status != GRUB_EFI_SUCCESS)
--
2.17.1

View File

@@ -0,0 +1,32 @@
From 5b7c30a1d5f6a30b60cbed7cedc516a27dba36d9 Mon Sep 17 00:00:00 2001
From: Lans Zhang <jia.zhang@windriver.com>
Date: Sun, 24 Apr 2016 15:56:38 +0800
Subject: [PATCH] chainloader: Don't check empty section in file like .bss
Upstream-Status: Pending
Because this kind of section always has a zeroed PointerToRawData denoting
the offset to file and a valid VirtualSize denoting the real size in the
memory.
Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
---
grub-core/loader/efi/chainloader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 9ff4faf..f736bee 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -530,7 +530,7 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
}
if (section->virtual_address < context->header_size
- || section->raw_data_offset < context->header_size)
+ || (section->raw_data_offset && section->raw_data_offset < context->header_size))
{
grub_printf("Section is inside image headers\n");
status = GRUB_ERR_BAD_FILE_TYPE;
--
2.17.1

View File

@@ -0,0 +1,223 @@
From 3df0895087be6affb95db4f42239bc0160c16bfa Mon Sep 17 00:00:00 2001
From: Lans Zhang <jia.zhang@windriver.com>
Date: Sun, 24 Apr 2016 19:02:28 +0800
Subject: [PATCH] chainloader: find the relocations correctly
Upstream-Status: Pending
Refer to a846aedd0e9dfe26ca6afaf6a1db8a54c20363c1 in shim.
Actually find the relocations correctly and process them that way
in chainloader.
Find the relocations based on the *file* address in the old binary,
because it's only the same as the virtual address some of the time.
Also perform some extra validation before processing it, and don't bail
out in /error/ if both reloc_base and reloc_base_end are null - that
condition is fine.
Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
[lz: Adapt git log and do some whitespaces cleanups.]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/loader/efi/chainloader.c | 97 +++++++++++++++++++++++++-----
1 file changed, 81 insertions(+), 16 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index f736bee..0979dc0 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -166,6 +166,7 @@ grub_shim_image_address (grub_addr_t image, grub_uint32_t size, grub_uint32_t ad
*/
static grub_err_t
grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
+ struct grub_pe32_section_table *section,
void *orig, void *data)
{
struct grub_image_base_relocation *reloc_base, *reloc_base_end;
@@ -177,19 +178,53 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
grub_efi_uint64_t *fixup64;
grub_int32_t size = context->image_size;
void *image_end = (char *)orig + size;
+ int n = 0;
if (grub_shim_image_is_64_bit(context->pe_hdr))
context->pe_hdr->pe32plus.opt_hdr.image_base = (grub_efi_uint64_t)(unsigned long)data;
else
context->pe_hdr->pe32.opt_hdr.image_base = (grub_efi_uint32_t)(unsigned long)data;
+
+ /* Alright, so here's how this works:
+ *
+ * context->RelocDir gives us two things:
+ * - the VA the table of base relocation blocks are (maybe) to be
+ * mapped at (RelocDir->VirtualAddress)
+ * - the virtual size (RelocDir->Size)
+ *
+ * The .reloc section (Section here) gives us some other things:
+ * - the name! kind of. (Section->Name)
+ * - the virtual size (Section->VirtualSize), which should be the same
+ * as RelocDir->Size
+ * - the virtual address (Section->VirtualAddress)
+ * - the file section size (Section->SizeOfRawData), which is
+ * a multiple of OptHdr->FileAlignment. Only useful for image
+ * validation, not really useful for iteration bounds.
+ * - the file address (Section->PointerToRawData)
+ * - a bunch of stuff we don't use that's 0 in our binaries usually
+ * - Flags (Section->Characteristics)
+ *
+ * and then the thing that's actually at the file address is an array
+ * of EFI_IMAGE_BASE_RELOCATION structs with some values packed behind
+ * them. The SizeOfBlock field of this structure includes the
+ * structure itself, and adding it to that structure's address will
+ * yield the next entry in the array.
+ */
reloc_base = (struct grub_image_base_relocation *)
grub_shim_image_address ((grub_efi_uint64_t)orig, size,
- context->reloc_dir->rva);
+ section->raw_data_offset);
+ /* reloc_base_end is the address of the first entry /past/ the
+ * table. */
reloc_base_end = (struct grub_image_base_relocation *)
grub_shim_image_address ((grub_efi_uint64_t)orig, size,
- context->reloc_dir->rva
- + context->reloc_dir->size - 1);
+ section->raw_data_offset
+ + section->virtual_size - 1);
+
+ if (!reloc_base && !reloc_base_end)
+ {
+ return GRUB_EFI_SUCCESS;
+ }
if (!reloc_base || !reloc_base_end)
{
@@ -210,7 +245,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
if ((reloc_base->block_size == 0)
|| (reloc_base->block_size > context->reloc_dir->size))
{
- grub_printf("Reloc block size %d is invalid\n", reloc_base->block_size);
+ grub_printf("Reloc %d block size %d is invalid\n", n, reloc_base->block_size);
return GRUB_ERR_FILE_READ_ERROR;
}
@@ -218,7 +253,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
((grub_uint8_t *) reloc_base + reloc_base->block_size);
if ((void *)reloc_end < orig || (void *)reloc_end > image_end)
{
- grub_printf("Reloc entry overflows binary\n");
+ grub_printf("Reloc %d entry overflows binary\n", n);
return GRUB_ERR_FILE_READ_ERROR;
}
@@ -228,7 +263,7 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
reloc_base->virtual_address);
if (!fixup_base)
{
- grub_printf("Invalid fixup_base\n");
+ grub_printf("Reloc %d invalid fixup_base\n", n);
return GRUB_ERR_FILE_READ_ERROR;
}
@@ -286,12 +321,13 @@ grub_shim_relocate_coff (struct grub_shim_pe_coff_loader_image_context *context,
break;
default:
- grub_printf("Unknown relocation\n");
+ grub_printf("Reloc %d unknown relocation\n", n);
return GRUB_ERR_FILE_READ_ERROR;
}
reloc += 1;
}
reloc_base = (struct grub_image_base_relocation *) reloc_end;
+ n++;
}
return GRUB_EFI_SUCCESS;
@@ -462,9 +498,9 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
grub_efi_status_t efi_status;
grub_uint32_t sect_size;
/* TODO: can they be unsigned? */
- grub_int8_t *base, *end;
+ grub_int8_t *base, *end, *reloc_base, *reloc_base_end;
grub_int32_t i;
- struct grub_pe32_section_table *section;
+ struct grub_pe32_section_table *section, *reloc_section;
grub_efi_boot_services_t *b;
shim_used = 0;
@@ -500,16 +536,21 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
/* TODO: do we need the double cast? */
grub_memcpy ((void *) ((grub_efi_physical_address_t) shim_buffer),
(void *) ((grub_addr_t) addr), context->header_size);
+
+ reloc_base = (grub_int8_t *) grub_shim_image_address (shim_buffer, size,
+ context->reloc_dir->rva);
+ /* reloc_base_end here is the address of the last byte of the table */
+ reloc_base_end = (grub_int8_t *) grub_shim_image_address (shim_buffer, size,
+ context->reloc_dir->rva +
+ context->reloc_dir->size - 1);
+ reloc_section = NULL;
+
/*
* Copy the executable's sections to their desired offsets
*/
section = context->first_section;
for (i = 0; i < context->num_sections; i++, section++)
{
- if (section->characteristics & 0x02000000)
- /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */
- continue;
-
sect_size = section->virtual_size;
if (sect_size > section->raw_data_size)
@@ -522,6 +563,30 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
grub_shim_image_address (shim_buffer, context->image_size,
section->virtual_address
+ sect_size - 1);
+
+ /* We do want to process .reloc, but it's often marked
+ * discardable, so we don't want to memcpy it. */
+ if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0) {
+ if (reloc_section) {
+ grub_printf("Image has multiple relocation sections\n");
+ status = GRUB_ERR_BAD_FILE_TYPE;
+ goto fail;
+ }
+ /* If it has nonzero sizes, and our bounds check
+ * made sense, and the VA and size match RelocDir's
+ * versions, then we believe in this section table. */
+ if (section->raw_data_size && section->virtual_size &&
+ base && end &&
+ reloc_base == base &&
+ reloc_base_end == end) {
+ reloc_section = section;
+ }
+ }
+
+ if (section->characteristics & 0x02000000)
+ /* section has EFI_IMAGE_SCN_MEM_DISCARDABLE attr set */
+ continue;
+
if (!base || !end)
{
grub_printf("Invalid section base\n");
@@ -555,10 +620,10 @@ grub_shim_load_image(grub_addr_t addr, grub_ssize_t size,
goto fail;
}
- if (context->reloc_dir->size)
+ if (context->reloc_dir->size && reloc_section)
{
- status = grub_shim_relocate_coff (context, (void *) addr,
- (void *) shim_buffer);
+ status = grub_shim_relocate_coff (context, reloc_section,
+ (void *) addr, (void *) shim_buffer);
if (status != GRUB_ERR_NONE)
{
grub_printf("Relocation failed: [%u]\n", status);
--
2.17.1

View File

@@ -0,0 +1,282 @@
From a9bccd374d23f67d2c3604f7c069be40ec996f9f Mon Sep 17 00:00:00 2001
From: Lans Zhang <jia.zhang@windriver.com>
Date: Thu, 22 Jun 2017 15:22:01 +0800
Subject: [PATCH] Add a module for reading EFI global variables
Add functions to read EFI global variables.
Signed-off-by: Lans Zhang <jia.zhang@windriver.com>
[lz: Add git log.]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/Makefile.core.def | 8 ++
grub-core/commands/efi/efivar.c | 238 ++++++++++++++++++++++++++++++++
2 files changed, 246 insertions(+)
create mode 100644 grub-core/commands/efi/efivar.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8022e1c..f8fad6e 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -761,6 +761,14 @@ module = {
enable = i386_multiboot;
};
+module = {
+ name = efivar;
+
+ common = commands/efi/efivar.c;
+
+ enable = efi;
+};
+
module = {
name = lsacpi;
diff --git a/grub-core/commands/efi/efivar.c b/grub-core/commands/efi/efivar.c
new file mode 100644
index 0000000..bb9aed3
--- /dev/null
+++ b/grub-core/commands/efi/efivar.c
@@ -0,0 +1,238 @@
+/* efivar.c - Read EFI global variables. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2015 Free Software Foundation, Inc.
+ * Copyright (C) 2015 CloudFlare, 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/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/extcmd.h>
+#include <grub/env.h>
+#include <grub/lib/hexdump.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const struct grub_arg_option options[] = {
+ {"format", 'f', GRUB_ARG_OPTION_OPTIONAL, N_("Parse EFI_VAR in specific format (hex, uint8, ascii, dump). Default: hex."), N_("FORMAT"), ARG_TYPE_STRING},
+ {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Save parsed result to environment variable (does not work with dump)."), N_("ENV_VAR"), ARG_TYPE_STRING},
+ {0, 0, 0, 0, 0, 0}
+};
+
+enum efi_var_type
+ {
+ EFI_VAR_ASCII = 0,
+ EFI_VAR_UINT8,
+ EFI_VAR_HEX,
+ EFI_VAR_DUMP,
+ EFI_VAR_INVALID = -1
+ };
+
+static enum efi_var_type
+parse_efi_var_type (const char *type)
+{
+ if (!grub_strncmp (type, "ascii", sizeof("ascii")))
+ return EFI_VAR_ASCII;
+
+ if (!grub_strncmp (type, "uint8", sizeof("uint8")))
+ return EFI_VAR_UINT8;
+
+ if (!grub_strncmp (type, "hex", sizeof("hex")))
+ return EFI_VAR_HEX;
+
+ if (!grub_strncmp (type, "dump", sizeof("dump")))
+ return EFI_VAR_DUMP;
+
+ return EFI_VAR_INVALID;
+}
+
+static int
+grub_print_ascii (char *str, char c)
+{
+ if (grub_iscntrl (c))
+ {
+ switch (c)
+ {
+ case '\0':
+ str[0] = '\\';
+ str[1] = '0';
+ return 2;
+
+ case '\a':
+ str[0] = '\\';
+ str[1] = 'a';
+ return 2;
+
+ case '\b':
+ str[0] = '\\';
+ str[1] = 'b';
+ return 2;
+
+ case '\f':
+ str[0] = '\\';
+ str[1] = 'f';
+ return 2;
+
+ case '\n':
+ str[0] = '\\';
+ str[1] = 'n';
+ return 2;
+
+ case '\r':
+ str[0] = '\\';
+ str[1] = 'r';
+ return 2;
+
+ case '\t':
+ str[0] = '\\';
+ str[1] = 't';
+ return 2;
+
+ case '\v':
+ str[0] = '\\';
+ str[1] = 'v';
+ return 2;
+
+ default:
+ str[0] = '.'; /* as in hexdump -C */
+ return 1;
+ }
+ }
+
+ str[0] = c;
+ return 1;
+}
+
+static grub_err_t
+grub_cmd_get_efi_var (struct grub_extcmd_context *ctxt,
+ int argc, char **args)
+{
+ struct grub_arg_list *state = ctxt->state;
+ grub_err_t status;
+ void *efi_var = NULL;
+ grub_size_t efi_var_size = 0;
+ enum efi_var_type efi_type = EFI_VAR_HEX;
+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
+ char *env_var = NULL;
+ grub_size_t i;
+ char *ptr;
+
+ if (1 != argc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ if (state[0].set)
+ efi_type = parse_efi_var_type (state[0].arg);
+
+ if (EFI_VAR_INVALID == efi_type)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid format specifier"));
+
+ grub_efi_get_variable (args[0], &global, &efi_var_size, &efi_var);
+ if (!efi_var || !efi_var_size)
+ {
+ status = grub_error (GRUB_ERR_READ_ERROR, N_("cannot read variable"));
+ goto err;
+ }
+
+ switch (efi_type)
+ {
+ case EFI_VAR_ASCII:
+ env_var = grub_malloc (efi_var_size * 2 + 1);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+
+ ptr = env_var;
+
+ for (i = 0; i < efi_var_size; i++)
+ ptr += grub_print_ascii (ptr, ((const char *)efi_var)[i]);
+ *ptr = '\0';
+ break;
+
+ case EFI_VAR_UINT8:
+ env_var = grub_malloc (4);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+ grub_snprintf (env_var, 4, "%u", *((grub_uint8_t *)efi_var));
+ break;
+
+ case EFI_VAR_HEX:
+ env_var = grub_malloc (efi_var_size * 2 + 1);
+ if (!env_var)
+ {
+ status = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+ break;
+ }
+ for (i = 0; i < efi_var_size; i++)
+ grub_snprintf (env_var + (i * 2), 3, "%02x", ((grub_uint8_t *)efi_var)[i]);
+ break;
+
+ case EFI_VAR_DUMP:
+ if (state[1].set)
+ status = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot set variable with dump format specifier"));
+ else
+ {
+ hexdump (0, (char *)efi_var, efi_var_size);
+ status = GRUB_ERR_NONE;
+ }
+ break;
+
+ default:
+ status = grub_error (GRUB_ERR_BUG, N_("should not happen (bug in module?)"));
+ }
+
+ if (efi_type != EFI_VAR_DUMP)
+ {
+ if (state[1].set)
+ status = grub_env_set (state[1].arg, env_var);
+ else
+ {
+ grub_printf ("%s\n", (const char *)env_var);
+ status = GRUB_ERR_NONE;
+ }
+ }
+
+err:
+
+ if (env_var)
+ grub_free (env_var);
+
+ if (efi_var)
+ grub_free (efi_var);
+
+ return status;
+}
+
+static grub_extcmd_t cmd = NULL;
+
+GRUB_MOD_INIT (efivar)
+{
+ cmd = grub_register_extcmd ("get_efivar", grub_cmd_get_efi_var, 0, N_("[-f FORMAT] [-s ENV_VAR] EFI_VAR"),
+ N_("Read EFI variable and print it or save its contents to environment variable."), options);
+}
+
+GRUB_MOD_FINI (efivar)
+{
+ if (cmd)
+ grub_unregister_extcmd (cmd);
+}
--
2.17.1

View File

@@ -0,0 +1,69 @@
From 038c21e7a7609340734d044482f24fee7f9f7a8f Mon Sep 17 00:00:00 2001
From: Jason Wessel <jason.wessel@windriver.com>
Date: Thu, 17 Oct 2019 12:35:01 -0700
Subject: [PATCH] grub shim verify: Report that the loaded object is verified
When check_signatures is set to enforcing, the signatures of the
loaded files have been checked, so the shim service should be informed
that it is ok to execute the loaded file.
Upstream-Status: Inappropriate
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
grub-core/loader/i386/linux.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 747cfe0..87469e7 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -21,6 +21,10 @@
#include <grub/normal.h>
#include <grub/file.h>
#include <grub/disk.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/disk.h>
+#include <grub/efi/shim.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/types.h>
@@ -647,6 +651,23 @@ grub_linux_unload (void)
return GRUB_ERR_NONE;
}
+static grub_efi_guid_t grub_shim_protocol_guid = GRUB_EFI_SHIM_PROTOCOL_GUID;
+
+static grub_efi_status_t
+grub_shim_verify (grub_addr_t addr, grub_ssize_t size)
+{
+ struct grub_shim_lock *shim_lock;
+ shim_lock = grub_efi_locate_protocol (&grub_shim_protocol_guid, 0);
+ if (!shim_lock)
+ {
+ grub_error (GRUB_ERR_BAD_OS, "could not load shim protocol");
+ return GRUB_EFI_UNSUPPORTED;
+ }
+
+ shim_lock->verify((void *) addr, size);
+ return GRUB_ERR_NONE;
+}
+
static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
@@ -680,6 +701,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
argv[0]);
goto fail;
}
+ const char *ge_val = grub_env_get ("check_signatures");
+ if (ge_val && (ge_val[0] == '1' || ge_val[0] == 'e'))
+ /* Verify was handled by .sig files, inform shim */
+ grub_shim_verify((grub_addr_t)&lh, sizeof(lh));
if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55))
{
--
2.17.1

View File

@@ -0,0 +1,111 @@
From aacf59cc01555c645e5594c0cdaa0e6735921e80 Mon Sep 17 00:00:00 2001
From: Jason Wessel <jason.wessel@windriver.com>
Date: Thu, 17 Oct 2019 12:35:01 -0700
Subject: [PATCH] grub verify: Add strict_security variable
With strict_security set to 1, it is impossible to change the value of
check_signatures. It will also cause grub to reboot instead of
allowing a rescue or grub shell, which could allow an end user to
alter boot arguments or load some other binary.
Upstream-Status: Pending
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
---
grub-core/commands/pgp.c | 16 +++++++++++++++-
grub-core/kern/main.c | 9 +++++++++
grub-core/normal/main.c | 7 +++++--
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index e60a29a..578ad18 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -864,6 +864,7 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
}
static int sec = 0;
+static int strict_sec = 0;
static grub_err_t
grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)),
@@ -930,10 +931,21 @@ static char *
grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
- sec = (*val == '1') || (*val == 'e');
+ if (!strict_sec)
+ sec = (*val == '1') || (*val == 'e');
return grub_strdup (sec ? "enforce" : "no");
}
+static char *
+grub_env_write_strict_sec (struct grub_env_var *var __attribute__ ((unused)),
+ const char *val)
+{
+ /* once it is set, it is a one way transition */
+ if (!strict_sec)
+ strict_sec = (*val == '1') || (*val == 'e');
+ return grub_strdup (strict_sec ? "enforce" : "no");
+}
+
static grub_ssize_t
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
{
@@ -973,7 +985,9 @@ GRUB_MOD_INIT(pgp)
sec = 0;
grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
+ grub_register_variable_hook ("strict_security", 0, grub_env_write_strict_sec);
grub_env_export ("check_signatures");
+ grub_env_export ("strict_security");
grub_pk_trusted = 0;
FOR_MODULES (header)
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 73967e2..86e7f35 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -30,6 +30,7 @@
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/verify.h>
+#include <grub/time.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/memory.h>
@@ -312,5 +313,13 @@ grub_main (void)
grub_boot_time ("After execution of embedded config. Attempt to go to normal mode");
grub_load_normal_mode ();
+ const char *val = grub_env_get ("strict_security");
+ if (val && (val[0] == '1' || val[0] == 'e'))
+ while (1) {
+ grub_printf("Boot configuration error - Attempting reboot\n");
+ grub_sleep(3);
+ grub_dl_load ("reboot");
+ grub_command_execute ("reboot", 0, 0);
+ }
grub_rescue_run ();
}
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index c4ebe9e..2c3f4f8 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -302,8 +302,11 @@ grub_enter_normal_mode (const char *config)
grub_boot_time ("Entering normal mode");
nested_level++;
grub_normal_execute (config, 0, 0);
- grub_boot_time ("Entering shell");
- grub_cmdline_run (0, 1);
+ const char *val = grub_env_get ("strict_security");
+ if (!(val && (val[0] == '1' || val[0] == 'e'))) {
+ grub_boot_time ("Entering shell");
+ grub_cmdline_run (0, 1);
+ }
nested_level--;
if (grub_normal_exit_level)
grub_normal_exit_level--;
--
2.17.1

View File

@@ -0,0 +1,48 @@
From 7ed6b7cbdc5f0721a7f6e89e601ad1b8c2cff267 Mon Sep 17 00:00:00 2001
From: Yi Zhao <yi.zhao@windriver.com>
Date: Wed, 7 Apr 2021 11:00:37 +0800
Subject: [PATCH] Disable inside lockdown and shim_lock verifiers
The lockdown support[1] and secure boot detection[2] have been added to
grub 2.06. These verifiers are registered when UEFI Secure Boot is
enabled. Unfortunately, they conflict with the current MOK2 Verify
mechanism. So disable them when enable SELoader.
Fixes grub error:
error: failed to verify kernel /bzImage
[1] http://git.savannah.gnu.org/cgit/grub.git/commit/?id=578c95298bcc46e0296f4c786db64c2ff26ce2cc
[2] http://git.savannah.gnu.org/cgit/grub.git/commit/?id=d7e54b2e5feee95d2f83058ed30d883c450d1473
Upstream-Status: Inappropriate [embedded specific]
Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
[lz: Adapt git log.]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/kern/efi/init.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 4a88397..e512a8e 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -159,6 +159,7 @@ grub_efi_init (void)
/* Initialize the memory management system. */
grub_efi_mm_init ();
+#if 0
/*
* Lockdown the GRUB and register the shim_lock verifier
* if the UEFI Secure Boot is enabled.
@@ -168,6 +169,7 @@ grub_efi_init (void)
grub_lockdown ();
grub_shim_lock_verifier_setup ();
}
+#endif
efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer,
0, 0, 0, NULL);
--
2.17.1

View File

@@ -0,0 +1,45 @@
0001-grub2-add-tboot.patch
0002-grub2-checking-if-loop-devices-are-available.patch
0020-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch
0021-video-readers-Add-artificial-limit-to-image-dimensio.patch
0022-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch
0023-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch
0024-font-Fix-several-integer-overflows-in-grub_font_cons.patch
0025-font-Remove-grub_font_dup_glyph.patch
0026-font-Fix-integer-overflow-in-ensure_comb_space.patch
0027-font-Fix-integer-overflow-in-BMP-index.patch
0028-font-Fix-integer-underflow-in-binary-search-of-char-.patch
0029-kern-efi-sb-Enforce-verification-of-font-files.patch
0030-fbutil-Fix-integer-overflow.patch
0031-font-Fix-an-integer-underflow-in-blit_comb.patch
0032-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch
0033-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
0034-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
0035-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
0036-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
0037-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
0038-net-ip-Do-IP-fragment-maths-safely.patch
0039-net-http-Fix-OOB-write-for-split-http-headers.patch
0040-net-http-Error-out-on-headers-with-LF-without-CR.patch
0041-loader-efi-chainloader-Simplify-the-loader-state.patch
0042-commands-boot-Add-API-to-pass-context-to-loader.patch
0043-loader-efi-chainloader-Use-grub_loader_set_ex.patch
0044-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
0045-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
lat/0003-Make-UEFI-watchdog-behaviour-configurable.patch
lat/0004-correct-grub_errno.patch
lat/0005-grub-verify-Add-skip_check_cfg-variable.patch
secure-core/0006-pe32.h-add-header-structures-for-TE-and-DOS-executab.patch
secure-core/0007-shim-add-needed-data-structures.patch
secure-core/0008-efi-chainloader-implement-an-UEFI-Exit-service.patch
secure-core/0009-efi-chainloader-port-shim-to-grub.patch
secure-core/0010-efi-chainloader-use-shim-to-load-and-verify-an-image.patch
secure-core/0011-efi-chainloader-boot-the-image-using-shim.patch
secure-core/0012-efi-chainloader-take-care-of-unload-undershim.patch
secure-core/0013-chainloader-handle-the-unauthenticated-image-by-shim.patch
secure-core/0014-chainloader-Don-t-check-empty-section-in-file-like-..patch
secure-core/0015-chainloader-find-the-relocations-correctly.patch
secure-core/0016-Add-a-module-for-reading-EFI-global-variables.patch
secure-core/0017-grub-shim-verify-Report-that-the-loaded-object-is-ve.patch
secure-core/0018-grub-verify-Add-strict_security-variable.patch
secure-core/0019-Disable-inside-lockdown-and-shim_lock-verifiers.patch

View File

@@ -0,0 +1,26 @@
From a781e6bfe6af44d3bc159c01c9f8df684c782185 Mon Sep 17 00:00:00 2001
From: Jim Somerville <jim.somerville@windriver.com>
Date: Mon, 11 Apr 2022 22:02:21 +0000
Subject: [PATCH] Provide softlinks to grub menus
Allows tools such as grubby to locate them.
Signed-off-by: Jim Somerville <jim.somerville@windriver.com>
---
debian/grub2-common.links | 3 +++
1 file changed, 3 insertions(+)
diff --git a/debian/grub2-common.links b/debian/grub2-common.links
index a082aa2..01d4ba8 100644
--- a/debian/grub2-common.links
+++ b/debian/grub2-common.links
@@ -4,3 +4,6 @@ usr/share/man/man8/update-grub.8 usr/share/man/man8/update-grub2.8
usr/share/bash-completion/completions/grub usr/share/bash-completion/completions/grub-install
usr/share/bash-completion/completions/grub usr/share/bash-completion/completions/grub-reboot
usr/share/bash-completion/completions/grub usr/share/bash-completion/completions/grub-set-default
+
+boot/efi/EFI/BOOT/grub.cfg etc/grub2-efi.cfg
+boot/grub2/grub.cfg etc/grub2.cfg
--
2.30.2

View File

@@ -0,0 +1,82 @@
From 215aa0657ab2f7b52c7b7eebec465ffdda1ff0d1 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Wed, 31 Aug 2022 13:53:19 +0800
Subject: [PATCH 2/4] grub2: remove unnecessary patches
Clean the patches from debian release to get a clean grub source
and only keep 2 patches necessary for debian packages' build.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/patches/series | 59 -------------------------------------------
1 file changed, 59 deletions(-)
diff --git a/debian/patches/series b/debian/patches/series
index 748318a..0478754 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,61 +1,2 @@
-olpc-prefix-hack.patch
-core-in-fs.patch
-dpkg-version-comparison.patch
-grub-legacy-0-based-partitions.patch
-disable-floppies.patch
-grub.cfg-400.patch
-gfxpayload-keep-default.patch
-install-stage2-confusion.patch
-mkrescue-efi-modules.patch
-mkconfig-loopback.patch
restore-mkdevicemap.patch
-gettext-quiet.patch
-install-efi-fallback.patch
-mkconfig-ubuntu-recovery.patch
-install-locale-langpack.patch
-mkconfig-nonexistent-loopback.patch
-default-grub-d.patch
-blacklist-1440x900x32.patch
-mkconfig-ubuntu-distributor.patch
-linuxefi.patch
-mkconfig-signed-kernel.patch
-install-signed.patch
-wubi-no-windows.patch
-maybe-quiet.patch
-install-efi-adjust-distributor.patch
-quick-boot.patch
-quick-boot-lvm.patch
-gfxpayload-dynamic.patch
-vt-handoff.patch
-probe-fusionio.patch
-ignore-grub_func_test-failures.patch
-mkconfig-recovery-title.patch
-install-powerpc-machtypes.patch
-ieee1275-clear-reset.patch
-ppc64el-disable-vsx.patch
-grub-install-pvxen-paths.patch
-insmod-xzio-and-lzopio-on-xen.patch
-grub-install-extra-removable.patch
-mkconfig-other-inits.patch
-zpool-full-device-name.patch
-net-read-bracketed-ipv6-addr.patch
-bootp-new-net_bootp6-command.patch
-efinet-uefi-ipv6-pxe-support.patch
-bootp-process-dhcpack-http-boot.patch
-efinet-set-network-from-uefi-devpath.patch
-efinet-set-dns-from-uefi-proto.patch
-fix-lockdown.patch
-skip-grub_cmd_set_date.patch
-bash-completion-drop-have-checks.patch
-at_keyboard-module-init.patch
-uefi-secure-boot-cryptomount.patch
-efi-variable-storage-minimise-writes.patch
-grub-install-removable-shim.patch
dejavu-font-path.patch
-xen-no-xsm-policy-in-non-xsm-options.patch
-pc-verifiers-module.patch
-debug_verifiers.patch
-mkimage-fix-section-sizes.patch
-tpm-unknown-error-non-fatal.patch
-xfs-fix-v4-superblock.patch
-tests-ahci-update-qemu-device-name.patch
--
2.17.1

View File

@@ -0,0 +1,321 @@
From db378eae439f7d2d356441ec130ba12321815979 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Thu, 1 Sep 2022 14:41:02 +0800
Subject: [PATCH 3/4] grub2: remove packages' build about grub-efi
Packages related with grub-efi will be built separately with special
patches about secure boot.
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/control | 287 -------------------------------------------------
1 file changed, 287 deletions(-)
diff --git a/debian/control b/debian/control
index 591394f..b318ec8 100644
--- a/debian/control
+++ b/debian/control
@@ -60,15 +60,6 @@ Multi-Arch: foreign
Description: GRand Unified Bootloader, version 2 (dummy package)
This is a dummy transitional package that depends on grub-coreboot.
-Package: grub-efi
-Architecture: any-i386 any-amd64 any-arm64 any-ia64 any-arm
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${misc:Depends}, grub-efi-ia32 (= ${binary:Version}) [any-i386], grub-efi-amd64 (= ${binary:Version}) [any-amd64], grub-efi-arm64 (= ${binary:Version}) [any-arm64], grub-efi-ia64 (= ${binary:Version}) [any-ia64], grub-efi-arm (= ${binary:Version}) [any-arm]
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (dummy package)
- This is a dummy package that depends on the grub-efi-$ARCH package most likely
- to be appropriate for each architecture.
-
Package: grub-common
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, gettext-base, ${lsb-base-depends}
@@ -245,284 +236,6 @@ Description: GRand Unified Bootloader, version 2 (Coreboot version)
use with platforms running the Coreboot firmware. Installing this package
indicates that this version of GRUB should be the active boot loader.
-Package: grub-efi-ia32-bin
-Architecture: any-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Recommends: grub-efi-ia32-signed [i386], efibootmgr [linux-any]
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-ia32 (<< 1.99-1)
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with the
- EFI-IA32 architecture, as used by Intel Macs (unless a BIOS interface has
- been activated). It can be installed in parallel with other flavours, but
- will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-efi-ia32 is also
- installed.
-
-Package: grub-efi-ia32-dbg
-Section: debug
-Architecture: any-i386 any-amd64
-Depends: ${misc:Depends}, grub-efi-ia32-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 debug files)
- This package contains debugging files for grub-efi-ia32-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-ia32
-Architecture: any-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-ia32-bin (= ${binary:Version}), ucf
-Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the EFI-IA32 architecture, as used by Intel Macs (unless a BIOS
- interface has been activated). Installing this package indicates that this
- version of GRUB should be the active boot loader.
-
-Package: grub-efi-ia32-signed-template
-Architecture: i386
-Description: GRand Unified Bootloader, version 2 (EFI-IA32 signing template)
- This package contains template files for grub-efi-ia32-signed.
- This is only needed for Secure Boot signing.
-
-Package: grub-efi-amd64-bin
-Architecture: i386 kopensolaris-i386 any-amd64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Recommends: grub-efi-amd64-signed [amd64], efibootmgr [linux-any]
-Replaces: grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64 (<< 1.99-1)
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (EFI-AMD64 modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use with the
- EFI-AMD64 architecture, as used by Intel Macs (unless a BIOS interface has
- been activated). It can be installed in parallel with other flavours, but
- will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-efi-amd64 is also
- installed.
-
-Package: grub-efi-amd64-dbg
-Section: debug
-Architecture: i386 kopensolaris-i386 any-amd64
-Depends: ${misc:Depends}, grub-efi-amd64-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-AMD64 debug files)
- This package contains debugging files for grub-efi-amd64-bin. You only
- need these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-amd64
-Architecture: i386 kopensolaris-i386 any-amd64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-amd64-bin (= ${binary:Version}), ucf
-Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-pc, grub-efi-ia32, grub-coreboot, grub-ieee1275
-Conflicts: grub, grub-legacy, grub-efi-ia32, grub-pc, grub-coreboot, grub-ieee1275, grub-xen, elilo
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (EFI-AMD64 version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use with the EFI-AMD64 architecture, as used by Intel Macs (unless a BIOS
- interface has been activated). Installing this package indicates that this
- version of GRUB should be the active boot loader.
-
-Package: grub-efi-amd64-signed-template
-Architecture: amd64
-Description: GRand Unified Bootloader, version 2 (EFI-AMD64 signing template)
- This package contains template files for grub-efi-amd64-signed.
- This is only needed for Secure Boot signing.
-
-Package: grub-efi-ia64-bin
-Architecture: any-ia64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (IA64 modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use on IA64.
- It can be installed in parallel with other flavours, but will not
- automatically install GRUB as the active boot loader nor automatically
- update grub.cfg on upgrade unless grub-efi-ia64 is also installed.
-
-Package: grub-efi-ia64-dbg
-Section: debug
-Architecture: any-ia64
-Depends: ${misc:Depends}, grub-efi-ia64-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (IA64 debug files)
- This package contains debugging files for grub-efi-ia64-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-ia64
-Architecture: any-ia64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-ia64-bin (= ${binary:Version}), ucf
-Conflicts: elilo
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (IA64 version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use on IA64. Installing this package indicates that this version of GRUB
- should be the active boot loader.
-
-Package: grub-efi-arm-bin
-Architecture: any-arm
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Recommends: efibootmgr [linux-any]
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (ARM UEFI modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use on ARM
- systems with UEFI. It can be installed in parallel with other flavours,
- but will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-efi-arm is also
- installed.
-
-Package: grub-efi-arm-dbg
-Section: debug
-Architecture: any-arm
-Depends: ${misc:Depends}, grub-efi-arm-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM UEFI debug files)
- This package contains debugging files for grub-efi-arm-bin. You only need
- these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-arm
-Architecture: any-arm
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-arm-bin (= ${binary:Version}), ucf
-Conflicts: grub-uboot
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM UEFI version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use on ARM systems with UEFI. Installing this package indicates that this
- version of GRUB should be the active boot loader.
-
-Package: grub-efi-arm64-bin
-Architecture: any-arm64
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
-Recommends: grub-efi-arm64-signed [arm64], efibootmgr [linux-any]
-Multi-Arch: foreign
-XB-Efi-Vendor: ${efi:Vendor}
-Description: GRand Unified Bootloader, version 2 (ARM64 UEFI modules)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This package contains GRUB modules that have been built for use on ARM64
- systems with UEFI. It can be installed in parallel with other flavours,
- but will not automatically install GRUB as the active boot loader nor
- automatically update grub.cfg on upgrade unless grub-efi-arm64 is also
- installed.
-
-Package: grub-efi-arm64-dbg
-Section: debug
-Architecture: any-arm64
-Depends: ${misc:Depends}, grub-efi-arm64-bin (= ${binary:Version}), grub-common (= ${binary:Version})
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM64 UEFI debug files)
- This package contains debugging files for grub-efi-arm64-bin. You only
- need these if you are trying to debug GRUB using its GDB stub.
-
-Package: grub-efi-arm64
-Architecture: any-arm64
-Pre-Depends: ${misc:Pre-Depends}
-Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-efi-arm64-bin (= ${binary:Version}), ucf
-Multi-Arch: foreign
-Description: GRand Unified Bootloader, version 2 (ARM64 UEFI version)
- GRUB is a portable, powerful bootloader. This version of GRUB is based on a
- cleaner design than its predecessors, and provides the following new features:
- .
- - Scripting in grub.cfg using BASH-like syntax.
- - Support for modern partition maps such as GPT.
- - Modular generation of grub.cfg via update-grub. Packages providing GRUB
- add-ons can plug in their own script rules and trigger updates by invoking
- update-grub.
- .
- This is a dependency package for a version of GRUB that has been built for
- use on ARM64 systems with UEFI. Installing this package indicates that
- this version of GRUB should be the active boot loader.
-
-Package: grub-efi-arm64-signed-template
-Architecture: arm64
-Description: GRand Unified Bootloader, version 2 (ARM64 UEFI signing template)
- This package contains template files for grub-efi-arm64-signed.
- This is only needed for Secure Boot signing.
-
Package: grub-ieee1275-bin
Architecture: any-i386 any-amd64 any-powerpc any-ppc64 any-ppc64el any-sparc any-sparc64
Depends: ${shlibs:Depends}, ${misc:Depends}, grub-common (= ${binary:Version})
--
2.17.1

View File

@@ -0,0 +1,29 @@
From 84bb9335c054cbd61fd54f05f1fa43318b44dae0 Mon Sep 17 00:00:00 2001
From: Li Zhou <li.zhou@windriver.com>
Date: Mon, 5 Sep 2022 11:00:14 +0800
Subject: [PATCH 4/4] grub-pc: remove conflict with grub-efi-amd64
Solve this error when build-image with package grub-efi-amd64:
grub-pc : Conflicts: grub-efi-amd64 but 2.06-1.stx.3 is to be installed
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
debian/control | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/debian/control b/debian/control
index b318ec8..b38d66a 100644
--- a/debian/control
+++ b/debian/control
@@ -152,7 +152,7 @@ Architecture: any-i386 any-amd64
Pre-Depends: ${misc:Pre-Depends}
Depends: ${shlibs:Depends}, ${misc:Depends}, grub2-common (= ${binary:Version}), grub-pc-bin (= ${binary:Version}), ucf, freebsd-utils (>= 8.0-4) [kfreebsd-any], ${gfxpayload-depends}
Replaces: grub, grub-legacy, grub2 (<< ${source:Version}), grub-common (<= 1.97~beta2-1), grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275
-Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-amd64, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-xen
+Conflicts: grub (<< 0.97-54), grub-legacy, grub-efi-ia32, grub-coreboot, grub-ieee1275, grub-xen
Multi-Arch: foreign
Description: GRand Unified Bootloader, version 2 (PC/BIOS version)
GRUB is a portable, powerful bootloader. This version of GRUB is based on a
--
2.17.1

View File

@@ -0,0 +1,4 @@
0001-Provide-softlinks-to-grub-menus.patch
0002-grub2-remove-unnecessary-patches.patch
0003-grub2-remove-packages-build-about-grub-efi.patch
0004-grub-pc-remove-conflict-with-grub-efi-amd64.patch

View File

@@ -0,0 +1,40 @@
#!/bin/bash
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# The only parameter is the name of the folder where the source code
# is extracted to. Pay attention to that the extracted package should
# be put at the same path where this script is located.
# Tools needed: tar
tar xvf grub2_2.06.orig.tar.xz
if [ $? -ne 0 ]
then
echo "tar failed: orig source!"
exit 1
fi
mv grub-2.06 $1
cd $1
tar xvf ../grub2_2.06-1.debian.tar.xz
if [ $? -ne 0 ]
then
echo "tar failed: debian folder!"
exit 1
fi

View File

@@ -0,0 +1,21 @@
---
debver: 2.06-1
debname: grub2
serial: true
dl_hook: dl_hook
dl_files:
grub2_2.06.orig.tar.xz:
topdir: null
url:
"https://snapshot.debian.org/archive/debian/20211128T160803Z/\
pool/main/g/grub2/grub2_2.06.orig.tar.xz"
sha256sum: b79ea44af91b93d17cd3fe80bdae6ed43770678a9a5ae192ccea803ebb657ee1
grub2_2.06-1.debian.tar.xz:
topdir: null
url:
"https://snapshot.debian.org/archive/debian/20211128T160803Z/\
pool/main/g/grub2/grub2_2.06-1.debian.tar.xz"
sha256sum: 16a1a89d93abf8beb148dc30738be1bda05ed3c09cfffd4a1f5e1a0328c74b26
revision:
dist: $STX_DIST
PKG_GITREVCOUNT: true

View File

@@ -0,0 +1,32 @@
From be38cbc51f89493c46e299950937b85893ca05e8 Mon Sep 17 00:00:00 2001
From: Bin Qian <bin.qian@windriver.com>
Date: Tue, 21 Nov 2017 15:36:42 -0500
Subject: [PATCH] grub2: add tboot
Original patch is 1001-add-tboot.patch
Signed-off-by: Bin Qian <bin.qian@windriver.com>
Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
---
util/grub.d/10_linux.in | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 0cd4cf5..81435a8 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -28,6 +28,11 @@ vt_handoff="@VT_HANDOFF@"
. "$pkgdatadir/grub-mkconfig_lib"
+tboot=`cat /proc/cmdline | xargs -n1 | grep '^tboot=true$'` || true
+if [ -n "$tboot" ]; then
+ exit 0
+fi
+
export TEXTDOMAIN=@PACKAGE@
export TEXTDOMAINDIR="@localedir@"
--
2.25.1

View File

@@ -0,0 +1,48 @@
From bbd8d33b8646785ee31b435e9decf4271d6ecb68 Mon Sep 17 00:00:00 2001
From: Yue Tao <Yue.Tao@windriver.com>
Date: Sun, 5 Dec 2021 10:01:05 +0800
Subject: [PATCH] grub2: checking if loop devices are available
Building in a chroot environment, may not have loop device.
Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
---
tests/ext234_test.in | 5 +++++
tests/fat_test.in | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/tests/ext234_test.in b/tests/ext234_test.in
index 4f1eb52..380850e 100644
--- a/tests/ext234_test.in
+++ b/tests/ext234_test.in
@@ -25,6 +25,11 @@ if ! which mkfs.ext4 >/dev/null 2>&1; then
exit 77
fi
+if ! losetup -f >/dev/null 2>&1; then
+ echo "No loop device, cannot test."
+ exit 77
+fi
+
"@builddir@/grub-fs-tester" ext2_old
"@builddir@/grub-fs-tester" ext2
"@builddir@/grub-fs-tester" ext3
diff --git a/tests/fat_test.in b/tests/fat_test.in
index b6b4748..ab5348a 100644
--- a/tests/fat_test.in
+++ b/tests/fat_test.in
@@ -15,6 +15,11 @@ if ! which mkfs.vfat >/dev/null 2>&1; then
exit 77
fi
+if ! losetup -f >/dev/null 2>&1; then
+ echo "No loop device, cannot test."
+ exit 77
+fi
+
"@builddir@/grub-fs-tester" vfat16a
"@builddir@/grub-fs-tester" vfat12a
"@builddir@/grub-fs-tester" vfat12
--
2.25.1

View File

@@ -0,0 +1,99 @@
From 24e6d59ac676791507ff5267bf3bef6cbaff6aef Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Thu, 2 Dec 2021 15:03:53 +0100
Subject: kern/efi/sb: Reject non-kernel files in the shim_lock verifier
We must not allow other verifiers to pass things like the GRUB modules.
Instead of maintaining a blocklist, maintain an allowlist of things
that we do not care about.
This allowlist really should be made reusable, and shared by the
lockdown verifier, but this is the minimal patch addressing
security concerns where the TPM verifier was able to mark modules
as verified (or the OpenPGP verifier for that matter), when it
should not do so on shim-powered secure boot systems.
Fixes: CVE-2022-28735
Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/sb.c | 39 ++++++++++++++++++++++++++++++++++++---
include/grub/verify.h | 1 +
2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index c52ec6226..89c4bb3fd 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -119,10 +119,11 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
void **context __attribute__ ((unused)),
enum grub_verify_flags *flags)
{
- *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ *flags = GRUB_VERIFY_FLAGS_NONE;
switch (type & GRUB_FILE_TYPE_MASK)
{
+ /* Files we check. */
case GRUB_FILE_TYPE_LINUX_KERNEL:
case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
case GRUB_FILE_TYPE_BSD_KERNEL:
@@ -130,11 +131,43 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_PLAN9_KERNEL:
case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
*flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
- /* Fall through. */
+ /* Files that do not affect secureboot state. */
+ case GRUB_FILE_TYPE_NONE:
+ case GRUB_FILE_TYPE_LOOPBACK:
+ case GRUB_FILE_TYPE_LINUX_INITRD:
+ case GRUB_FILE_TYPE_OPENBSD_RAMDISK:
+ case GRUB_FILE_TYPE_XNU_RAMDISK:
+ case GRUB_FILE_TYPE_SIGNATURE:
+ case GRUB_FILE_TYPE_PUBLIC_KEY:
+ case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST:
+ case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
+ case GRUB_FILE_TYPE_TESTLOAD:
+ case GRUB_FILE_TYPE_GET_SIZE:
+ case GRUB_FILE_TYPE_FONT:
+ case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
+ case GRUB_FILE_TYPE_CAT:
+ case GRUB_FILE_TYPE_HEXCAT:
+ case GRUB_FILE_TYPE_CMP:
+ case GRUB_FILE_TYPE_HASHLIST:
+ case GRUB_FILE_TYPE_TO_HASH:
+ case GRUB_FILE_TYPE_KEYBOARD_LAYOUT:
+ case GRUB_FILE_TYPE_PIXMAP:
+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST:
+ case GRUB_FILE_TYPE_CONFIG:
+ case GRUB_FILE_TYPE_THEME:
+ case GRUB_FILE_TYPE_GETTEXT_CATALOG:
+ case GRUB_FILE_TYPE_FS_SEARCH:
+ case GRUB_FILE_TYPE_LOADENV:
+ case GRUB_FILE_TYPE_SAVEENV:
+ case GRUB_FILE_TYPE_VERIFY_SIGNATURE:
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ /* Other files. */
default:
- return GRUB_ERR_NONE;
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy"));
}
}
diff --git a/include/grub/verify.h b/include/grub/verify.h
index 6fde244fc..67448165f 100644
--- a/include/grub/verify.h
+++ b/include/grub/verify.h
@@ -24,6 +24,7 @@
enum grub_verify_flags
{
+ GRUB_VERIFY_FLAGS_NONE = 0,
GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1,
GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2,
/* Defer verification to another authority. */

View File

@@ -0,0 +1,109 @@
From a85714545fe57a86d14ee231a4cd312158101d43 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Wed, 26 Oct 2022 20:16:44 -0400
Subject: [PATCH 01/14] video/readers: Add artificial limit to image dimensions
In grub-core/video/readers/jpeg.c, the height and width of a JPEG image don't
have an upper limit for how big the JPEG image can be. In Coverity, this is
getting flagged as an untrusted loop bound. This issue can also seen in PNG and
TGA format images as well but Coverity isn't flagging it. To prevent this, the
constant IMAGE_HW_MAX_PX is being added to include/grub/bitmap.h, which has
a value of 16384, to act as an artificial limit and restrict the height and
width of images. This value was picked as it is double the current max
resolution size, which is 8K.
Fixes: CID 292450
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 3 ++-
grub-core/video/readers/jpeg.c | 6 +++++-
grub-core/video/readers/png.c | 6 +++++-
grub-core/video/readers/tga.c | 7 +++++++
include/grub/bitmap.h | 2 ++
5 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 0dbbdc374..2d6cd8358 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1515,7 +1515,8 @@ resolution. @xref{gfxmode}.
Set a background image for use with the @samp{gfxterm} graphical terminal.
The value of this option must be a file readable by GRUB at boot time, and
it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}.
-The image will be scaled if necessary to fit the screen.
+The image will be scaled if necessary to fit the screen. Image height and
+width will be restricted by an artificial limit of 16384.
@item GRUB_THEME
Set a theme for use with the @samp{gfxterm} graphical terminal.
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 09596fbf5..ae634fd41 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -346,7 +346,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
data->image_height = grub_jpeg_get_word (data);
data->image_width = grub_jpeg_get_word (data);
- if ((!data->image_height) || (!data->image_width))
+ grub_dprintf ("jpeg", "image height: %d\n", data->image_height);
+ grub_dprintf ("jpeg", "image width: %d\n", data->image_width);
+
+ if ((!data->image_height) || (!data->image_width) ||
+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
cc = grub_jpeg_get_byte (data);
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 7f2ba7849..3163e97bf 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -264,7 +264,11 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->image_width = grub_png_get_dword (data);
data->image_height = grub_png_get_dword (data);
- if ((!data->image_height) || (!data->image_width))
+ grub_dprintf ("png", "image height: %d\n", data->image_height);
+ grub_dprintf ("png", "image width: %d\n", data->image_width);
+
+ if ((!data->image_height) || (!data->image_width) ||
+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size");
color_bits = grub_png_get_byte (data);
diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c
index a9ec3a1b6..9c35bf29d 100644
--- a/grub-core/video/readers/tga.c
+++ b/grub-core/video/readers/tga.c
@@ -340,6 +340,13 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap,
data.image_width = grub_le_to_cpu16 (data.hdr.image_width);
data.image_height = grub_le_to_cpu16 (data.hdr.image_height);
+ grub_dprintf ("tga", "image height: %d\n", data.image_height);
+ grub_dprintf ("tga", "image width: %d\n", data.image_width);
+
+ /* Check image height and width are within restrictions. */
+ if ((data.image_height > IMAGE_HW_MAX_PX) || (data.image_width > IMAGE_HW_MAX_PX))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "tga: invalid image size");
+
/* Check that bitmap encoding is supported. */
switch (data.hdr.image_type)
{
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
index 5728f8ca3..149d37bfe 100644
--- a/include/grub/bitmap.h
+++ b/include/grub/bitmap.h
@@ -24,6 +24,8 @@
#include <grub/types.h>
#include <grub/video.h>
+#define IMAGE_HW_MAX_PX 16384
+
struct grub_video_bitmap
{
/* Bitmap format description. */
--
2.30.2

View File

@@ -0,0 +1,33 @@
From 5760fcfd466cc757540ea0d591bad6a08caeaa16 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Wed, 3 Aug 2022 19:45:33 +0800
Subject: [PATCH 02/14] font: Reject glyphs exceeds font->max_glyph_width or
font->max_glyph_height
Check glyph's width and height against limits specified in font's
metadata. Reject the glyph (and font) if such limits are exceeded.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 42189c325..756ca0abf 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|| read_be_uint16 (font->file, &height) != 0
|| read_be_int16 (font->file, &xoff) != 0
|| read_be_int16 (font->file, &yoff) != 0
- || read_be_int16 (font->file, &dwidth) != 0)
+ || read_be_int16 (font->file, &dwidth) != 0
+ || width > font->max_char_width
+ || height > font->max_char_height)
{
remove_font (font);
return 0;
--
2.30.2

View File

@@ -0,0 +1,110 @@
From 941d10ad6f1dcbd12fb613002249e29ba035f985 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 00:51:20 +0800
Subject: [PATCH 03/14] font: Fix size overflow in
grub_font_get_glyph_internal()
The length of memory allocation and file read may overflow. This patch
fixes the problem by using safemath macros.
There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe
if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz().
It is safe replacement for such code. It has safemath-like prototype.
This patch also introduces grub_cast(value, pointer), it casts value to
typeof(*pointer) then store the value to *pointer. It returns true when
overflow occurs or false if there is no overflow. The semantics of arguments
and return value are designed to be consistent with other safemath macros.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 17 +++++++++++++----
include/grub/bitmap.h | 18 ++++++++++++++++++
include/grub/safemath.h | 2 ++
3 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 2f09a4a55..6a3fbebbd 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
grub_int16_t xoff;
grub_int16_t yoff;
grub_int16_t dwidth;
- int len;
+ grub_ssize_t len;
+ grub_size_t sz;
if (index_entry->glyph)
/* Return cached glyph. */
@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
return 0;
}
- len = (width * height + 7) / 8;
- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
- if (!glyph)
+ /* Calculate real struct size of current glyph. */
+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) ||
+ grub_add (sizeof (struct grub_font_glyph), len, &sz))
+ {
+ remove_font (font);
+ return 0;
+ }
+
+ /* Allocate and initialize the glyph struct. */
+ glyph = grub_malloc (sz);
+ if (glyph == NULL)
{
remove_font (font);
return 0;
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
index 149d37bfe..431048936 100644
--- a/include/grub/bitmap.h
+++ b/include/grub/bitmap.h
@@ -23,6 +23,7 @@
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/video.h>
+#include <grub/safemath.h>
#define IMAGE_HW_MAX_PX 16384
@@ -81,6 +82,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
return bitmap->mode_info.height;
}
+/*
+ * Calculate and store the size of data buffer of 1bit bitmap in result.
+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs.
+ * Return true when overflow occurs or false if there is no overflow.
+ * This function is intentionally implemented as a macro instead of
+ * an inline function. Although a bit awkward, it preserves data types for
+ * safemath macros and reduces macro side effects as much as possible.
+ *
+ * XXX: Will report false overflow if width * height > UINT64_MAX.
+ */
+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \
+({ \
+ grub_uint64_t _bitmap_pixels; \
+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \
+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \
+})
+
void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
struct grub_video_mode_info *mode_info);
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
index c17b89bba..bb0f826de 100644
--- a/include/grub/safemath.h
+++ b/include/grub/safemath.h
@@ -30,6 +30,8 @@
#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
+#define grub_cast(a, res) grub_add ((a), 0, (res))
+
#else
#error gcc 5.1 or newer or clang 3.8 or newer is required
#endif

View File

@@ -0,0 +1,81 @@
From b1805f251b31a9d3cfae5c3572ddfa630145dbbf Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 01:58:27 +0800
Subject: [PATCH 04/14] font: Fix several integer overflows in
grub_font_construct_glyph()
This patch fixes several integer overflows in grub_font_construct_glyph().
Glyphs of invalid size, zero or leading to an overflow, are rejected.
The inconsistency between "glyph" and "max_glyph_size" when grub_malloc()
returns NULL is fixed too.
Fixes: CVE-2022-2601
Reported-by: Zhang Boyang <zhangboyang.id@gmail.com>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e781521a7..e6548892f 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
struct grub_video_signed_rect bounds;
static struct grub_font_glyph *glyph = 0;
static grub_size_t max_glyph_size = 0;
+ grub_size_t cur_glyph_size;
ensure_comb_space (glyph_id);
@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font,
if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph;
- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) ||
+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size))
+ return main_glyph;
+
+ if (max_glyph_size < cur_glyph_size)
{
grub_free (glyph);
- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
- if (max_glyph_size < 8)
- max_glyph_size = 8;
- glyph = grub_malloc (max_glyph_size);
+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size))
+ max_glyph_size = 0;
+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL;
}
if (!glyph)
{
+ max_glyph_size = 0;
grub_errno = GRUB_ERR_NONE;
return main_glyph;
}
- grub_memset (glyph, 0, sizeof (*glyph)
- + (bounds.width * bounds.height
- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
+ grub_memset (glyph, 0, cur_glyph_size);
glyph->font = main_glyph->font;
- glyph->width = bounds.width;
- glyph->height = bounds.height;
- glyph->offset_x = bounds.x;
- glyph->offset_y = bounds.y;
+ if (bounds.width == 0 || bounds.height == 0 ||
+ grub_cast (bounds.width, &glyph->width) ||
+ grub_cast (bounds.height, &glyph->height) ||
+ grub_cast (bounds.x, &glyph->offset_x) ||
+ grub_cast (bounds.y, &glyph->offset_y))
+ return main_glyph;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
grub_font_blit_glyph_mirror (glyph, main_glyph,
--
2.30.2

View File

@@ -0,0 +1,42 @@
From 25ad31c19c331aaa2dbd9bd2b2e2655de5766a9d Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 02:13:29 +0800
Subject: [PATCH 05/14] font: Remove grub_font_dup_glyph()
Remove grub_font_dup_glyph() since nobody is using it since 2013, and
I'm too lazy to fix the integer overflow problem in it.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e6548892f..a8576ffec 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
return best_glyph;
}
-#if 0
-static struct grub_font_glyph *
-grub_font_dup_glyph (struct grub_font_glyph *glyph)
-{
- static struct grub_font_glyph *ret;
- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
- if (!ret)
- return NULL;
- grub_memcpy (ret, glyph, sizeof (*ret)
- + (glyph->width * glyph->height + 7) / 8);
- return ret;
-}
-#endif
-
/* FIXME: suboptimal. */
static void
grub_font_blit_glyph (struct grub_font_glyph *target,
--
2.30.2

View File

@@ -0,0 +1,48 @@
From b2740b7e4a03bb8331d48b54b119afea76bb9d5f Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 5 Aug 2022 02:27:05 +0800
Subject: [PATCH 06/14] font: Fix integer overflow in ensure_comb_space()
In fact it can't overflow at all because glyph_id->ncomb is only 8-bit
wide. But let's keep safe if somebody changes the width of glyph_id->ncomb
in the future. This patch also fixes the inconsistency between
render_max_comb_glyphs and render_combining_glyphs when grub_malloc()
returns NULL.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index a8576ffec..9e3e0a94e 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
if (glyph_id->ncomb <= render_max_comb_glyphs)
return;
- render_max_comb_glyphs = 2 * glyph_id->ncomb;
- if (render_max_comb_glyphs < 8)
+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs))
+ render_max_comb_glyphs = 0;
+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8)
render_max_comb_glyphs = 8;
grub_free (render_combining_glyphs);
- render_combining_glyphs = grub_malloc (render_max_comb_glyphs
- * sizeof (render_combining_glyphs[0]));
+ render_combining_glyphs = (render_max_comb_glyphs > 0) ?
+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL;
if (!render_combining_glyphs)
- grub_errno = 0;
+ {
+ render_max_comb_glyphs = 0;
+ grub_errno = GRUB_ERR_NONE;
+ }
}
int
--
2.30.2

View File

@@ -0,0 +1,65 @@
From afda8b60ba0712abe01ae1e64c5f7a067a0e6492 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 15 Aug 2022 02:04:58 +0800
Subject: [PATCH 07/14] font: Fix integer overflow in BMP index
The BMP index (font->bmp_idx) is designed as a reverse lookup table of
char entries (font->char_index), in order to speed up lookups for BMP
chars (i.e. code < 0x10000). The values in BMP index are the subscripts
of the corresponding char entries, stored in grub_uint16_t, while 0xffff
means not found.
This patch fixes the problem of large subscript truncated to grub_uint16_t,
leading BMP index to return wrong char entry or report false miss. The
code now checks for bounds and uses BMP index as a hint, and fallbacks
to binary-search if necessary.
On the occasion add a comment about BMP index is initialized to 0xffff.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 9e3e0a94e..e4cb0d867 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
if (!font->bmp_idx)
return 1;
+
+ /* Init the BMP index array to 0xffff. */
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
return 1;
}
- if (entry->code < 0x10000)
+ if (entry->code < 0x10000 && i < 0xffff)
font->bmp_idx[entry->code] = i;
last_code = entry->code;
@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
/* Use BMP index if possible. */
if (code < 0x10000 && font->bmp_idx)
{
- if (font->bmp_idx[code] == 0xffff)
- return 0;
- return &table[font->bmp_idx[code]];
+ if (font->bmp_idx[code] < 0xffff)
+ return &table[font->bmp_idx[code]];
+ /*
+ * When we are here then lookup in BMP index result in miss,
+ * fallthough to binary-search.
+ */
}
/* Do a binary search in `char_index', which is ordered by code point. */
--
2.30.2

View File

@@ -0,0 +1,86 @@
From c140a086838e7c9af87842036f891b8393a8c4bc Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Sun, 14 Aug 2022 18:09:38 +0800
Subject: [PATCH 08/14] font: Fix integer underflow in binary search of char
index
If search target is less than all entries in font->index then "hi"
variable is set to -1, which translates to SIZE_MAX and leads to errors.
This patch fixes the problem by replacing the entire binary search code
with the libstdc++'s std::lower_bound() implementation.
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index e4cb0d867..abd412a5e 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
static inline struct char_index_entry *
find_glyph (const grub_font_t font, grub_uint32_t code)
{
- struct char_index_entry *table;
- grub_size_t lo;
- grub_size_t hi;
- grub_size_t mid;
+ struct char_index_entry *table, *first, *end;
+ grub_size_t len;
table = font->char_index;
+ if (table == NULL)
+ return NULL;
/* Use BMP index if possible. */
if (code < 0x10000 && font->bmp_idx)
@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
*/
}
- /* Do a binary search in `char_index', which is ordered by code point. */
- lo = 0;
- hi = font->num_chars - 1;
-
- if (!table)
- return 0;
+ /*
+ * Do a binary search in char_index which is ordered by code point.
+ * The code below is the same as libstdc++'s std::lower_bound().
+ */
+ first = table;
+ len = font->num_chars;
+ end = first + len;
- while (lo <= hi)
+ while (len > 0)
{
- mid = lo + (hi - lo) / 2;
- if (code < table[mid].code)
- hi = mid - 1;
- else if (code > table[mid].code)
- lo = mid + 1;
+ grub_size_t half = len >> 1;
+ struct char_index_entry *middle = first + half;
+
+ if (middle->code < code)
+ {
+ first = middle + 1;
+ len = len - half - 1;
+ }
else
- return &table[mid];
+ len = half;
}
- return 0;
+ return (first < end && first->code == code) ? first : NULL;
}
/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded
--
2.30.2

View File

@@ -0,0 +1,54 @@
From 630deb8c0d8b02b670ced4b7030414bcf17aa080 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Sun, 14 Aug 2022 15:51:54 +0800
Subject: [PATCH 09/14] kern/efi/sb: Enforce verification of font files
As a mitigation and hardening measure enforce verification of font
files. Then only trusted font files can be load. This will reduce the
attack surface at cost of losing the ability of end-users to customize
fonts if e.g. UEFI Secure Boot is enabled. Vendors can always customize
fonts because they have ability to pack fonts into their GRUB bundles.
This goal is achieved by:
* Removing GRUB_FILE_TYPE_FONT from shim lock verifier's
skip-verification list.
* Adding GRUB_FILE_TYPE_FONT to lockdown verifier's defer-auth list,
so font files must be verified by a verifier before they can be loaded.
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/sb.c | 1 -
grub-core/kern/lockdown.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
index 89c4bb3fd..db42c2539 100644
--- a/grub-core/kern/efi/sb.c
+++ b/grub-core/kern/efi/sb.c
@@ -145,7 +145,6 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
case GRUB_FILE_TYPE_TESTLOAD:
case GRUB_FILE_TYPE_GET_SIZE:
- case GRUB_FILE_TYPE_FONT:
case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
case GRUB_FILE_TYPE_CAT:
case GRUB_FILE_TYPE_HEXCAT:
diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c
index 0bc70fd42..af6d493cd 100644
--- a/grub-core/kern/lockdown.c
+++ b/grub-core/kern/lockdown.c
@@ -51,6 +51,7 @@ lockdown_verifier_init (grub_file_t io __attribute__ ((unused)),
case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
case GRUB_FILE_TYPE_ACPI_TABLE:
case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+ case GRUB_FILE_TYPE_FONT:
*flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
/* Fall through. */
--
2.30.2

View File

@@ -0,0 +1,85 @@
From 50a11a81bc842c58962244a2dc86bbd31a426e12 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Tue, 6 Sep 2022 03:03:21 +0800
Subject: [PATCH 10/14] fbutil: Fix integer overflow
Expressions like u64 = u32 * u32 are unsafe because their products are
truncated to u32 even if left hand side is u64. This patch fixes all
problems like that one in fbutil.
To get right result not only left hand side have to be u64 but it's also
necessary to cast at least one of the operands of all leaf operators of
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
u64 = (u64)u32 * u32 + (u64)u32 * u32.
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
not overflow grub_uint64_t.
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
This patch also adds a comment to grub_video_fb_get_video_ptr() which
says it's arguments must be valid and no sanity check is performed
(like its siblings in grub-core/video/fb/fbutil.c).
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/fb/fbutil.c | 4 ++--
include/grub/fbutil.h | 13 +++++++++----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
index b98bb51fe..25ef39f47 100644
--- a/grub-core/video/fb/fbutil.c
+++ b/grub-core/video/fb/fbutil.c
@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source,
case 1:
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
{
- int bit_index = y * source->mode_info->width + x;
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
grub_uint8_t *ptr = source->data + bit_index / 8;
int bit_pos = 7 - bit_index % 8;
color = (*ptr >> bit_pos) & 0x01;
@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source,
case 1:
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
{
- int bit_index = y * source->mode_info->width + x;
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
grub_uint8_t *ptr = source->data + bit_index / 8;
int bit_pos = 7 - bit_index % 8;
*ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
index 4205eb917..78a1ab3b4 100644
--- a/include/grub/fbutil.h
+++ b/include/grub/fbutil.h
@@ -31,14 +31,19 @@ struct grub_video_fbblit_info
grub_uint8_t *data;
};
-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
- and it doesn't make sense, in general, to ask for a pointer
- to a particular pixel's data. */
+/*
+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
+ * and it doesn't make sense, in general, to ask for a pointer
+ * to a particular pixel's data.
+ *
+ * This function assumes that bounds checking has been done in previous phase
+ * and they are opted out in here.
+ */
static inline void *
grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
unsigned int x, unsigned int y)
{
- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel;
+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel;
}
/* Advance pointer by VAL bytes. If there is no unaligned access available,
--
2.30.2

View File

@@ -0,0 +1,91 @@
From 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 24 Oct 2022 08:05:35 +0800
Subject: [PATCH 11/14] font: Fix an integer underflow in blit_comb()
The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
evaluate to a very big invalid value even if both ctx.bounds.height and
combining_glyphs[i]->height are small integers. For example, if
ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
expression evaluates to 2147483647 (expected -1). This is because
coordinates are allowed to be negative but ctx.bounds.height is an
unsigned int. So, the subtraction operates on unsigned ints and
underflows to a very big value. The division makes things even worse.
The quotient is still an invalid value even if converted back to int.
This patch fixes the problem by casting ctx.bounds.height to int. As
a result the subtraction will operate on int and grub_uint16_t which
will be promoted to an int. So, the underflow will no longer happen. Other
uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
to ensure coordinates are always calculated on signed integers.
Fixes: CVE-2022-3775
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index abd412a5e..3d3d803e8 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
ctx.bounds.height = main_glyph->height;
above_rightx = main_glyph->offset_x + main_glyph->width;
- above_righty = ctx.bounds.y + ctx.bounds.height;
+ above_righty = ctx.bounds.y + (int) ctx.bounds.height;
above_leftx = main_glyph->offset_x;
- above_lefty = ctx.bounds.y + ctx.bounds.height;
+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
- below_rightx = ctx.bounds.x + ctx.bounds.width;
+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
below_righty = ctx.bounds.y;
comb = grub_unicode_get_comb (glyph_id);
@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
if (!combining_glyphs[i])
continue;
- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
/* CGJ is to avoid diacritics reordering. */
if (comb[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
targetx,
- (ctx.bounds.height - combining_glyphs[i]->height) / 2
- - (ctx.bounds.height + ctx.bounds.y), &ctx);
+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
break;
@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
/* Fallthrough. */
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
do_blit (combining_glyphs[i], targetx,
- -(ctx.bounds.height + ctx.bounds.y + space
+ -((int) ctx.bounds.height + ctx.bounds.y + space
+ combining_glyphs[i]->height), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
case GRUB_UNICODE_COMB_HEBREW_DAGESH:
do_blit (combining_glyphs[i], targetx,
- -(ctx.bounds.height / 2 + ctx.bounds.y
+ -((int) ctx.bounds.height / 2 + ctx.bounds.y
+ combining_glyphs[i]->height / 2), &ctx);
if (min_devwidth < combining_glyphs[i]->width)
min_devwidth = combining_glyphs[i]->width;
--
2.30.2

View File

@@ -0,0 +1,75 @@
From fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Mon, 24 Oct 2022 07:15:41 +0800
Subject: [PATCH 12/14] font: Harden grub_font_blit_glyph() and
grub_font_blit_glyph_mirror()
As a mitigation and hardening measure add sanity checks to
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
makes these two functions do nothing if target blitting area isn't fully
contained in target bitmap. Therefore, if complex calculations in caller
overflows and malicious coordinates are given, we are still safe because
any coordinates which result in out-of-bound-write are rejected. However,
this patch only checks for invalid coordinates, and doesn't provide any
protection against invalid source glyph or destination glyph, e.g.
mismatch between glyph size and buffer size.
This hardening measure is designed to mitigate possible overflows in
blit_comb(). If overflow occurs, it may return invalid bounding box
during dry run and call grub_font_blit_glyph() with malicious
coordinates during actual blitting. However, we are still safe because
the scratch glyph itself is valid, although its size makes no sense, and
any invalid coordinates are rejected.
It would be better to call grub_fatal() if illegal parameter is detected.
However, doing this may end up in a dangerous recursion because grub_fatal()
would print messages to the screen and we are in the progress of drawing
characters on the screen.
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 3d3d803e8..cf15dc2f9 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1069,8 +1069,15 @@ static void
grub_font_blit_glyph (struct grub_font_glyph *target,
struct grub_font_glyph *src, unsigned dx, unsigned dy)
{
+ grub_uint16_t max_x, max_y;
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
unsigned i, j;
+
+ /* Harden against out-of-bound writes. */
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
+ return;
+
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i) % 8;
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
struct grub_font_glyph *src,
unsigned dx, unsigned dy)
{
+ grub_uint16_t max_x, max_y;
unsigned tgt_bit, src_byte, tgt_byte;
signed src_bit;
unsigned i, j;
+
+ /* Harden against out-of-bound writes. */
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
+ return;
+
for (i = 0; i < src->height; i++)
{
src_bit = (src->width * i + src->width - 1) % 8;
--
2.30.2

View File

@@ -0,0 +1,36 @@
From dd539d695482069d28b40f2d3821f710cdcf6ee6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 28 Oct 2022 17:29:16 +0800
Subject: [PATCH 13/14] font: Assign null_font to glyphs in ascii_font_glyph[]
The calculations in blit_comb() need information from glyph's font, e.g.
grub_font_get_xheight(main_glyph->font). However, main_glyph->font is
NULL if main_glyph comes from ascii_font_glyph[]. Therefore
grub_font_get_*() crashes because of NULL pointer.
There is already a solution, the null_font. So, assign it to those glyphs
in ascii_font_glyph[].
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/font/font.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index cf15dc2f9..3821937e6 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code)
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
- ascii_font_glyph[current]->font = NULL;
+ ascii_font_glyph[current]->font = &null_font;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
--
2.30.2

View File

@@ -0,0 +1,55 @@
From da90d62316a3b105d2fbd7334d6521936bd6dcf6 Mon Sep 17 00:00:00 2001
From: Zhang Boyang <zhangboyang.id@gmail.com>
Date: Fri, 28 Oct 2022 21:31:39 +0800
Subject: [PATCH 14/14] normal/charset: Fix an integer overflow in
grub_unicode_aglomerate_comb()
The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255.
However, code in grub_unicode_aglomerate_comb() doesn't check for an
overflow when incrementing out->ncomb. If out->ncomb is already 255,
after incrementing it will get 0 instead of 256, and cause illegal
memory access in subsequent processing.
This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max
acceptable value of ncomb. The code now checks for this limit and
ignores additional combining characters when limit is reached.
Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/normal/charset.c | 3 +++
include/grub/unicode.h | 2 ++
2 files changed, 5 insertions(+)
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
index 000e687bd..4f6647116 100644
--- a/grub-core/normal/charset.c
+++ b/grub-core/normal/charset.c
@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
if (!haveout)
continue;
+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX)
+ continue;
+
if (comb_type == GRUB_UNICODE_COMB_MC
|| comb_type == GRUB_UNICODE_COMB_ME
|| comb_type == GRUB_UNICODE_COMB_MN)
diff --git a/include/grub/unicode.h b/include/grub/unicode.h
index 71a4d1a54..9360b0b97 100644
--- a/include/grub/unicode.h
+++ b/include/grub/unicode.h
@@ -147,7 +147,9 @@ struct grub_unicode_glyph
grub_uint8_t bidi_level:6; /* minimum: 6 */
enum grub_bidi_type bidi_type:5; /* minimum: :5 */
+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1)
unsigned ncomb:8;
+
/* Hint by unicode subsystem how wide this character usually is.
Real width is determined by font. Set only in UTF-8 stream. */
int estimated_width:8;
--
2.30.2

View File

@@ -0,0 +1,171 @@
From 157486f818ecbe26b7962f5795a8f48393ba5169 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 18:51:35 +1000
Subject: [PATCH 1/6] video/readers/png: Drop greyscale support to fix heap
out-of-bounds write
A 16-bit greyscale PNG without alpha is processed in the following loop:
for (i = 0; i < (data->image_width * data->image_height);
i++, d1 += 4, d2 += 2)
{
d1[R3] = d2[1];
d1[G3] = d2[1];
d1[B3] = d2[1];
}
The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration,
but there are only 3 bytes allocated for storage. This means that image
data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes
out of every 4 following the end of the image.
This has existed since greyscale support was added in 2013 in commit
3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale).
Saving starfield.png as a 16-bit greyscale image without alpha in the gimp
and attempting to load it causes grub-emu to crash - I don't think this code
has ever worked.
Delete all PNG greyscale support.
Fixes: CVE-2021-3695
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 87 +++--------------------------------
1 file changed, 7 insertions(+), 80 deletions(-)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 4827b9c..1e35eae 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -100,7 +100,7 @@ struct grub_png_data
unsigned image_width, image_height;
int bpp, is_16bit;
- int raw_bytes, is_gray, is_alpha, is_palette;
+ int raw_bytes, is_alpha, is_palette;
int row_bytes, color_bits;
grub_uint8_t *image_data;
@@ -284,13 +284,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
data->bpp = 3;
else
{
- data->is_gray = 1;
- data->bpp = 1;
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: color type not supported");
}
if ((color_bits != 8) && (color_bits != 16)
&& (color_bits != 4
- || !(data->is_gray || data->is_palette)))
+ || !data->is_palette))
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"png: bit depth must be 8 or 16");
@@ -319,7 +319,7 @@ grub_png_decode_image_header (struct grub_png_data *data)
}
#ifndef GRUB_CPU_WORDS_BIGENDIAN
- if (data->is_16bit || data->is_gray || data->is_palette)
+ if (data->is_16bit || data->is_palette)
#endif
{
data->image_data = grub_calloc (data->image_height, data->row_bytes);
@@ -863,27 +863,8 @@ grub_png_convert_image (struct grub_png_data *data)
int shift;
int mask = (1 << data->color_bits) - 1;
unsigned j;
- if (data->is_gray)
- {
- /* Generic formula is
- (0xff * i) / ((1U << data->color_bits) - 1)
- but for allowed bit depth of 1, 2 and for it's
- equivalent to
- (0xff / ((1U << data->color_bits) - 1)) * i
- Precompute the multipliers to avoid division.
- */
-
- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 };
- for (i = 0; i < (1U << data->color_bits); i++)
- {
- grub_uint8_t col = multipliers[data->color_bits] * i;
- palette[i][0] = col;
- palette[i][1] = col;
- palette[i][2] = col;
- }
- }
- else
- grub_memcpy (palette, data->palette, 3 << data->color_bits);
+
+ grub_memcpy (palette, data->palette, 3 << data->color_bits);
d1c = d1;
d2c = d2;
for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3,
@@ -920,60 +901,6 @@ grub_png_convert_image (struct grub_png_data *data)
}
return;
}
-
- if (data->is_gray)
- {
- switch (data->bpp)
- {
- case 4:
- /* 16-bit gray with alpha. */
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 4)
- {
- d1[R4] = d2[3];
- d1[G4] = d2[3];
- d1[B4] = d2[3];
- d1[A4] = d2[1];
- }
- break;
- case 2:
- if (data->is_16bit)
- /* 16-bit gray without alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R3] = d2[1];
- d1[G3] = d2[1];
- d1[B3] = d2[1];
- }
- }
- else
- /* 8-bit gray with alpha. */
- {
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 4, d2 += 2)
- {
- d1[R4] = d2[1];
- d1[G4] = d2[1];
- d1[B4] = d2[1];
- d1[A4] = d2[0];
- }
- }
- break;
- /* 8-bit gray without alpha. */
- case 1:
- for (i = 0; i < (data->image_width * data->image_height);
- i++, d1 += 3, d2++)
- {
- d1[R3] = d2[0];
- d1[G3] = d2[0];
- d1[B3] = d2[0];
- }
- break;
- }
- return;
- }
{
/* Only copy the upper 8 bit. */
--
2.17.1

View File

@@ -0,0 +1,42 @@
From b54f7505732ad5c6237a133c0a1cf00774f13508 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 6 Jul 2021 23:25:07 +1000
Subject: [PATCH 2/6] video/readers/png: Avoid heap OOB R/W inserting huff
table items
In fuzzing we observed crashes where a code would attempt to be inserted
into a huffman table before the start, leading to a set of heap OOB reads
and writes as table entries with negative indices were shifted around and
the new code written in.
Catch the case where we would underflow the array and bail.
Fixes: CVE-2021-3696
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/png.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 1e35eae..0356f91 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -420,6 +420,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len)
for (i = len; i < ht->max_length; i++)
n += ht->maxval[i];
+ if (n > ht->num_values)
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "png: out of range inserting huffman table item");
+ return;
+ }
+
for (i = 0; i < n; i++)
ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1];
--
2.17.1

View File

@@ -0,0 +1,79 @@
From a10c2350a766f9b315735931a49499a7e2c77bf3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 4 Sep 2023 16:32:43 +0800
Subject: [PATCH 3/6] video/readers/jpeg: Block int underflow -> wild pointer
write
Certain 1 px wide images caused a wild pointer write in
grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(),
we have the following loop:
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
We did not check if vb * width >= hb * nc1.
On a 64-bit platform, if that turns out to be negative, it will underflow,
be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so
we see data->bitmap_ptr jump, e.g.:
0x6180_0000_0480 to
0x6181_0000_0498
^
~--- carry has occurred and this pointer is now far away from
any object.
On a 32-bit platform, it will decrement the pointer, creating a pointer
that won't crash but will overwrite random data.
Catch the underflow and error out.
Fixes: CVE-2021-3697
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
[lz: Adapt the patch for context changes]
Signed-off-by: Li Zhou <li.zhou@windriver.com>
---
grub-core/video/readers/jpeg.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 0eeea0e..fdaef18 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.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+");
@@ -643,6 +644,7 @@ static grub_err_t
grub_jpeg_decode_data (struct grub_jpeg_data *data)
{
unsigned c1, vb, hb, nr1, nc1;
+ unsigned stride_a, stride_b, stride;
int rst = data->dri;
vb = 8 << data->log_vs;
@@ -654,8 +656,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
return grub_error(GRUB_ERR_BAD_FILE_TYPE,
"jpeg: attempted to decode data before start of stream");
+ if (grub_mul(vb, data->image_width, &stride_a) ||
+ grub_mul(hb, nc1, &stride_b) ||
+ grub_sub(stride_a, stride_b, &stride))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: cannot decode image with these dimensions");
+
for (; data->r1 < nr1 && (!data->dri || rst);
- data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+ data->r1++, data->bitmap_ptr += stride * 3)
for (c1 = 0; c1 < nc1 && (!data->dri || rst);
c1++, rst--, data->bitmap_ptr += hb * 3)
{
--
2.17.1

View File

@@ -0,0 +1,46 @@
From 5d2f1e350e39677938a70c17a163f1a9cde36a18 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 20 Dec 2021 19:41:21 +1100
Subject: [PATCH 4/6] net/ip: Do IP fragment maths safely
This avoids an underflow and subsequent unpleasantness.
Fixes: CVE-2022-28733
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/ip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index ea5edf8..74e4e8b 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -25,6 +25,7 @@
#include <grub/net/netbuff.h>
#include <grub/mm.h>
#include <grub/priority_queue.h>
+#include <grub/safemath.h>
#include <grub/time.h>
struct iphdr {
@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
{
rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
+ (nb->tail - nb->data));
- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
+
+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
+ &rsm->total_len))
+ {
+ grub_dprintf ("net", "IP reassembly size underflow\n");
+ return GRUB_ERR_NONE;
+ }
+
rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
if (!rsm->asm_netbuff)
{
--
2.17.1

View File

@@ -0,0 +1,48 @@
From f37943427c5bf16a0003d3049221da698006f6f3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 18:17:03 +1100
Subject: [PATCH 5/6] net/http: Fix OOB write for split http headers
GRUB has special code for handling an http header that is split
across two packets.
The code tracks the end of line by looking for a "\n" byte. The
code for split headers has always advanced the pointer just past the
end of the line, whereas the code that handles unsplit headers does
not advance the pointer. This extra advance causes the length to be
one greater, which breaks an assumption in parse_line(), leading to
it writing a NUL byte one byte past the end of the buffer where we
reconstruct the line from the two packets.
It's conceivable that an attacker controlled set of packets could
cause this to zero out the first byte of the "next" pointer of the
grub_mm_region structure following the current_line buffer.
Do not advance the pointer in the split header case.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index b616cf4..a19b0a2 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -190,9 +190,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
int have_line = 1;
char *t;
ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data);
- if (ptr)
- ptr++;
- else
+ if (ptr == NULL)
{
have_line = 0;
ptr = (char *) nb->tail;
--
2.17.1

View File

@@ -0,0 +1,50 @@
From c96929e9eea455b07e0c2e06bc401eea6bf2be11 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 8 Mar 2022 19:04:40 +1100
Subject: [PATCH 6/6] net/http: Error out on headers with LF without CR
In a similar vein to the previous patch, parse_line() would write
a NUL byte past the end of the buffer if there was an HTTP header
with a LF rather than a CRLF.
RFC-2616 says:
Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value (as defined in section 3.6).
We don't support quoted sections or continuation lines, etc.
If we see an LF that's not part of a CRLF, bail out.
Fixes: CVE-2022-28734
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/http.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index a19b0a2..1fa62b5 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len)
char *end = ptr + len;
while (end > ptr && *(end - 1) == '\r')
end--;
+
+ /* LF without CR. */
+ if (end == ptr + len)
+ {
+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR"));
+ return GRUB_ERR_NONE;
+ }
*end = 0;
+
/* Trailing CRLF. */
if (data->in_chunk_len == 1)
{
--
2.17.1

View File

@@ -0,0 +1,129 @@
From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:02:04 +0100
Subject: [PATCH] loader/efi/chainloader: Simplify the loader state
The chainloader command retains the source buffer and device path passed
to LoadImage(), requiring the unload hook passed to grub_loader_set() to
free them. It isn't required to retain this state though - they aren't
required by StartImage() or anything else in the boot hook, so clean them
up before grub_cmd_chainloader() finishes.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1469983ebb9674753ad333d37087fb8cb20e1dce
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 38 +++++++++++++++++-------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2bd80f4db..d1602c89b 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,25 +44,20 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_physical_address_t address;
-static grub_efi_uintn_t pages;
-static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
-static grub_efi_char16_t *cmdline;
static grub_err_t
grub_chainloader_unload (void)
{
+ grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
+ loaded_image = grub_efi_get_loaded_image (image_handle);
+ if (loaded_image != NULL)
+ grub_free (loaded_image->load_options);
+
b = grub_efi_system_table->boot_services;
efi_call_1 (b->unload_image, image_handle);
- efi_call_2 (b->free_pages, address, pages);
-
- grub_free (file_path);
- grub_free (cmdline);
- cmdline = 0;
- file_path = 0;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -140,7 +135,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
char *dir_start;
char *dir_end;
grub_size_t size;
- grub_efi_device_path_t *d;
+ grub_efi_device_path_t *d, *file_path;
dir_start = grub_strchr (filename, ')');
if (! dir_start)
@@ -222,11 +217,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_device_t dev = 0;
- grub_efi_device_path_t *dp = 0;
+ grub_efi_device_path_t *dp = NULL, *file_path = NULL;
grub_efi_loaded_image_t *loaded_image;
char *filename;
void *boot_image = 0;
grub_efi_handle_t dev_handle = 0;
+ grub_efi_physical_address_t address = 0;
+ grub_efi_uintn_t pages = 0;
+ grub_efi_char16_t *cmdline = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -234,11 +232,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_dl_ref (my_mod);
- /* Initialize some global variables. */
- address = 0;
- image_handle = 0;
- file_path = 0;
-
b = grub_efi_system_table->boot_services;
file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
@@ -408,6 +401,10 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_file_close (file);
grub_device_close (dev);
+ /* We're finished with the source image buffer and file path now. */
+ efi_call_2 (b->free_pages, address, pages);
+ grub_free (file_path);
+
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
return 0;
@@ -419,11 +416,18 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (file)
grub_file_close (file);
+ grub_free (cmdline);
grub_free (file_path);
if (address)
efi_call_2 (b->free_pages, address, pages);
+ if (image_handle != NULL)
+ {
+ efi_call_1 (b->unload_image, image_handle);
+ image_handle = NULL;
+ }
+
grub_dl_unref (my_mod);
return grub_errno;
--
2.34.1

View File

@@ -0,0 +1,168 @@
From 14ceb3b3ff6db664649138442b6562c114dcf56e Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 10:58:28 +0100
Subject: [PATCH] commands/boot: Add API to pass context to loader
Loaders rely on global variables for saving context which is consumed
in the boot hook and freed in the unload hook. In the case where a loader
command is executed twice, calling grub_loader_set() a second time executes
the unload hook, but in some cases this runs when the loader's global
context has already been updated, resulting in the updated context being
freed and potential use-after-free bugs when the boot hook is subsequently
called.
This adds a new API, grub_loader_set_ex(), which allows a loader to specify
context that is passed to its boot and unload hooks. This is an alternative
to requiring that loaders call grub_loader_unset() before mutating their
global context.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=14ceb3b3ff6db664649138442b6562c114dcf56e
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/commands/boot.c | 66 ++++++++++++++++++++++++++++++++++-----
include/grub/loader.h | 5 +++
2 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c
index bbca81e94..61514788e 100644
--- a/grub-core/commands/boot.c
+++ b/grub-core/commands/boot.c
@@ -27,10 +27,20 @@
GRUB_MOD_LICENSE ("GPLv3+");
-static grub_err_t (*grub_loader_boot_func) (void);
-static grub_err_t (*grub_loader_unload_func) (void);
+static grub_err_t (*grub_loader_boot_func) (void *context);
+static grub_err_t (*grub_loader_unload_func) (void *context);
+static void *grub_loader_context;
static int grub_loader_flags;
+struct grub_simple_loader_hooks
+{
+ grub_err_t (*boot) (void);
+ grub_err_t (*unload) (void);
+};
+
+/* Don't heap allocate this to avoid making grub_loader_set() fallible. */
+static struct grub_simple_loader_hooks simple_loader_hooks;
+
struct grub_preboot
{
grub_err_t (*preboot_func) (int);
@@ -44,6 +54,29 @@ static int grub_loader_loaded;
static struct grub_preboot *preboots_head = 0,
*preboots_tail = 0;
+static grub_err_t
+grub_simple_boot_hook (void *context)
+{
+ struct grub_simple_loader_hooks *hooks;
+
+ hooks = (struct grub_simple_loader_hooks *) context;
+ return hooks->boot ();
+}
+
+static grub_err_t
+grub_simple_unload_hook (void *context)
+{
+ struct grub_simple_loader_hooks *hooks;
+ grub_err_t ret;
+
+ hooks = (struct grub_simple_loader_hooks *) context;
+
+ ret = hooks->unload ();
+ grub_memset (hooks, 0, sizeof (*hooks));
+
+ return ret;
+}
+
int
grub_loader_is_loaded (void)
{
@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd)
}
void
-grub_loader_set (grub_err_t (*boot) (void),
- grub_err_t (*unload) (void),
- int flags)
+grub_loader_set_ex (grub_err_t (*boot) (void *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags)
{
if (grub_loader_loaded && grub_loader_unload_func)
- grub_loader_unload_func ();
+ grub_loader_unload_func (grub_loader_context);
grub_loader_boot_func = boot;
grub_loader_unload_func = unload;
+ grub_loader_context = context;
grub_loader_flags = flags;
grub_loader_loaded = 1;
}
+void
+grub_loader_set (grub_err_t (*boot) (void),
+ grub_err_t (*unload) (void),
+ int flags)
+{
+ grub_loader_set_ex (grub_simple_boot_hook,
+ grub_simple_unload_hook,
+ &simple_loader_hooks,
+ flags);
+
+ simple_loader_hooks.boot = boot;
+ simple_loader_hooks.unload = unload;
+}
+
void
grub_loader_unset(void)
{
if (grub_loader_loaded && grub_loader_unload_func)
- grub_loader_unload_func ();
+ grub_loader_unload_func (grub_loader_context);
grub_loader_boot_func = 0;
grub_loader_unload_func = 0;
+ grub_loader_context = 0;
grub_loader_loaded = 0;
}
@@ -158,7 +208,7 @@ grub_loader_boot (void)
return err;
}
}
- err = (grub_loader_boot_func) ();
+ err = (grub_loader_boot_func) (grub_loader_context);
for (cur = preboots_tail; cur; cur = cur->prev)
if (! err)
diff --git a/include/grub/loader.h b/include/grub/loader.h
index b20864282..97f231054 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
grub_err_t (*unload) (void),
int flags);
+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *context),
+ grub_err_t (*unload) (void *context),
+ void *context,
+ int flags);
+
/* Unset current loader, if any. */
void EXPORT_FUNC (grub_loader_unset) (void);
--
2.34.1

View File

@@ -0,0 +1,86 @@
From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 5 Apr 2022 11:48:58 +0100
Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex()
This ports the EFI chainloader to use grub_loader_set_ex() in order to fix
a use-after-free bug that occurs when grub_cmd_chainloader() is executed
more than once before a boot attempt is performed.
Fixes: CVE-2022-28736
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Upstream-Status: Backport
CVE: CVE-2022-28736
Reference to upstream patch:
https://git.savannah.gnu.org/cgit/grub.git/commit/?id=04c86e0bb7b58fc2f913f798cdb18934933e532d
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
---
grub-core/loader/efi/chainloader.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index d1602c89b..7557eb269 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -44,11 +44,10 @@ GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
-static grub_efi_handle_t image_handle;
-
static grub_err_t
-grub_chainloader_unload (void)
+grub_chainloader_unload (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_loaded_image_t *loaded_image;
grub_efi_boot_services_t *b;
@@ -64,8 +63,9 @@ grub_chainloader_unload (void)
}
static grub_err_t
-grub_chainloader_boot (void)
+grub_chainloader_boot (void *context)
{
+ grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
@@ -225,6 +225,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_efi_physical_address_t address = 0;
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
+ grub_efi_handle_t image_handle = NULL;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
@@ -405,7 +406,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
grub_free (file_path);
- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
return 0;
fail:
@@ -423,10 +424,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
efi_call_2 (b->free_pages, address, pages);
if (image_handle != NULL)
- {
- efi_call_1 (b->unload_image, image_handle);
- image_handle = NULL;
- }
+ efi_call_1 (b->unload_image, image_handle);
grub_dl_unref (my_mod);
--
2.34.1

View File

@@ -0,0 +1,89 @@
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:31:57 +0300
Subject: fs/ntfs: Fix an OOB write when parsing the $ATTRIBUTE_LIST attribute
for the $MFT file
When parsing an extremely fragmented $MFT file, i.e., the file described
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
containing bytes read from the underlying drive to store sector numbers,
which are consumed later to read data from these sectors into another buffer.
These sectors numbers, two 32-bit integers, are always stored at predefined
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
However, when parsing a specially-crafted file system image, this may cause
the NTFS code to write these integers beyond the buffer boundary, likely
causing the GRUB memory allocator to misbehave or fail. These integers contain
values which are controlled by on-disk structures of the NTFS file system.
Such modification and resulting misbehavior may touch a memory range not
assigned to the GRUB and owned by firmware or another EFI application/driver.
This fix introduces checks to ensure that these sector numbers are never
written beyond the boundary.
Fixes: CVE-2023-4692
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index bbdbe24..c3c4db1 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
if (at->attr_end)
{
- grub_uint8_t *pa;
+ grub_uint8_t *pa, *pa_end;
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
if (at->emft_buf == NULL)
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
at->attr_nxt = at->edat_buf;
at->attr_end = at->edat_buf + u32at (pa, 0x30);
+ pa_end = at->edat_buf + n;
}
else
{
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
at->attr_end = at->attr_end + u32at (pa, 4);
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
}
at->flags |= GRUB_NTFS_AF_ALST;
while (at->attr_nxt < at->attr_end)
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
at->flags |= GRUB_NTFS_AF_GPOS;
at->attr_cur = at->attr_nxt;
pa = at->attr_cur;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
grub_set_unaligned32 ((char *) pa + 0x10,
grub_cpu_to_le32 (at->mft->data->mft_start));
grub_set_unaligned32 ((char *) pa + 0x14,
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
{
if (*pa != attr)
break;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
if (read_attr
(at, pa + 0x10,
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),

View File

@@ -0,0 +1,54 @@
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:32:33 +0300
Subject: fs/ntfs: Fix an OOB read when reading data from the resident $DATA
attribute
When reading a file containing resident data, i.e., the file data is stored in
the $DATA attribute within the NTFS file record, not in external clusters,
there are no checks that this resident data actually fits the corresponding
file record segment.
When parsing a specially-crafted file system image, the current NTFS code will
read the file data from an arbitrary, attacker-chosen memory offset and of
arbitrary, attacker-chosen length.
This allows an attacker to display arbitrary chunks of memory, which could
contain sensitive information like password hashes or even plain-text,
obfuscated passwords from BS EFI variables.
This fix implements a check to ensure that resident data is read from the
corresponding file record segment only.
Fixes: CVE-2023-4693
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index c3c4db1..a68e173 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
{
if (ofs + len > u32at (pa, 0x10))
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
+
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
+
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
return 0;
}

View File

@@ -0,0 +1,28 @@
0001-grub2-add-tboot.patch
0002-grub2-checking-if-loop-devices-are-available.patch
0003-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch
0004-video-readers-Add-artificial-limit-to-image-dimensio.patch
0005-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch
0006-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch
0007-font-Fix-several-integer-overflows-in-grub_font_cons.patch
0008-font-Remove-grub_font_dup_glyph.patch
0009-font-Fix-integer-overflow-in-ensure_comb_space.patch
0010-font-Fix-integer-overflow-in-BMP-index.patch
0011-font-Fix-integer-underflow-in-binary-search-of-char-.patch
0012-kern-efi-sb-Enforce-verification-of-font-files.patch
0013-fbutil-Fix-integer-overflow.patch
0014-font-Fix-an-integer-underflow-in-blit_comb.patch
0015-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch
0016-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
0017-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
0018-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
0019-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
0020-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
0021-net-ip-Do-IP-fragment-maths-safely.patch
0022-net-http-Fix-OOB-write-for-split-http-headers.patch
0023-net-http-Error-out-on-headers-with-LF-without-CR.patch
0024-loader-efi-chainloader-Simplify-the-loader-state.patch
0025-commands-boot-Add-API-to-pass-context-to-loader.patch
0026-loader-efi-chainloader-Use-grub_loader_set_ex.patch
0027-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
0028-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch

View File

@@ -0,0 +1,5 @@
grubby (8.4-1) unstable; urgency=medium
* Initial release.
-- Charles Short <charles.short@windriver.com> Wed, 02 Feb 2022 13:30:33 +0000

View File

@@ -0,0 +1,16 @@
Source: grubby
Section: admin
Priority: optional
Maintainer: StarlingX Developers <starlingx-dev@lists.starlingx.io>
Build-Depends: debhelper-compat (= 13), libblkid-dev, libpopt-dev
Standards-Version: 4.5.1
Homepage: https://www.github.com/rhboot/grubby
Rules-Requires-Root: no
Package: grubby
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Command line tool for updating bootloader configs
This package provides a grubby compatibility script that manages
BootLoaderSpec files and is meant to be backward compatible with
the previous grubby tool.

View File

@@ -0,0 +1,41 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: grubby
Source: https://github.com/rhboot/grubby
Files: *
Copyright: (C) 2007 - 2009 Red Hat, Inc. All rights reserved.
License: GPL-2+
This package 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 2 of the License, or
(at your option) any later version.
.
This package 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 this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
Files: debian/*
Copyright: 2022 Wind River
License: GPL-2+
This package 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 2 of the License, or
(at your option) any later version.
.
This package 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 this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

View File

@@ -0,0 +1,24 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#export DH_VERBOSE = 1
%:
dh $@
override_dh_install:
# nothing to be done here
override_dh_auto_install:
mkdir -p $(CURDIR)/debian/grubby/usr/sbin
mkdir -p $(CURDIR)/debian/grubby/usr/share/man/man8
install -m 755 grubby $(CURDIR)/debian/grubby/usr/sbin/grubby
install -m 755 installkernel $(CURDIR)/debian/grubby/usr/sbin/installkernel
install -m 755 new-kernel-pkg $(CURDIR)/debian/grubby/usr/sbin/new-kernel-pkg
cp grubby.8 $(CURDIR)/debian/grubby/usr/share/man/man8
cp new-kernel-pkg.8 $(CURDIR)/debian/grubby/usr/share/man/man8
dh_install
override_dh_auto_test:
# nothing to be done here

View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -0,0 +1,11 @@
---
debname: grubby
debver: 8.4
dl_path:
name: grubby-8.4.tar.gz
url: https://github.com/rhboot/grubby/archive/66fd06e2346a9f334a4e5d426332e74319f927c2.tar.gz
md5sum: cbe22140baf6569f19c2e6149ea7748b
sha256sum: 1369940637b27f47fb6225168c76e3798f1d9c1ba7f8859b8754324e17415c77
revision:
dist: $STX_DIST
PKG_GITREVCOUNT: true