[dm-crypt] The future of disk encryption with LUKS2

Sven Eschenberg sven at whgl.uni-frankfurt.de
Sat Feb 6 19:56:02 CET 2016


Hi Michael,


Am 06.02.2016 um 11:01 schrieb Michael Kjörling:
> On 6 Feb 2016 04:18 +0100, from sven at whgl.uni-frankfurt.de (Sven Eschenberg):
>> (A secondary header implies that
>> all changes on both headers need to be atomic and in sync. While
>> this is doable, LVM clearly shows, that it is not trivial, otherwise
>> it would certainly be available as feature by now).
>
> I'm not so sure it does imply that. It does certainly imply the need
> to know that a, and which one out of the lot, header is most up to
> date, but that does not necessarily require writes to both to be done
> atomically and in sync. (In fact, truly atomic, in-sync writes to
> multiple distinct locations seems a physical impossibility at least in
> the case of a single spinning disk, since the write head can only be
> in one location at any one time.)

Of course atomicity applies to the transaction as whole. Here atomicity 
implies that before starting and afterwards the state is consistent and 
that if something goes wrong inbetween, you'll be able to cleanly roll 
back or conclude the operation.
>
> This is where the "update counter" and a checksum that I mentioned
> earlier comes in. An example of how to actually do this might be to
> first discard (or perhaps rather, remove from consideration) any
> header which doesn't match its checksum (for integrity purposes), then
> use the one with the highest update counter value (taking care to
> allow for wraparound) as a starting point for the operation at hand,
> then rewrite any previously discarded headers (ideally writing the
> checksum last, such that the header remains considered invalid until
> it has been fully rewritten).

An update counter+checksum will not do the trick. Let's see (This is has 
not been completely thought over and checked) a resize operation that 
grows the container:
The backing device grows, possibly without any warning -> We'll need to 
keep the secondary header location in the primary header.
Check that both headers are consistent, otherwise fix them first.
Add old location and new planned location of the header into the WAL.
Read secondary header, write secondary header (note in WAL, note the 
secondary header at old location will be removed)
safely wipe old header (note in WAL)
Note that primary header's location info on secondary header is about to 
be updated, update and note success in WAL.

Check for consistency & clear WAL.

Hopefully I did not miss any step and yes, it is not THAT complicated as 
there is no concurrency involved, but the transactions for resizing need 
to be crafted carefully.

With a single metadatacopy 90% of the issues don't even exist ;-).

>
> Or maybe even better, rewrite a previously considered invalid header
> (if any) first; that should ensure that as long as the storage itself
> works properly, if any header is ever valid at the beginning of an
> operation, there exists at all times at least one header which is
> valid.
>
> By placing the headers far apart from each other, this forces at least
> spinning disks to seek, which naturally introduces a sequence point
> into the write process; even if the two write requests were to be put
> onto the I/O bus at the same instant, one write must complete before
> the other can physically begin. (Finally, a good use for the seek
> delay in rotational storage!)
>
> This should work equally well for any number of header copies.
>


More information about the dm-crypt mailing list