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