b3cd9f
From f5ffe8bc95ee989ef39b7c149d268b5988f952a0 Mon Sep 17 00:00:00 2001
b3cd9f
From: Jonathan Lebon <jonathan@jlebon.com>
b3cd9f
Date: Thu, 17 Jun 2021 10:47:33 -0400
b3cd9f
Subject: [PATCH] fix(fips): handle s390x OSTree systems
b3cd9f
b3cd9f
On s390x, the `BOOT_IMAGE` karg injected by the bootloader is not a path
b3cd9f
to the kernel image, but rather an integer describing the index of the
b3cd9f
menu entry selected. Because of the way the s390x bootloader works,
b3cd9f
there is no information retained about e.g. the path of the kernel that
b3cd9f
was loaded.
b3cd9f
b3cd9f
This causes issues for the FIPS code which assumes that `BOOT_IMAGE` is
b3cd9f
a path to the kernel image to derive the HMAC path. In non-OSTree
b3cd9f
systems, this ends up working anyway, because the kernel is located at
b3cd9f
the root of the boot partition.  In OSTree systems, this is not the
b3cd9f
case. However, OSTree systems use BLS configs, and they are named in
b3cd9f
reverse order of precedence (i.e. menu ordering). So from the
b3cd9f
`BOOT_IMAGE` integer, we can figure out which BLS entry was selected.
b3cd9f
b3cd9f
Add some code to do just this on s390x. This isn't completely foolproof,
b3cd9f
because it presumes that (1) BLS configs were used to populate the
b3cd9f
bootloader (and that they were exactly in the same state they currently
b3cd9f
are when `zipl` was run), and (2) there are no other menu entries
b3cd9f
originating from outside the BLS configs. However, if these assumptions
b3cd9f
are wrong we would simply fail the boot, which is currently what is
b3cd9f
happening anyway.
b3cd9f
b3cd9f
See also:
b3cd9f
https://github.com/openshift/os/pull/546
b3cd9f
https://github.com/ibm-s390-linux/s390-tools/issues/78
b3cd9f
b3cd9f
Tested-by: Muhammad Adeel <muhammad.adeel@ibm.com>
b3cd9f
b3cd9f
Resolves: rhbz#2007586
b3cd9f
---
b3cd9f
 modules.d/01fips/fips.sh         | 21 +++++++++++++++++++++
b3cd9f
 modules.d/01fips/module-setup.sh |  2 +-
b3cd9f
 2 files changed, 22 insertions(+), 1 deletion(-)
b3cd9f
b3cd9f
diff --git a/modules.d/01fips/fips.sh b/modules.d/01fips/fips.sh
b3cd9f
index 1d57a889..c57fd426 100755
b3cd9f
--- a/modules.d/01fips/fips.sh
b3cd9f
+++ b/modules.d/01fips/fips.sh
b3cd9f
@@ -114,6 +114,27 @@ do_fips()
b3cd9f
     else
b3cd9f
         BOOT_IMAGE="$(getarg BOOT_IMAGE)"
b3cd9f
 
b3cd9f
+        # On s390x, BOOT_IMAGE isn't a path but an integer representing the
b3cd9f
+        # entry number selected. Let's try the root of /boot first, and
b3cd9f
+        # otherwise fallback to trying to parse the BLS entries if it's a
b3cd9f
+        # BLS-based system.
b3cd9f
+        if [ "$(uname -m)" = s390x ]; then
b3cd9f
+            if [ -e "/boot/vmlinuz-${KERNEL}" ]; then
b3cd9f
+                BOOT_IMAGE="vmlinuz-${KERNEL}"
b3cd9f
+            elif [ -d /boot/loader/entries ]; then
b3cd9f
+                i=0
b3cd9f
+                for bls in $(ls -d /boot/loader/entries/*.conf | sort -rV); do
b3cd9f
+                  ((i++))
b3cd9f
+
b3cd9f
+                  if [ $i -eq ${BOOT_IMAGE:-0} ] && [ -r "$bls" ]; then
b3cd9f
+                      BOOT_IMAGE="$(grep -e '^linux' "$bls" | grep -o ' .*$')"
b3cd9f
+                      BOOT_IMAGE=${BOOT_IMAGE:1}
b3cd9f
+                      break
b3cd9f
+                  fi
b3cd9f
+                done
b3cd9f
+            fi
b3cd9f
+        fi
b3cd9f
+
b3cd9f
         # Trim off any leading GRUB boot device (e.g. ($root) )
b3cd9f
         BOOT_IMAGE="$(echo "${BOOT_IMAGE}" | sed 's/^(.*)//')"
b3cd9f
 
b3cd9f
diff --git a/modules.d/01fips/module-setup.sh b/modules.d/01fips/module-setup.sh
b3cd9f
index 8800a49e..71bea53a 100755
b3cd9f
--- a/modules.d/01fips/module-setup.sh
b3cd9f
+++ b/modules.d/01fips/module-setup.sh
b3cd9f
@@ -67,7 +67,7 @@ install() {
b3cd9f
     inst_hook pre-udev 01 "$moddir/fips-load-crypto.sh"
b3cd9f
     inst_script "$moddir/fips.sh" /sbin/fips.sh
b3cd9f
 
b3cd9f
-    inst_multiple sha512hmac rmmod insmod mount uname umount
b3cd9f
+    inst_multiple sha512hmac rmmod insmod mount uname umount grep sort
b3cd9f
 
b3cd9f
     inst_simple /etc/system-fips
b3cd9f
     [ -c ${initdir}/dev/random ] || mknod ${initdir}/dev/random c 1 8 \