FS#56771 - [cryptsetup] using luks2 produces an unbootable system
Attached to Project:
Arch Linux
Opened by Christopher (_zeptoSteve) - Tuesday, 19 December 2017, 11:16 GMT
Last edited by Christian Hesse (eworm) - Monday, 08 January 2018, 19:12 GMT
Opened by Christopher (_zeptoSteve) - Tuesday, 19 December 2017, 11:16 GMT
Last edited by Christian Hesse (eworm) - Monday, 08 January 2018, 19:12 GMT
|
Details
recently installed Arch on a second SSD with
cryptsetup-2.0.0-1 (from core). I'm using luks on both
drives, but only one (with LUKS2) is unbootable.
`cryptsetup --cipher aes-xts-plain64 --iter-time 8192 --key-size 512 --type luks2 --verify-passphrase luksFormat /dev/sda2` is the exact command for creating the encryption. I rebooted and found that `cryptsetup isLuks /dev/sda2` fails because a lock cannot be obtained. error -5. I tried: `cryptsetup --disable-locks --type luks open /dev/sda2 core`, but something complained (probably cryptsetup) about missing "libgcc_s.so". it may have been "libgcc_s.so.1", though. this file was apparently required for (I think) some pthread operation. (pthread_cancel, if I remember correctly.) I realize this is probably hard to test, sorry about that. I am using the encrypt hook after block and before filesystem. I hope I'm not missing anything really obvious. |
This task depends upon
Closed by Christian Hesse (eworm)
Monday, 08 January 2018, 19:12 GMT
Reason for closing: Fixed
Additional comments about closing: Latest cryptsetup and argon revisions.
Monday, 08 January 2018, 19:12 GMT
Reason for closing: Fixed
Additional comments about closing: Latest cryptsetup and argon revisions.
* removed the "isLuks" check from /usr/lib/initcpio/hooks/encrypt, and placed "true" there instead (line 70)
* added --disable-locks to the "cryptsetup open" line of the same file (line 87)
* added 'add_file "libgcc_s.so.1"' before the add_runscript line of /usr/lib/initcpio/install/encrypt
not the greatest, because "isLuks" is kinda required sometimes. and I'm not sure what the locks even do in LUKS2, so removing them might be a bad idea.
aside from this, though, maybe the "isLuks" thing just doesn't work in busybox due to the lock? that would be an upstream issue I guess.
Do you see the locking issue in initramfs only? Would be nice if you could reproduce this from a running system as well.
I could not see a way that cryptsetup could load "libgcc_s.so.1". Can you try to get the details what happens? Even more interesting: mkinitcpio adds all required libraries to initramfs, so no idea why this one can be missing when it is required.
I will try to install a system with LUKS2 any time soon... Not sure when I will have any spare time.
You could try to migrate your initramfs to a systemd-based one... Possibly that works.
actually, I can open it from an already running Arch; it's only inside initramfs that the locking issue occurs.
I tried the sd-encrypt hook. I'm not too familiar with the required hooks. I got an error then too, dropped into a console. it was just "check systemctl status <something>". can't remember the exact term used.
when I did that, it said something about "/usr/lib/systemd/systemd-<something> attach /dev/sda2", where <something> is "generator" or "cryptsetup", can't remember.
(I'm saying "/dev/sda2" because I can't remember the exact UUID of the disk; I'm on a different computer right now.)
obviously failed when I tried it. their error messages are not much help.
EDIT: the systemd command was "/usr/lib/systemd/systemd-cryptsetup attach absoCore /dev/sda2". the error returned was: "crypt_load() failed on device /dev/sda2".
I tried to see if I could boot after creating /run/lock/cryptsetup, and I got pretty close. I had to include /usr/bin/mkdir, because I guess including /run/lock/cryptsetup/dummy didn't persist. (I created the dummy file and added it to the FILES array of mkinitcpio.conf)
the only trouble I had was using the "switch_root" command, because it complained about not being boot in a systemd environment. so basically:
~~~
mkdir -p /run/lock/cryptsetup # works.
cryptsetup isLuks /dev/sda2 # works.
cryptsetup --type luks open /dev/sda2 absoCore # works.
mount /dev/mapper/absoCore /new_root # works.
switch_root /new_root /usr/bin/systemd/systemd # does not work.
~~~
I know it's not rendered as a code block, but whatever.
inspired by https://gitlab.com/cryptsetup/cryptsetup/issues/325
anyway, three changes.
* "/usr/lib/initcpio/install/encrypt" must also 'add_binary "mkdir"', because of the next thing.
* "/usr/lib/initcpio/hooks/encrypt" must "mkdir -p /run/locks/cryptsetup" **before** isLuks. anytime before is probably fine, but I chose the line immediately above.
* "/etc/mkinitcpio.conf" must have "/usr/lib/libgcc_s.so.1" in the FILES array.
there may be a simpler way to do this, but this works.
Even after applying the changes what Christopher have mentioned I get the following error:
The device /dev/* is not a LUKS volume and the crypto= parameter was not specified.
After this error I get dropped to the emergency shell. If I then try to open the partition manually using:
cryptsetup luksOpen /dev/* root
Then I get the following error:
Failed to acquire read lock on device /dev/*
I reverted Christopher's changes and tried running cryptsetup using '--disable-locks':
/usr/lib/initcpio/hooks/encrypt: In my case I just had to change the following line with isLuks:
if cryptsetup isLuks ${resolved} ...
to
if cryptsetup isLuks --disable-locks ${resolved} ...
and the following line for opening the LUKS container:
while ! eval cryptsetup open --type luks ...
to
while ! eval cryptsetup open --disable-locks --type luks ...
After these changes I noticed that the global variable $root is not set by the encrypt hook if $DEPRECATED_CRYPT==0, so I had to add the following block:
if [ -e "/dev/mapper/${cryptname}" ]; then
if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
export root="/dev/mapper/root"
fi
else
to:
if [ -e "/dev/mapper/${cryptname}" ]; then
if [ ${DEPRECATED_CRYPT} -eq 1 ]; then
export root="/dev/mapper/root"
fi
export root=/dev/mapper/${cryptname}
else
A last change was needed due to the following error by cryptsetup:
libgcc_s.so.1 must be installed for pthread_cancel to work
So I added /usr/lib/libgcc_s.so.1 to the FILES array in /etc/mkinitcpio.conf like Christopher mentioned:
FILES=(/usr/lib/libgcc_s.so.1)
Then, I could finally boot!
[1] https://gitlab.com/cryptsetup/cryptsetup/blob/master/lib/luks2/luks2_json_metadata.c#L820
Same boot errors as show in Christopher's image.
From the cryptsetup 2.0.0 release notes:
NOTE: to operate correctly, LUKS2 requires locking of metadata.
Locking is performed by using flock() system call for images in file
and for block device by using a specific lock file in /run/lock/cryptsetup.
If your distro does not support tmpfiles.d directory, you have to create locking directory (/run/lock/cryptsetup) in cryptsetup package (or init scripts).
Let me know if there's any input that I can provide.
Here's my temporary fix.
1. Add "FILES=(/usr/lib/libgcc_s.so.1)" to /etc/mkinitcpio.conf
2. Add "mkdir -p /run/lock/cryptsetup/" to /usr/lib/initcpio/hooks/encrypt
Seems like the cleanest way for now...
Still does not explain what is calling libgcc_s.so.1 it is not linked against cryptsetup but clearly something is trying to use it.
and https://gitlab.com/cryptsetup/cryptsetup/blob/master/lib/crypto_backend/argon2/thread.c#L34 and http://man7.org/linux/man-pages/man3/pthread_cancel.3.html
What CPU does your system have?
https://github.com/P-H-C/phc-winner-argon2/blob/20171227/Makefile#L44
I tried to be honest to our i686 and arm friends. ;)