[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Change "efi" to "EFI" in grub-mkrescue for secure boot
From: |
Askar Safin |
Subject: |
[PATCH] Change "efi" to "EFI" in grub-mkrescue for secure boot |
Date: |
Fri, 6 Sep 2024 16:15:10 +0300 |
Hi. I propose changing "efi" to "EFI" in grub-mkrescue, because this is needed
for secure boot. Please, apply patch below. Here is why.
First of all, iso9660 file system is case sensitive from GRUB point of view. I.
e. if you have directory named "efi" in iso9660, then GRUB command "ls /EFI"
will not work.
Second, it seems that "EFI", as opposed to "efi", is standard among Linux CDs.
I examined the following .iso files:
- Debian installer
- Debian live image
- Ubuntu live image
- Fedora network install
All they have "EFI", as opposed to "efi".
And main argument: I'm aware of one example when "EFI" is hard-coded in signed
secure boot GRUB binary. Debian has 4 signed GRUB binaries. All they are
generated here:
https://sources.debian.org/src/grub2/2.12-5/debian/build-efi-images/ . One of
them, grubx64.efi is created using "grub-mkimage ... -p /EFI/debian". The
binary is signed, so I cannot change it if I want secure boot support. So if I
want to use this binary, I should have directory named exactly "EFI".
You may say: "But grub-mkrescue doesn't support secure boot". Yes, it doesn't
support it. But I think this patch will simplify adding secure boot support by
distributions.
Now let me describe in detail why I need all this. Also I will show you results
of additional experiments.
I attempted to create bootable GRUB disk using grub-mkrescue. I wanted the disk
to support secure boot. I failed. I don't remember why. It is possible that
this EFI vs efi issue was one of the problems. So I resorted to writing script,
which replaces grub-mkrescue. This is simplified version of that script. Note:
this is simplification written specially for presenting here. So I
intentionally dropped things I would not drop in real code.
====
#!/bin/bash
# This script is merely demonstration created specially to present on GRUB
mailing list. So it intentionally drops some important things
# This script can be run on any Linux distro
# This script creates isohybrid disk, which supports UEFI booting
# The disk can be used both as CD image and as USB disk image
# So, in total 2 boot modes are supported: UEFI-CD and UEFI-USB
# Secure boot is supported
# This script can be run on any Linux distro (but was tested on Debian only).
# The script doesn't rely on specific files present in specific places, it
downloads all its dependencies
# This script doesn't support "EFI file system transposition" (
https://lists.gnu.org/archive/html/grub-devel/2022-06/msg00024.html ). This is
intentional, because this is just a demo
# The script was tested in Qemu only. Also secure boot was not tested
{
# This is just boilerplate I insert to all my bash scripts
set -e
set -u
set -o pipefail
shopt -s inherit_errexit
shopt -s nullglob
export LC_ALL=C.UTF-8
if [ $# != 1 ]; then
echo "Usage: ${0##*/} OUT" >&2
exit 1
fi
OUT="$1"
DIR="$(mktemp -d /tmp/grub-XXXXXX)"
mkdir -p "$DIR/esp/EFI/boot" "$DIR/esp/EFI/debian"
"$DIR/main-root/EFI/debian" "$DIR/main-root/boot/grub"
wget -O "$DIR/esp/EFI/boot/bootx64.efi"
'https://sources.debian.org/src/shim-signed/latest/shimx64.efi.signed/'
wget -O "$DIR/grub-efi-amd64-signed.deb"
'https://deb.debian.org/debian/pool/main/g/grub-efi-amd64-signed/grub-efi-amd64-signed_1+2.12+5_amd64.deb'
ar p "$DIR/grub-efi-amd64-signed.deb" data.tar.xz > "$DIR/data.tar.xz"
tar -xf "$DIR/data.tar.xz" --to-stdout
./usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed >
"$DIR/esp/EFI/boot/grubx64.efi"
cat << "EOF" > "$DIR/esp/EFI/debian/grub.cfg"
echo "This is /EFI/debian/grub.cfg from ESP"
echo "Testing shows that this file is loaded during UEFI-USB"
sleep 10
EOF
mkfs.vfat -C "$DIR/main-root/boot/grub/efi.img" 10000
mcopy -s -i "$DIR/main-root/boot/grub/efi.img" "$DIR/esp/EFI" ::/
cat << "EOF" > "$DIR/main-root/EFI/debian/grub.cfg"
echo "This is /EFI/debian/grub.cfg from main file system (iso9660)"
echo "Testing shows that this file is loaded during UEFI-CD"
sleep 10
EOF
# I don't know why this "$DIR/main-root/zero" is needed. Anyway this is just
a demo
dd if=/dev/zero of="$DIR/main-root/zero" bs=1M count=1
xorriso -as mkisofs -b /zero -no-emul-boot --efi-boot /boot/grub/efi.img
-efi-boot-part --efi-boot-image -o "$OUT" -r "$DIR/main-root"
rm -r "$DIR"
exit 0
}
====
While testing this script I noticed this: if I boot from disk (i. e. using
"-drive" Qemu option), then "grub.cfg" is read from ESP, i. e. FAT. But if I
boot from CD (i. e. using "-cdrom" Qemu option), then "grub.cfg" is read from
main .iso partition, i. e. iso9660. I don't know whether this is expected
behavior or just a bug.
FAT is case insensitive from GRUB point of view. But iso9660 is case sensitive.
So, the file (in case of CD boot) must be named exactly /EFI/debian/grub.cfg.
Name /efi/debian/grub.cfg will not work, I tested this. I. e. I replaced "EFI"
with "efi" everywhere in the script above and I saw that in case of UEFI-CD
file /efi/debian/grub.cfg is not read anymore. (Again: I checked in my
experiments nearly all statements I made in this letter.)
So, grub-mkrescue is incompatible with Debian's signed GRUB image
"grubx64.efi". So, if someone tries to create their custom .iso using
grub-mkrescue with secure boot support with that grubx64.efi, they will likely
fail. And they will have to resort to reimplementing grub-mkrescue (this is
what I did with script above). For this reason I suggest replacing "efi" with
"EFI" in grub-mkrescue.
You may say: "But why choose this signed binary? Debian has 3 other signed
binaries". Yes, it has. But all these 3 binaries contain complicated logic for
finding config. I don't like this. So I choose grubx64.efi for my personal GRUB
disk. Yes, I can choose from other 3 binaries. But I still think that this
patch is good thing. It allows one to choose grubx64.efi. I. e. this patch
allows new uses without removing existing ones.
Also, I kindly ask for making new GRUB release after applying this patch. This
is because I possibly will try to add secure boot support to Debian version of
GRUB. So I need GRUB to be released first. Of course, if I do this, I will
again think about what of these 4 binaries I should choose.
I send this letter to grub-devel. Also I CC Pete Batard, because it seems my
work is somehow related to his work on grub-mkrescue (
https://lists.gnu.org/archive/html/grub-devel/2022-06/msg00024.html ). I CC
Thomas Schmitt, because my work seems to be related to xorriso. I CC Adrian,
because I think the problem I talk about is the problem, which prevented
supergrubdisk from making image for CD with secure boot support (
https://github.com/supergrub/supergrub/commit/25414fcbbcb47c1d8616fa18d20409d570145b8f
).
Signed-off-by: Askar Safin <safinaskar@zohomail.com>
---
util/grub-mkrescue.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
index 6dc71a8a1..c78647ebe 100644
--- a/util/grub-mkrescue.c
+++ b/util/grub-mkrescue.c
@@ -771,8 +771,12 @@ main (int argc, char *argv[])
|| source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI])
{
FILE *f;
- char *efidir_efi = grub_util_path_concat (2, iso9660_dir, "efi");
- char *efidir_efi_boot = grub_util_path_concat (3, iso9660_dir, "efi",
"boot");
+
+ /* This directory should be named "EFI", not "efi". See September 2024
grub-devel discussion for details
+ ( https://lists.gnu.org/archive/html/grub-devel/2024-09/index.html )
+ */
+ char *efidir_efi = grub_util_path_concat (2, iso9660_dir, "EFI");
+ char *efidir_efi_boot = grub_util_path_concat (3, iso9660_dir, "EFI",
"boot");
char *imgname, *img32, *img64, *img_mac = NULL;
char *efiimgfat, *iso_uuid_file, *diskdir, *diskdir_uuid;
grub_install_mkdir_p (efidir_efi_boot);
--
2.43.0
- [PATCH] Change "efi" to "EFI" in grub-mkrescue for secure boot,
Askar Safin <=