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