mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2026-01-06 23:45:31 +01:00
Fix bug in minimal device size calculation for reencryption.
This commit is contained in:
@@ -431,6 +431,7 @@ const char *LUKS2_reencrypt_protection_hash(struct luks2_hdr *hdr);
|
||||
uint64_t LUKS2_reencrypt_data_shift(struct luks2_hdr *hdr);
|
||||
const char *LUKS2_reencrypt_mode(struct luks2_hdr *hdr);
|
||||
int LUKS2_reencrypt_direction(struct luks2_hdr *hdr, crypt_reencrypt_direction_info *di);
|
||||
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);
|
||||
|
||||
/*
|
||||
* Generic LUKS2 digest
|
||||
|
||||
@@ -1965,13 +1965,7 @@ static int _prepare_multi_dmd(struct crypt_device *cd,
|
||||
else
|
||||
device_check = DEV_EXCL;
|
||||
|
||||
/* FIXME: replace == 0 with < LUKS2_header_size() */
|
||||
data_offset = json_segments_get_minimal_offset(jobj_segments, 1);
|
||||
if (data_offset == 0 &&
|
||||
crypt_data_device(cd) == crypt_metadata_device(cd)) {
|
||||
log_dbg(cd, "Internal error. Wrong data offset");
|
||||
return -EINVAL;
|
||||
}
|
||||
data_offset = LUKS2_reencrypt_data_offset(hdr, true);
|
||||
|
||||
r = device_block_adjust(cd, crypt_data_device(cd), device_check,
|
||||
data_offset, &dmd->size, &dmd->flags);
|
||||
|
||||
@@ -3262,6 +3262,21 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* use only for calculation of minimal data device size.
|
||||
* The real data offset is taken directly from segments!
|
||||
*/
|
||||
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise)
|
||||
{
|
||||
crypt_reencrypt_direction_info di;
|
||||
uint64_t data_offset = LUKS2_get_data_offset(hdr);
|
||||
|
||||
if (!LUKS2_reencrypt_direction(hdr, &di) && (di == CRYPT_REENCRYPT_FORWARD))
|
||||
data_offset += LUKS2_reencrypt_data_shift(hdr) >> SECTOR_SHIFT;
|
||||
|
||||
return blockwise ? data_offset : data_offset << SECTOR_SHIFT;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic)
|
||||
{
|
||||
@@ -3277,7 +3292,7 @@ int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
data_offset = crypt_get_data_offset(cd) << SECTOR_SHIFT;
|
||||
data_offset = LUKS2_reencrypt_data_offset(hdr, false);
|
||||
|
||||
r = device_check_size(cd, crypt_data_device(cd), data_offset, 1);
|
||||
if (r)
|
||||
@@ -3287,6 +3302,12 @@ int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
log_dbg(cd, "Required minimal device size: %" PRIu64 " (%" PRIu64 " sectors)"
|
||||
", real device size: %" PRIu64 " (%" PRIu64 " sectors)\n"
|
||||
"calculated device size: %" PRIu64 " (%" PRIu64 " sectors)",
|
||||
check_size, check_size >> SECTOR_SHIFT, real_size, real_size >> SECTOR_SHIFT,
|
||||
real_size - data_offset, (real_size - data_offset) >> SECTOR_SHIFT);
|
||||
|
||||
if (real_size < data_offset || (check_size && (real_size - data_offset) < check_size)) {
|
||||
log_err(cd, _("Device %s is too small."), device_path(crypt_data_device(cd)));
|
||||
return -EINVAL;
|
||||
|
||||
Reference in New Issue
Block a user