Blame 0001-fix-dracut.sh-use-dynamically-uefi-s-sections-offset.patch

Lukas Nykryn 734137
From ec6972ab724c23edb47394e1211c4d3dc635ea8f Mon Sep 17 00:00:00 2001
Lukas Nykryn 734137
From: Valentin Lefebvre <valentin.lefebvre@suse.com>
Lukas Nykryn 734137
Date: Mon, 13 Mar 2023 12:06:13 +0100
Lukas Nykryn 734137
Subject: [PATCH] fix(dracut.sh): use dynamically uefi's sections offset
Lukas Nykryn 734137
Lukas Nykryn 734137
* Uefi section are creating by `objcopy` with hardcoded sections
Lukas Nykryn 734137
offset. This commit allow to have the correct offset between
Lukas Nykryn 734137
each part of the efi file, needed to create an UKI. Offsets
Lukas Nykryn 734137
are simply calculated so no sections overlap, as recommended
Lukas Nykryn 734137
in  https://wiki.archlinux.org/title/Unified_kernel_image#Manually
Lukas Nykryn 734137
Moreover, efi stub file's header is parsed to apply the correct
Lukas Nykryn 734137
offsets according the section alignment factor.
Lukas Nykryn 734137
* Remove EFI_SECTION_VMA_INITRD, no need anymore as initrd
Lukas Nykryn 734137
section offset dynamically calculated
Lukas Nykryn 734137
Lukas Nykryn 734137
Fixes dracutdevs#2275
Lukas Nykryn 734137
Lukas Nykryn 734137
Signed-off-by: Valentin Lefebvre <valentin.lefebvre@suse.com>
Lukas Nykryn 734137
---
Lukas Nykryn 734137
 dracut-functions.sh | 23 +++++++++++++++++++++++
Lukas Nykryn 734137
 dracut.sh           | 45 +++++++++++++++++++++++++++++++++++----------
Lukas Nykryn 734137
 2 files changed, 58 insertions(+), 10 deletions(-)
Lukas Nykryn 734137
Lukas Nykryn 734137
diff --git a/dracut-functions.sh b/dracut-functions.sh
Lukas Nykryn 734137
index 280e4e7..78547f3 100755
Lukas Nykryn 734137
--- a/dracut-functions.sh
Lukas Nykryn 734137
+++ b/dracut-functions.sh
Lukas Nykryn 734137
@@ -1011,3 +1011,26 @@ get_dev_module() {
Lukas Nykryn 734137
     fi
Lukas Nykryn 734137
     echo "$dev_drivers"
Lukas Nykryn 734137
 }
