From 8a60930c6b97ae65fbe2e60675c845edde082353 Mon Sep 17 00:00:00 2001 From: HardenedVault Date: Fri, 6 Nov 2020 08:03:44 +0200 Subject: [PATCH] Make the path to crypttab within initramfs overridable Not all distro put crypttab under /etc/ within initramfs, but finding it at runtime needs unpacking, which may be hard to do, so it is made overridable with a file at /boot/kexec_initrd_crypttab_path.txt, whose content could be obtained with $ cpio -t < ${uncompressed_initrd} | grep crypttab . The "target" field of the record within the crypttab stored in the root file system for the luks container which is going to be unlocked via kexec-insert-key should be modified into the same "luks-$uuid" format, otherwise the boot sequence will get stuck when OS is trying to unlock them again, in order to map them according to "target" fields written in the crypttab stored in the root fs. --- initrd/bin/kexec-insert-key | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key index 5b4020ec..4592f698 100755 --- a/initrd/bin/kexec-insert-key +++ b/initrd/bin/kexec-insert-key @@ -30,12 +30,24 @@ fi cat "$TMP_KEY_DEVICES" | cut -d\ -f1 | xargs /bin/qubes-measure-luks \ || die "LUKS measure failed" -# Unpack the initrd and fixup the /etc/crypttab +# Unpack the initrd and fixup the crypttab # this is a hack to split it into two parts since # we know that the first 0x3400 bytes are the microcode INITRD_DIR=/tmp/secret/initrd SECRET_CPIO=/tmp/secret/initrd.cpio -mkdir -p "$INITRD_DIR/etc" + +# Not all distro put crypttab under /etc/ within initramfs, but finding it at +# runtime needs unpacking, which may be hard to do, so it is made overridable +# with a file at /boot/kexec_initrd_crypttab_path.txt, whose content could be +# obtained with $ cpio -t < ${uncompressed_initrd} | grep crypttab . + +bootdir=$(dirname "$INITRD") +if [ -r $bootdir/kexec_initrd_crypttab_path.txt ]; then + crypttab_path=$(cat $bootdir/kexec_initrd_crypttab_path.txt) +else + crypttab_path=etc/crypttab +fi +mkdir -p "$INITRD_DIR/$(dirname $crypttab_path)" # Attempt to unseal the disk key from the TPM # should we give this some number of tries? @@ -72,10 +84,18 @@ echo '+++ Building initrd' dd if="$INITRD" of="$SECRET_CPIO" bs=512 conv=sync \ || die "Failed to copy initrd to /tmp" +# The "target" field of the record within the crypttab stored in the root +# file system for the luks container which is going to be unlocked via +# kexec-insert-key should be modified into the same "luks-$uuid" format, +# otherwise the boot sequence will get stuck when OS is trying to unlock them +# again, in order to map them according to "target" fields written in the +# crypttab stored in the root fs. + if [ "$unseal_failed" = "n" ]; then - # overwrite /etc/crypttab to mirror the behavior for in seal-key + # overwrite crypttab to mirror the behavior for in seal-key for uuid in `cat "$TMP_KEY_DEVICES" | cut -d\ -f2`; do - echo "luks-$uuid UUID=$uuid /secret.key" >> "$INITRD_DIR/etc/crypttab" + # In Debian, the "luks" option at last should not be omitted + echo "luks-$uuid UUID=$uuid /secret.key luks" >> "$INITRD_DIR/$crypttab_path" done ( cd "$INITRD_DIR" ; find . -type f | cpio -H newc -o ) >> "$SECRET_CPIO" fi