[pkg-cryptsetup-devel] Bug#994562: cryptsetup: consider exit statuses of keyscripts

Christoph Anton Mitterer calestyo at scientia.net
Fri Sep 17 19:29:46 BST 2021


Package: cryptsetup
Version: 2:2.4.0-1
Severity: important



Hey.

First a question, which I couldn't answer myself on a quick glance on the code:

When a keyscript is run, do the functions cache it's output and only execute
cryptsetup (with the key) when the keyscript's exit status is also 0?

Or is the output just piped through and the exit status ignored?


AFAICS it does the later.


First, I think this is generally problematic:
What if the keyscript actually wasn't able to obtain the key but still printed
out something?
For LUKS this might be no problem as that can be checked for. But for plain
dm-crypt? Checking for a fs may not work there either (it may not contain a fs).

So ideally I think, cryptsetup should only be executed, when the keyscript
succeded.


Simple test case:
# truncate image --size=1G  #(never written to)
# cryptsetup plainOpen image XXX
  <using test as password>
# hd /dev/mapper/XXX | head
00000000  89 fb be 33 ed 33 86 3a  d8 96 db 52 37 f2 41 d9  |...3.3.:...R7.A.|
00000010  5e 7e 95 62 19 59 e3 eb  db ad 42 ad 76 07 42 66  |^~.b.Y....B.v.Bf|
...

# cryptsetup plainClose XXX
# cryptsetup plainOpen image XXX
  <using foo as password>
# hd /dev/mapper/XXX | head
00000000  e2 2b f6 f5 7f 73 4c d9  1c bf 10 ad d5 bf d5 4b  |.+...sL........K|
00000010  b8 66 33 94 a1 c6 50 13  50 66 6a 36 bb b9 9e a0  |.f3...P.Pfj6....|
...


And I guess it would just behave the same when cryptdisks_start or the initramfs-
code was used?


What I do in my own keyscript is, that I store the results (base64-encoded)
in a variable and only when the final status is clear, I decode that and print it
to stdout andexit 0.

Maybe that's something you could do as well, e.g. something like.

key=$( keyscript | base64 -w 0 )
...
if [ $magic -eq 0]; then
	printf '$s' "$key" | base64 -d | cryptsetup ...
fi


Problem is obviously how to get the exit status of keyscript, rather than base64.
I do it as I describe here: https://unix.stackexchange.com/a/668853/474076

That seems to be even POSIX comptaible. ;-)


I'd say one can ignore the exit status of printf and base64 (even with -d, as we know
that the input has been correctly encoded), ... I guess these could only fail in
extreme cases like out of resources.



Second, and that was the actual reason for writing this ticket ;-) ...

Different exit statuses should be defined for keyscripts.
0 = obviously, everything worked, key shall be used
1 = some error occurred, please retry (as long as you tries=n is fulfilled)
2 = retry, but sleep 1s
3 = retry, but sleep 10s
4 = retry, but sleep 30s
5 = retry, but sleep 1m
6 = retry, but sleep 5m
10 = catatrophic failure, don't retry regardless of tries=n
(all others I'd reserve and handle for now like 1)

Something like 10 seems missing right now and is how I came to this:
E.g. my keyscript needs some parameters in the 3rd field of crypttab. If that's missing
it will always fail and there will be no recovery from that (i.e. it doesn't help
just to re-enter another passphrase).

In that case and with tries=0 it just goes into an endless loop right now, which is
always bad.

So in that case I'd wish I could exit 10 and cryptsetup would simply stop and indicate
some error status itself.
During the initramfs, that may of course mean unbootable system (which it is however
anyway).


Cheers,
Chris.



More information about the pkg-cryptsetup-devel mailing list