mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 00:10:04 +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;
|
||||
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;
|
||||
|
||||
assert(cd);
|
||||
@@ -2248,15 +2248,23 @@ static int opal_topology_alignment(struct crypt_device *cd,
|
||||
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,
|
||||
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)) {
|
||||
log_err(cd, _("Bogus OPAL logical block size."));
|
||||
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 &&
|
||||
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."));
|
||||
|
||||
Reference in New Issue
Block a user