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