Bug#1055024: cryptsetup-initramfs changes crypttab entries order when generating initramfs

2023-12-22 Thread Marc Haber
On Sun, Oct 29, 2023 at 03:10:18PM +0100, Nicolas Melot wrote:
> This is a repost of the same bug report I submitted to Ubuntu maintainers on
> https://bugs.launchpad.net/ubuntu/+source/cryptsetup/+bug/2031499 and that
> seems to have been left as is. I am now hitting the same issue on Debian
> Bookworm.

I have exactly the same problem with a setup where another crypt device
needs to be unlocked BEFORE the root file system because the other crypt
device holds part of the key.

And I came to the same solution independently.

Hence, this is not a totally exotic use case at least, since two users
came even to the same solution.

After taking a step back I also find the solution quite elegant: It
preserves the order of the crypt devices as given by the local admin, it
just adds the devices that the local admin didn't specify while the
system knows a device is needed. The admin has the option of taking
the complete crypttab in their own hands transparently.

Please consider implementing this.

Greetings
Marc



Bug#1055024: cryptsetup-initramfs changes crypttab entries order when generating initramfs

2023-10-29 Thread Nicolas Melot
Package: cryptsetup-initramfs
Version: 2:2.4.3-1ubuntu1.1
Severity: important
Tags: upstream d-i
X-Debbugs-Cc: ny...@doramail.com

Dear Maintainer,

This is a repost of the same bug report I submitted to Ubuntu maintainers on
https://bugs.launchpad.net/ubuntu/+source/cryptsetup/+bug/2031499 and that
seems to have been left as is. I am now hitting the same issue on Debian
Bookworm.

update-initramfs does not generate entries of initrd's /cryptroot/crypttab in
the same order as system's /etc/crypttab, when entries tagged as "initramfs"
are placed before entries that are not, or that are detected as necessary to
unlock the root partition. This is a problem if partitions automatically
detected as needed depends on a partition that is not detected as necessary;
even if it actually is. For examples, see system's /etc/crypttab below:

#
keyring UUID=abcdefg none luks,initramfs
swap /dev/xps-nicmel/swap legacy luks,keyscript=/etc/luks-key.sh

Turns to initrd's /cryptroot/crypttab:

swap /dev/mapper/xps--nicmel-swap legacy luks,keyscript=/etc/luks-key.sh
keyring UUID=abcdefg none luks,initramfs

The swap partition gets its key from the script luks-key.sh, which itself reads
it from keyring. update-initramfs cannot detect this dependency and places swap
as to be decrypted first. Decryption will fail at boot because it won't find
the necessary key.

I could work around the problem by modifying /usr/share/initramfs-
tools/hooks/cryptroot from

177 generate_initrd_crypttab() {
178 local devnos usage IFS="$(printf '\t\n ')"
179 mkdir -- "$DESTDIR/cryptroot"
180 true >"$DESTDIR/cryptroot/targets"
181
182 {
183 if devnos="$(get_mnt_devno /)"; then
184 if [ -n "$devnos" ]; then
185 usage=rootfs foreach_cryptdev crypttab_find_and_print_entry $devnos
186 fi
187 else
188 cryptsetup_message "WARNING: Couldn't determine root device"
189 fi
190
191 if devnos="$(get_resume_devno)" && [ -n "$devnos" ]; then
192 usage=resume foreach_cryptdev crypttab_find_and_print_entry $devnos
193 fi
194
195 if devnos="$(get_mnt_devno /usr)" && [ -n "$devnos" ]; then
196 usage="" foreach_cryptdev crypttab_find_and_print_entry $devnos
197 fi
198
199 # add crypttab entries with the 'initramfs' option set
200 crypttab_foreach_entry crypttab_print_initramfs_entry
201 } 3>"$DESTDIR/cryptroot/crypttab"
202 rm -f "$DESTDIR/cryptroot/targets"
203 }

to

generate_initrd_crypttab() {
178 local devnos usage IFS="$(printf '\t\n ')"
179 mkdir -- "$DESTDIR/cryptroot"
180 true >"$DESTDIR/cryptroot/targets"
181
182 {
183 # add crypttab entries with the 'initramfs' option set
184 crypttab_foreach_entry crypttab_print_initramfs_entry
185
186 if devnos="$(get_mnt_devno /)"; then
187 if [ -n "$devnos" ]; then
188 usage=rootfs foreach_cryptdev crypttab_find_and_print_entry $devnos
189 fi
190 else
191 cryptsetup_message "WARNING: Couldn't determine root device"
192 fi
193
194 if devnos="$(get_resume_devno)" && [ -n "$devnos" ]; then
195 usage=resume foreach_cryptdev crypttab_find_and_print_entry $devnos
196 fi
197
198 if devnos="$(get_mnt_devno /usr)" && [ -n "$devnos" ]; then
199 usage="" foreach_cryptdev crypttab_find_and_print_entry $devnos
200 fi
201 } 3>"$DESTDIR/cryptroot/crypttab"
202 rm -f "$DESTDIR/cryptroot/targets"
203 }

i.e. moving line 200 to line 183, so that "initramfs"-tagged entries are
generated before other entries. Of course this is a quick and dirty fix and
won't stand many other scenarios.

A possible quick fix includes an order field in options section of
/etc/crypttab, or preserving entries order of system's crypttab. A better one
would be a dependency option, e.g. depends=keyring in the example above:

keyring UUID=abcdefg none luks,initramfs
swap /dev/xps-nicmel/swap legacy luks,keyscript=/etc/luks-
key.sh,depends=keyring


-- Package-specific info:
-- /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.2.0-35-generic root=ZFS=xps-nicmel/ubuntu-22.04 ro quiet 
splash resume=UUID=dd6ea7ab-5651-4d11-ae2c-b02869051ea3 vt.handoff=1

-- /etc/crypttab
# 

keyring UUID=ab96a60d-94e8-40cf-b6e8-e29d30a5b5ec   none
luks,initramfs
#ubuntu-22.04   /dev/xps-nicmel/ubuntu-22.04none
luks
nvme0n1p10  /dev/nvme0n1p10 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p11  /dev/nvme0n1p11 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p12  /dev/nvme0n1p12 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p13  /dev/nvme0n1p13 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p16  /dev/nvme0n1p16 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p17  /dev/nvme0n1p17 xps-nicmel  
luks,initramfs,keyscript=/etc/luks-key.sh
nvme0n1p18  /dev/nvme0n1p18