Bug 1594217 - luksmeta slots come back from the dead when formatting a LUKS device
Summary: luksmeta slots come back from the dead when formatting a LUKS device
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: cryptsetup
Version: 28
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Milan Broz
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-06-22 12:05 UTC by Marius Vollmer
Modified: 2018-11-17 05:22 UTC (History)
4 users (show)

Fixed In Version: cryptsetup-2.0.5-1.fc28
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2018-11-17 05:22:20 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Marius Vollmer 2018-06-22 12:05:48 UTC
Description of problem:

Formatting a LUKS device again as a new LUKS device does not completely wipe the luksdata on it.

Version-Release number of selected component (if applicable):
luksmeta-8-3.fc28.x86_64
cryptsetup-2.0.3-4.fc28.x86_64

How reproducible:
Always

Steps to Reproduce:

Make a LUKS device with luksmeta data in slot 0 
# dd if=/dev/zero of=/dev/sdb
# cryptsetup luksFormat /dev/sdb
# luksmeta init -d /dev/sdb
# echo hello | luksmeta save -d /dev/sdb -s 0 -u cb6e8904-81ff-40da-a84a-07ab9ab5715f
# luksmeta show -d /dev/sdb
0   active cb6e8904-81ff-40da-a84a-07ab9ab5715f
...

Format the device again as LUKS
# cryptsetup luksFormat /dev/sdb
# luksmeta show -d /dev/sdb
0   active cb6e8904-81ff-40da-a84a-07ab9ab5715f

Actual results:
The luksmeta data is still there after a "cryptsetup luksFormat".  If that data is from "clevis luks bind" it is useless now and confusing.

Expected results:
luksmeta data should be gone.

Comment 1 Nathaniel McCallum 2018-08-27 20:24:01 UTC
LUKS never touches the header gap. Use: luksmeta nuke -d /dev/sdb.

Comment 2 Marius Vollmer 2018-08-28 07:13:17 UTC
> LUKS never touches the header gap. Use: luksmeta nuke -d /dev/sdb.

Wouldn't it be nice if cryptsetup itself would wipe its gap?  I'll reassign to find out.  I have also filed https://github.com/storaged-project/libblockdev/issues/391.

Comment 3 Ondrej Kozina 2018-08-28 08:04:25 UTC
I'm inclining to close it again, but few thoughts:

LUKS1 header size (including keyslots areas) depends on volume key size used during format action. If you change key size the respective luksmeta offset may change as well. IOW, even if add such wipe it will not work in all cases.

Nathaniel is right, luksmeta nuke is the correct way forward here.

Something like:
a) cryptsetup isLuks --type luks1 /dev/sdb ?
b) luksmeta nuke -d /dev/sdb
c) cryptsetup luksFormat...

But we already check for luksmeta presence if user wants to do up-conversion to LUKSv2 format.

Comment 4 Marius Vollmer 2018-08-28 09:32:33 UTC
(In reply to Ondrej Kozina from comment #3)

> Something like:
> a) cryptsetup isLuks --type luks1 /dev/sdb ?
> b) luksmeta nuke -d /dev/sdb
> c) cryptsetup luksFormat...

Why not the following sequence?

a) cryptsetup luksFormat --type luks1 /dev/sdb
b) luksmeta nuke -d /dev/sdb 

Step b) could actually also be "luksmeta init", no?  What else would people do with the gap anyway?

Comment 5 Marius Vollmer 2018-08-29 09:18:40 UTC
Here is a scenario that shows the potential harm of this bug:

# dd if=/dev/zero of=/dev/sdb
# cryptsetup luksFormat /dev/sdb
# clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }'

# cryptsetup luksFormat /dev/sdb
# cryptsetup luksAddKey /dev/sdb
# clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }'
# luksmeta show -d /dev/sdb
0   active empty
1   active cb6e8904-81ff-40da-a84a-07ab9ab5715e
2   active cb6e8904-81ff-40da-a84a-07ab9ab5715e

Clevis is now broken for /dev/sdb because the passphrase in slot 1 does not match the result of decryption with the tang pin anymore.

# clevis luks unlock -d /dev/sdb
No key available with this passphrase.

If /dev/sdb should be unlocked during boot, the next boot will time out and end up in the rescue shell.


I will lobby for a fix in libblockdev.

Comment 6 Marius Vollmer 2018-08-30 08:17:54 UTC
(In reply to Marius Vollmer from comment #5)

> I will lobby for a fix in libblockdev.

They don't want it either.  I can put a workaround in Cockpit, but that is arguably the worst place.  Please advise.

Comment 7 Ondrej Kozina 2018-08-30 08:46:50 UTC
(In reply to Marius Vollmer from comment #5)
> Here is a scenario that shows the potential harm of this bug:
> 
> # dd if=/dev/zero of=/dev/sdb
> # cryptsetup luksFormat /dev/sdb
> # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }'
> 
> # cryptsetup luksFormat /dev/sdb
> # cryptsetup luksAddKey /dev/sdb
> # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }'
> # luksmeta show -d /dev/sdb
> 0   active empty
> 1   active cb6e8904-81ff-40da-a84a-07ab9ab5715e
> 2   active cb6e8904-81ff-40da-a84a-07ab9ab5715e
> 
> Clevis is now broken for /dev/sdb because the passphrase in slot 1 does not
> match the result of decryption with the tang pin anymore.

And it would also break if user reencrypted the device, or performed LUKS header restore from backup where there is no 'nbde' keyslot. My point is that even if we fix this very case there will always be another one.

'bind' should probably check if the keyslot can be unlocked before it finishes the bind operation. It's a simple 'test passphrase for a keyslot' case from cryptsetup/luks perspective.

Comment 8 Marius Vollmer 2018-08-30 08:54:53 UTC
(In reply to Ondrej Kozina from comment #7)

> And it would also break if user reencrypted the device, or performed LUKS
> header restore from backup where there is no 'nbde' keyslot. My point is
> that even if we fix this very case there will always be another one.

Always?  Isn't the list of cases finite?

Anyway, y'all know about the problem and I let you go ahead and do the right thing.

Comment 9 Nathaniel McCallum 2018-08-30 13:53:59 UTC
The right thing is to move to LUKSv2 where luksmeta isn't needed. It was always a stop-gap.

Comment 10 Ondrej Kozina 2018-10-15 08:22:42 UTC
It gets mostly fixed by following upstream commit:

https://gitlab.com/cryptsetup/cryptsetup/commit/c2bce3e93ecee41f661b589ee28f112eb538259e

It'll not guarantee cryptstup erase luksmeta metadata in every case (see comment #3) but it fixes the problem you see after formating fresh LUKS device.

Comment 11 Fedora Update System 2018-10-29 10:59:54 UTC
cryptsetup-2.0.5-1.fc28 has been submitted as an update to Fedora 28. https://bodhi.fedoraproject.org/updates/FEDORA-2018-8936092f99

Comment 12 Fedora Update System 2018-10-31 17:30:21 UTC
cryptsetup-2.0.5-1.fc28 has been pushed to the Fedora 28 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-8936092f99

Comment 13 Fedora Update System 2018-11-17 05:22:20 UTC
cryptsetup-2.0.5-1.fc28 has been pushed to the Fedora 28 stable repository. If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.