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.
This commit is contained in:
HardenedVault 2020-11-06 08:03:44 +02:00 committed by Thierry Laurion
parent c1ae44d71c
commit 8a60930c6b
No known key found for this signature in database
GPG Key ID: E7B4A71658E36A93

View File

@ -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