commit: 940eefc07945dbf5d50dc818c3557e90a0d860f4
Author: Andrew Ammerlaan <andrewammerlaan <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 7 14:31:33 2024 +0000
Commit: Andrew Ammerlaan <andrewammerlaan <AT> gentoo <DOT> org>
CommitDate: Wed Aug 7 19:21:21 2024 +0000
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=940eefc0
sys-boot/grub: implement USE=secureboot via grub-mkstandalone
This makes it possible to create a pre-built grub EFI executable signed for
secureboot via portage/`secureboot.eclass`.
It greatly simplifies setting up grub with secureboot, which is now a bit of a
tricky section in the handbook, and makes it possible to get a signed grub EFI
executable on systems that do not have the `SECUREBOOT_SIGN_KEY` available via
a `sys-boot/grub[secureboot]` binpkg.
Unfortunately, since the use of boot partitions, and the mounting point of
ESP's varies between systems we cannot rely on the default
`/boot/grub/grub.cfg` location to configure grub. Instead the standalone
executable reads the `grub.cfg` in the same directory it is in.
It is then up to the user to either:
- configure `sys-kernel/installkernel` to put the `grub.cfg` in a different
location via `GRUB_CFG=`, or
- add a little `grub.cfg` that chainloads the real `grub.cfg`.
To make this even easier we could write some wrapper around grub-install which
would optionally install the prebuilt standalone EFI executable plus an
appropriate little `grub.cfg` to chainload the usual `grub.cfg`. But lets
leave that for later.
Signed-off-by: Andrew Ammerlaan <andrewammerlaan <AT> gentoo.org>
Closes: https://github.com/gentoo/gentoo/pull/38007
Signed-off-by: Andrew Ammerlaan <andrewammerlaan <AT> gentoo.org>
.../grub/{grub-9999.ebuild => grub-2.12-r5.ebuild} | 99 ++++++++++++++++++++--
sys-boot/grub/grub-9999.ebuild | 86 ++++++++++++++++++-
2 files changed, 178 insertions(+), 7 deletions(-)
diff --git a/sys-boot/grub/grub-9999.ebuild b/sys-boot/grub/grub-2.12-r5.ebuild
similarity index 73%
copy from sys-boot/grub/grub-9999.ebuild
copy to sys-boot/grub/grub-2.12-r5.ebuild
index f007f3aaa884..1e22477b727a 100644
--- a/sys-boot/grub/grub-9999.ebuild
+++ b/sys-boot/grub/grub-2.12-r5.ebuild
@@ -16,11 +16,7 @@ EAPI=7
# If any of the above applies to a user patch, the user should set the
# corresponding variable in make.conf or the environment.
-if [[ ${PV} == 9999 ]]; then
- GRUB_AUTORECONF=1
- GRUB_BOOTSTRAP=1
-fi
-
+GRUB_AUTORECONF=1
PYTHON_COMPAT=( python3_{10..12} )
WANT_LIBTOOL=none
VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/dkiper.gpg
@@ -29,7 +25,8 @@ if [[ -n ${GRUB_AUTORECONF} ]]; then
inherit autotools
fi
-inherit bash-completion-r1 flag-o-matic multibuild optfeature python-any-r1
toolchain-funcs
+inherit bash-completion-r1 flag-o-matic multibuild optfeature python-any-r1
+inherit secureboot toolchain-funcs
DESCRIPTION="GNU GRUB boot loader"
HOMEPAGE="https://www.gnu.org/software/grub/"
@@ -49,6 +46,7 @@ if [[ ${PV} != 9999 ]]; then
else
SRC_URI="
mirror://gnu/${PN}/${P}.tar.xz
+
https://dev.gentoo.org/~floppym/dist/${P}-bash-completion.patch.gz
verify-sig? ( mirror://gnu/${PN}/${P}.tar.xz.sig )
"
S=${WORKDIR}/${P%_*}
@@ -161,6 +159,8 @@ src_prepare() {
"${FILESDIR}"/gfxpayload.patch
"${FILESDIR}"/grub-2.02_beta2-KERNEL_GLOBS.patch
"${FILESDIR}"/grub-2.06-test-words.patch
+ "${FILESDIR}"/grub-2.12-fwsetup.patch
+ "${WORKDIR}"/grub-2.12-bash-completion.patch
)
default
@@ -177,6 +177,10 @@ src_prepare() {
if [[ -n ${GRUB_AUTORECONF} ]]; then
eautoreconf
fi
+
+ # Avoid error due to extra_deps.lst missing from source tarball:
+ # make[3]: *** No rule to make target 'grub-core/extra_deps.lst',
needed by 'syminfo.lst'. Stop.
+ echo "depends bli part_gpt" > grub-core/extra_deps.lst || die
}
grub_do() {
@@ -291,6 +295,70 @@ src_test() {
grub_do emake -j1 check
}
+grub_mkstandalone_secureboot() {
+ use secureboot || return
+
+ if tc-is-cross-compiler; then
+ ewarn "USE=secureboot is not supported when cross-compiling."
+ ewarn "No standalone EFI executable will be built."
+ return 1
+ fi
+
+ local standalone_targets
+
+ case ${CTARGET:-${CHOST}} in
+ i?86* | x86_64*)
+ use grub_platforms_efi-32 && standalone_targets+=(
i386-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
x86_64-efi )
+ ;;
+ arm* | aarch64*)
+ use grub_platforms_efi-32 && standalone_targets+=(
arm-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
arm64-efi )
+ ;;
+ riscv*)
+ use grub_platforms_efi-32 && standalone_targets+=(
riscv32-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
riscv64-efi )
+ ;;
+ ia64*)
+ use grub_platforms_efi-64 && standalone_targets+=(
ia64-efi )
+ ;;
+ loongarch64*)
+ use grub_platforms_efi-64 && standalone_targets+=(
loongarch64-efi )
+ ;;
+ esac
+
+ if [[ ${#standalone_targets[@]} -eq 0 ]]; then
+ ewarn "USE=secureboot is enabled, but no suitable EFI target in
GRUB_PLATFORMS."
+ ewarn "No standalone EFI executable will be built."
+ return 1
+ fi
+
+ local target mkstandalone_args
+
+ # grub-mkstandalone embeds a config file, make this config file
chainload
+ # a config file in the same directory grub is installed in. This
requires
+ # pre-loading the part_gpt and part_msdos modules.
+ echo 'configfile ${cmdpath}/grub.cfg' > "${T}/grub.cfg" || die
+ for target in "${standalone_targets[@]}"; do
+ ebegin "Building standalone EFI executable for ${target}"
+ mkstandalone_args=(
+ --verbose
+ --directory="${ED}/usr/lib/grub/${target}"
+ --locale-directory="${ED}/usr/share/locale"
+ --format="${target}"
+ --modules="part_gpt part_msdos"
+ --sbat="${ED}/usr/share/grub/sbat.csv"
+ --output="${ED}/usr/lib/grub/grub-${target%-efi}.efi"
+ "boot/grub/grub.cfg=${T}/grub.cfg"
+ )
+
+ "${ED}/usr/bin/grub-mkstandalone" "${mkstandalone_args[@]}"
+ eend ${?} || die "grub-mkstandalone failed to build EFI
executable"
+ done
+
+ secureboot_auto_sign
+}
+
src_install() {
grub_do emake install DESTDIR="${D}"
bashcompletiondir="$(get_bashcompdir)"
use doc && grub_do_once emake -C docs install-html DESTDIR="${D}"
@@ -311,6 +379,8 @@ src_install() {
# https://bugs.gentoo.org/900348
QA_CONFIG_IMPL_DECL_SKIP=(
re_{compile_pattern,match,search,set_syntax} )
fi
+
+ grub_mkstandalone_secureboot
}
pkg_postinst() {
@@ -345,4 +415,21 @@ pkg_postinst() {
ewarn "Due to security concerns, os-prober is disabled by
default."
ewarn "Set GRUB_DISABLE_OS_PROBER=false in /etc/default/grub to
enable it."
fi
+
+ if use secureboot; then
+ elog
+ elog "The signed standalone grub EFI executable(s) are
available in:"
+ elog " /usr/lib/grub/grub-<target>.efi(.signed)"
+ elog "These EFI executables should be copied to the usual
location at:"
+ elog " ESP/EFI/Gentoo/grub<arch>.efi"
+ elog "Note that 'grub-install' does not install these images."
+ elog
+ elog "These standalone grub executables read the grub config
file from"
+ elog "the grub.cfg in the same directory instead of the default"
+ elog "/boot/grub/grub.cfg. When sys-kernel/installkernel[grub]
is used,"
+ elog "the location of the grub.cfg may be overridden by setting
the"
+ elog "GRUB_CFG environment variable:"
+ elog " GRUB_CFG=ESP/EFI/Gentoo/grub.cfg"
+ elog
+ fi
}
diff --git a/sys-boot/grub/grub-9999.ebuild b/sys-boot/grub/grub-9999.ebuild
index f007f3aaa884..2b24a0433912 100644
--- a/sys-boot/grub/grub-9999.ebuild
+++ b/sys-boot/grub/grub-9999.ebuild
@@ -29,7 +29,8 @@ if [[ -n ${GRUB_AUTORECONF} ]]; then
inherit autotools
fi
-inherit bash-completion-r1 flag-o-matic multibuild optfeature python-any-r1
toolchain-funcs
+inherit bash-completion-r1 flag-o-matic multibuild optfeature python-any-r1
+inherit secureboot toolchain-funcs
DESCRIPTION="GNU GRUB boot loader"
HOMEPAGE="https://www.gnu.org/software/grub/"
@@ -291,6 +292,70 @@ src_test() {
grub_do emake -j1 check
}
+grub_mkstandalone_secureboot() {
+ use secureboot || return
+
+ if tc-is-cross-compiler; then
+ ewarn "USE=secureboot is not supported when cross-compiling."
+ ewarn "No standalone EFI executable will be built."
+ return 1
+ fi
+
+ local standalone_targets
+
+ case ${CTARGET:-${CHOST}} in
+ i?86* | x86_64*)
+ use grub_platforms_efi-32 && standalone_targets+=(
i386-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
x86_64-efi )
+ ;;
+ arm* | aarch64*)
+ use grub_platforms_efi-32 && standalone_targets+=(
arm-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
arm64-efi )
+ ;;
+ riscv*)
+ use grub_platforms_efi-32 && standalone_targets+=(
riscv32-efi )
+ use grub_platforms_efi-64 && standalone_targets+=(
riscv64-efi )
+ ;;
+ ia64*)
+ use grub_platforms_efi-64 && standalone_targets+=(
ia64-efi )
+ ;;
+ loongarch64*)
+ use grub_platforms_efi-64 && standalone_targets+=(
loongarch64-efi )
+ ;;
+ esac
+
+ if [[ ${#standalone_targets[@]} -eq 0 ]]; then
+ ewarn "USE=secureboot is enabled, but no suitable EFI target in
GRUB_PLATFORMS."
+ ewarn "No standalone EFI executable will be built."
+ return 1
+ fi
+
+ local target mkstandalone_args
+
+ # grub-mkstandalone embeds a config file, make this config file
chainload
+ # a config file in the same directory grub is installed in. This
requires
+ # pre-loading the part_gpt and part_msdos modules.
+ echo 'configfile ${cmdpath}/grub.cfg' > "${T}/grub.cfg" || die
+ for target in "${standalone_targets[@]}"; do
+ ebegin "Building standalone EFI executable for ${target}"
+ mkstandalone_args=(
+ --verbose
+ --directory="${ED}/usr/lib/grub/${target}"
+ --locale-directory="${ED}/usr/share/locale"
+ --format="${target}"
+ --modules="part_gpt part_msdos"
+ --sbat="${ED}/usr/share/grub/sbat.csv"
+ --output="${ED}/usr/lib/grub/grub-${target%-efi}.efi"
+ "boot/grub/grub.cfg=${T}/grub.cfg"
+ )
+
+ "${ED}/usr/bin/grub-mkstandalone" "${mkstandalone_args[@]}"
+ eend ${?} || die "grub-mkstandalone failed to build EFI
executable"
+ done
+
+ secureboot_auto_sign
+}
+
src_install() {
grub_do emake install DESTDIR="${D}"
bashcompletiondir="$(get_bashcompdir)"
use doc && grub_do_once emake -C docs install-html DESTDIR="${D}"
@@ -311,6 +376,8 @@ src_install() {
# https://bugs.gentoo.org/900348
QA_CONFIG_IMPL_DECL_SKIP=(
re_{compile_pattern,match,search,set_syntax} )
fi
+
+ grub_mkstandalone_secureboot
}
pkg_postinst() {
@@ -345,4 +412,21 @@ pkg_postinst() {
ewarn "Due to security concerns, os-prober is disabled by
default."
ewarn "Set GRUB_DISABLE_OS_PROBER=false in /etc/default/grub to
enable it."
fi
+
+ if use secureboot; then
+ elog
+ elog "The signed standalone grub EFI executable(s) are
available in:"
+ elog " /usr/lib/grub/grub-<target>.efi(.signed)"
+ elog "These EFI executables should be copied to the usual
location at:"
+ elog " ESP/EFI/Gentoo/grub<arch>.efi"
+ elog "Note that 'grub-install' does not install these images."
+ elog
+ elog "These standalone grub executables read the grub config
file from"
+ elog "the grub.cfg in the same directory instead of the default"
+ elog "/boot/grub/grub.cfg. When sys-kernel/installkernel[grub]
is used,"
+ elog "the location of the grub.cfg may be overridden by setting
the"
+ elog "GRUB_CFG environment variable:"
+ elog " GRUB_CFG=ESP/EFI/Gentoo/grub.cfg"
+ elog
+ fi
}