Lukas Nykryn 734137
+
Lukas Nykryn 734137
+# Check if file is in PE format
Lukas Nykryn 734137
+pe_file_format() {
Lukas Nykryn 734137
+    if [[ $# -eq 1 ]]; then
Lukas Nykryn 734137
+        local magic
Lukas Nykryn 734137
+        magic=$(objdump -p "$1" \
Lukas Nykryn 734137
+            | awk '{if ($1 == "Magic"){print strtonum("0x"$2)}}')
Lukas Nykryn 734137
+        magic=$(printf "0x%x" "$magic")
Lukas Nykryn 734137
+        # 0x10b (PE32), 0x20b (PE32+)
Lukas Nykryn 734137
+        [[ $magic == 0x20b || $magic == 0x10b ]] && return 0
Lukas Nykryn 734137
+    fi
Lukas Nykryn 734137
+    return 1
Lukas Nykryn 734137
+}
Lukas Nykryn 734137
+
Lukas Nykryn 734137
+# Get the sectionAlignment data from the PE header
Lukas Nykryn 734137
+pe_get_section_align() {
Lukas Nykryn 734137
+    local align_hex
Lukas Nykryn 734137
+    [[ $# -ne "1" ]] && return 1
Lukas Nykryn 734137
+    [[ $(pe_file_format "$1") -eq 1 ]] && return 1
Lukas Nykryn 734137
+    align_hex=$(objdump -p "$1" \
Lukas Nykryn 734137
+        | awk '{if ($1 == "SectionAlignment"){print $2}}')
Lukas Nykryn 734137
+    echo "$((16#$align_hex))"
Lukas Nykryn 734137
+}
Lukas Nykryn 734137
diff --git a/dracut.sh b/dracut.sh
Lukas Nykryn 734137
index 031dd85..f42ef89 100755
Lukas Nykryn 734137
--- a/dracut.sh
Lukas Nykryn 734137
+++ b/dracut.sh
Lukas Nykryn 734137
@@ -1447,7 +1447,6 @@ if [[ ! $print_cmdline ]]; then
Lukas Nykryn 734137
             exit 1
Lukas Nykryn 734137
         fi
Lukas Nykryn 734137
         unset EFI_MACHINE_TYPE_NAME
Lukas Nykryn 734137
-        EFI_SECTION_VMA_INITRD=0x3000000
Lukas Nykryn 734137
         case "${DRACUT_ARCH:-$(uname -m)}" in
Lukas Nykryn 734137
             x86_64)
Lukas Nykryn 734137
                 EFI_MACHINE_TYPE_NAME=x64
Lukas Nykryn 734137
@@ -1457,8 +1456,6 @@ if [[ ! $print_cmdline ]]; then
Lukas Nykryn 734137
                 ;;
Lukas Nykryn 734137
             aarch64)
Lukas Nykryn 734137
                 EFI_MACHINE_TYPE_NAME=aa64
Lukas Nykryn 734137
-                # aarch64 kernels are uncompressed and thus larger, so we need a bigger gap between vma sections
Lukas Nykryn 734137
-                EFI_SECTION_VMA_INITRD=0x4000000
Lukas Nykryn 734137
                 ;;
Lukas Nykryn 734137
             *)
Lukas Nykryn 734137
                 dfatal "Architecture '${DRACUT_ARCH:-$(uname -m)}' not supported to create a UEFI executable"
Lukas Nykryn 734137
@@ -2617,29 +2614,57 @@ if [[ $uefi == yes ]]; then
Lukas Nykryn 734137
         fi
Lukas Nykryn 734137
     fi
Lukas Nykryn 734137
 
Lukas Nykryn 734137
+    offs=$(objdump -h "$uefi_stub" 2> /dev/null | awk 'NF==7 {size=strtonum("0x"$3);\
Lukas Nykryn 734137
+                offset=strtonum("0x"$4)} END {print size + offset}')
Lukas Nykryn 734137
+    if [[ $offs -eq 0 ]]; then
Lukas Nykryn 734137
+        dfatal "Failed to get the size of $uefi_stub to create UEFI image file"
Lukas Nykryn 734137
+        exit 1
Lukas Nykryn 734137
+    fi
Lukas Nykryn 734137
+    align=$(pe_get_section_align "$uefi_stub")
Lukas Nykryn 734137
+    if [[ $? -eq 1 ]]; then
Lukas Nykryn 734137
+        dfatal "Failed to get the sectionAlignment of the stub PE header to create the UEFI image file"
Lukas Nykryn 734137
+        exit 1
Lukas Nykryn 734137
+    fi
Lukas Nykryn 734137
+    offs=$((offs + "$align" - offs % "$align"))
Lukas Nykryn 734137
+    [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
Lukas Nykryn 734137
+    [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
Lukas Nykryn 734137
+    [[ -s $uefi_osrelease ]] \
Lukas Nykryn 734137
+        && uefi_osrelease_offs=${offs} \
Lukas Nykryn 734137
+        && offs=$((offs + $(stat -Lc%s "$uefi_osrelease"))) \
Lukas Nykryn 734137
+        && offs=$((offs + "$align" - offs % "$align"))
Lukas Nykryn 734137
+
Lukas Nykryn 734137
     if [[ $kernel_cmdline ]] || [[ $hostonly_cmdline == yes && -e "${uefi_outdir}/cmdline.txt" ]]; then
Lukas Nykryn 734137
         echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
Lukas Nykryn 734137
         dinfo "Using UEFI kernel cmdline:"
Lukas Nykryn 734137
         dinfo "$(tr -d '\000' < "$uefi_outdir/cmdline.txt")"
Lukas Nykryn 734137
         uefi_cmdline="${uefi_outdir}/cmdline.txt"
Lukas Nykryn 734137
+        uefi_cmdline_offs=${offs}
Lukas Nykryn 734137
+        offs=$((offs + $(stat -Lc%s "$uefi_cmdline")))
Lukas Nykryn 734137
+        offs=$((offs + "$align" - offs % "$align"))
Lukas Nykryn 734137
     else
Lukas Nykryn 734137
         unset uefi_cmdline
Lukas Nykryn 734137
     fi
Lukas Nykryn 734137
 
Lukas Nykryn 734137
-    [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
Lukas Nykryn 734137
-    [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
Lukas Nykryn 734137
     if [[ -s ${dracutsysrootdir}${uefi_splash_image} ]]; then
Lukas Nykryn 734137
         uefi_splash_image="${dracutsysrootdir}${uefi_splash_image}"
Lukas Nykryn 734137
+        uefi_splash_offs=${offs}
Lukas Nykryn 734137
+        offs=$((offs + $(stat -Lc%s "$uefi_splash_image")))
Lukas Nykryn 734137
+        offs=$((offs + "$align" - offs % "$align"))
Lukas Nykryn 734137
     else
Lukas Nykryn 734137
         unset uefi_splash_image
Lukas Nykryn 734137
     fi
Lukas Nykryn 734137
 
Lukas Nykryn 734137
+    uefi_linux_offs="${offs}"
Lukas Nykryn 734137
+    offs=$((offs + $(stat -Lc%s "$kernel_image")))
Lukas Nykryn 734137
+    offs=$((offs + "$align" - offs % "$align"))
Lukas Nykryn 734137
+    uefi_initrd_offs="${offs}"
Lukas Nykryn 734137
+
Lukas Nykryn 734137
     if objcopy \
Lukas Nykryn 734137
-        ${uefi_osrelease:+--add-section .osrel="$uefi_osrelease" --change-section-vma .osrel=0x20000} \
Lukas Nykryn 734137
-        ${uefi_cmdline:+--add-section .cmdline="$uefi_cmdline" --change-section-vma .cmdline=0x30000} \
Lukas Nykryn 734137
-        ${uefi_splash_image:+--add-section .splash="$uefi_splash_image" --change-section-vma .splash=0x40000} \
Lukas Nykryn 734137
-        --add-section .linux="$kernel_image" --change-section-vma .linux=0x2000000 \
Lukas Nykryn 734137
-        --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd="${EFI_SECTION_VMA_INITRD}" \
Lukas Nykryn 734137
+        ${uefi_osrelease:+--add-section .osrel="$uefi_osrelease" --change-section-vma .osrel=$(printf 0x%x "$uefi_osrelease_offs")} \
Lukas Nykryn 734137
+        ${uefi_cmdline:+--add-section .cmdline="$uefi_cmdline" --change-section-vma .cmdline=$(printf 0x%x "$uefi_cmdline_offs")} \
Lukas Nykryn 734137
+        ${uefi_splash_image:+--add-section .splash="$uefi_splash_image" --change-section-vma .splash=$(printf 0x%x "$uefi_splash_offs")} \
Lukas Nykryn 734137
+        --add-section .linux="$kernel_image" --change-section-vma .linux="$(printf 0x%x "$uefi_linux_offs")" \
Lukas Nykryn 734137
+        --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd="$(printf 0x%x "$uefi_initrd_offs")" \
Lukas Nykryn 734137
         "$uefi_stub" "${uefi_outdir}/linux.efi"; then
Lukas Nykryn 734137
         if [[ -n ${uefi_secureboot_key} && -n ${uefi_secureboot_cert} ]]; then
Lukas Nykryn 734137
             if sbsign \
Lukas Nykryn 734137
-- 
Lukas Nykryn 734137
2.39.2
Lukas Nykryn 734137