mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Opal: Do not allow format if device and Opal logical block size disagrees
Some Opal devices contain a bug that device reports different logical size for block device and Opal SED layer. This can happen for NVMe after reformatting with different LBAF (512/4096). We will not support such configuration as Opal then calculates sizes differently for locking range (that could lead to data corruption or a partially unecrypted area).
This commit is contained in:
14
lib/setup.c
14
lib/setup.c
@@ -2232,7 +2232,7 @@ static int opal_topology_alignment(struct crypt_device *cd,
|
|||||||
{
|
{
|
||||||
bool opal_align;
|
bool opal_align;
|
||||||
int r;
|
int r;
|
||||||
uint32_t opal_block_bytes;
|
uint32_t opal_block_bytes, device_block_bytes;
|
||||||
uint64_t opal_alignment_granularity_blocks, opal_lowest_lba_blocks;
|
uint64_t opal_alignment_granularity_blocks, opal_lowest_lba_blocks;
|
||||||
|
|
||||||
assert(cd);
|
assert(cd);
|
||||||
@@ -2248,15 +2248,23 @@ static int opal_topology_alignment(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_dbg(cd, "OPAL geometry: alignment: '%c', logical block size: %" PRIu32
|
device_block_bytes = device_block_size(cd, crypt_data_device(cd));
|
||||||
|
|
||||||
|
log_dbg(cd, "OPAL geometry: alignment: '%c', logical block size: %" PRIu32 "/%" PRIu32
|
||||||
", alignment granularity: %" PRIu64 ", lowest aligned LBA: %" PRIu64,
|
", alignment granularity: %" PRIu64 ", lowest aligned LBA: %" PRIu64,
|
||||||
opal_align ? 'y' : 'n', opal_block_bytes, opal_alignment_granularity_blocks, opal_lowest_lba_blocks);
|
opal_align ? 'y' : 'n', opal_block_bytes, device_block_bytes,
|
||||||
|
opal_alignment_granularity_blocks, opal_lowest_lba_blocks);
|
||||||
|
|
||||||
if (opal_block_bytes < SECTOR_SIZE || NOTPOW2(opal_block_bytes)) {
|
if (opal_block_bytes < SECTOR_SIZE || NOTPOW2(opal_block_bytes)) {
|
||||||
log_err(cd, _("Bogus OPAL logical block size."));
|
log_err(cd, _("Bogus OPAL logical block size."));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_block_bytes != opal_block_bytes) {
|
||||||
|
log_err(cd, _("Bogus OPAL logical block size differs from device block size."));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (data_offset_sectors &&
|
if (data_offset_sectors &&
|
||||||
MISALIGNED(data_offset_sectors + partition_offset_sectors, opal_block_bytes / SECTOR_SIZE)) {
|
MISALIGNED(data_offset_sectors + partition_offset_sectors, opal_block_bytes / SECTOR_SIZE)) {
|
||||||
log_err(cd, _("Requested data offset is not compatible with OPAL block size."));
|
log_err(cd, _("Requested data offset is not compatible with OPAL block size."));
|
||||||
|
|||||||
Reference in New Issue
Block a user