dracut/0076.patch
Pavel Valena f8e78fc034 dracut-057-79.git20241127
Resolves: RHEL-55245,RHEL-55708,RHEL-56885,RHEL-64754,RHEL-65249,RHEL-66582
2024-11-27 21:54:00 +01:00

119 lines
4.3 KiB
Diff

From 492bc949e16f78fad9f274744c72bc2fd0161d84 Mon Sep 17 00:00:00 2001
From: Vitaly Kuznetsov <vkuznets@redhat.com>
Date: Fri, 9 Aug 2024 12:49:05 +0200
Subject: [PATCH] feat(fips): add support for UKIs
Kernel integrity check in FIPS module is incompatible with UKIs as neither
/boot/vmlinuz-`uname-r` nor /boot/.vmlinuz-`uname-r`.hmac are present. UKI
is placed to $ESP\EFI\Linux\<install-tag>-<uname-r>.efi and if a .hmac file
is present next to it, it is possible to do similar check.
Note, UKIs have a 'one size fits all' command line and 'boot=' is not expected
to be set. Luckily, if the UKI is systemd-stub based then we can expect
'LoaderDevicePartUUID' variable containing PARTUUID of the ESP to be set. Mount
it to /boot using the existing logic.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
(cherry picked from commit 72684ff519be4f29c45cbb0f84759e645b0ac4be)
Resolves: RHEL-56885
---
modules.d/01fips/fips.sh | 51 ++++++++++++++++++++++++++++++++++++++++
modules.d/01fips/module-setup.sh | 2 +-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/modules.d/01fips/fips.sh b/modules.d/01fips/fips.sh
index 05631c8a..3889dc0c 100755
--- a/modules.d/01fips/fips.sh
+++ b/modules.d/01fips/fips.sh
@@ -14,9 +14,22 @@ else
}
fi
+# Checks if a systemd-based UKI is running and ESP UUID is set
+is_uki() {
+ [ -f /sys/firmware/efi/efivars/StubFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f ] \
+ && [ -f /sys/firmware/efi/efivars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f ]
+}
+
mount_boot() {
boot=$(getarg boot=)
+ if is_uki && [ -z "$boot" ]; then
+ # efivar file has 4 bytes header and contain UCS-2 data. Note, 'cat' is required
+ # as sys/firmware/efi/efivars/ files are 'special' and don't allow 'seeking'.
+ # shellcheck disable=SC2002
+ boot="PARTUUID=$(cat /sys/firmware/efi/efivars/LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f | tail -c +5 | tr -d '\0' | tr 'A-F' 'a-f')"
+ fi
+
if [ -n "$boot" ]; then
if [ -d /boot ] && ismounted /boot; then
boot_dev=
@@ -81,6 +94,41 @@ do_rhevh_check() {
return 0
}
+do_uki_check() {
+ local KVER
+ local uki_checked=0
+
+ KVER="$(uname -r)"
+ # UKI are placed in $ESP\EFI\Linux\<intall-tag>-<uname-r>.efi
+ if ! [ "$FIPS_MOUNTED_BOOT" = 1 ]; then
+ warn "Failed to mount ESP for doing UKI integrity check"
+ return 1
+ fi
+
+ for UKIpath in /boot/EFI/Linux/*-"$KVER".efi; do
+ # UKIs are installed to $ESP/EFI/Linux/<entry-token-or-machine-id>-<uname-r>.efi
+ # and in some cases (e.g. when the image is used as a template for creating new
+ # VMs) entry-token-or-machine-id can change. To make sure the running UKI is
+ # always checked, check all UKIs which match the 'uname -r' of the running kernel
+ # and fail the whole check if any of the matching UKIs are corrupted.
+
+ [ -r "$UKIpath" ] || break
+
+ local UKI="${UKIpath##*/}"
+ local UKIHMAC=."$UKI".hmac
+
+ fips_info "checking $UKIHMAC"
+ (cd /boot/EFI/Linux/ && sha512hmac -c "$UKIHMAC") || return 1
+ uki_checked=1
+ done
+
+ if [ "$uki_checked" = 0 ]; then
+ warn "Failed for find UKI for checking"
+ return 1
+ fi
+ return 0
+}
+
nonfatal_modprobe() {
modprobe "$1" 2>&1 > /dev/stdout \
| while read -r line || [ -n "$line" ]; do
@@ -133,6 +181,9 @@ do_fips() {
elif [ -e "/run/install/repo/images/pxeboot/vmlinuz" ]; then
# This is a boot.iso with the .hmac inside the install.img
do_rhevh_check /run/install/repo/images/pxeboot/vmlinuz || return 1
+ elif is_uki; then
+ # This is a UKI
+ do_uki_check || return 1
else
BOOT_IMAGE="$(getarg BOOT_IMAGE)"
diff --git a/modules.d/01fips/module-setup.sh b/modules.d/01fips/module-setup.sh
index 91612ff3..a090bc88 100755
--- a/modules.d/01fips/module-setup.sh
+++ b/modules.d/01fips/module-setup.sh
@@ -67,7 +67,7 @@ install() {
inst_hook pre-udev 01 "$moddir/fips-load-crypto.sh"
inst_script "$moddir/fips.sh" /sbin/fips.sh
- inst_multiple sha512hmac rmmod insmod mount uname umount grep sed sort
+ inst_multiple sha512hmac rmmod insmod mount uname umount grep sed cut find sort cat tail tr
inst_simple /etc/system-fips