mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Check HW OPAL range parameters in proper units.
The opal_range_check_attributes_fd function expected both offset and length parameters of a LR to be passed in sectors (512B). During format we passed it wrongly in OPAL blocks which caused bogus check provided OPAL block size was not 512B. Fixes: #871.
This commit is contained in:
@@ -405,8 +405,9 @@ static int opal_enabled(struct crypt_device *cd, struct device *dev)
|
||||
int opal_setup_ranges(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
const struct volume_key *vk,
|
||||
uint64_t range_start,
|
||||
uint64_t range_length,
|
||||
uint64_t range_start_blocks,
|
||||
uint64_t range_length_blocks,
|
||||
uint32_t opal_block_bytes,
|
||||
uint32_t segment_number,
|
||||
const void *admin_key,
|
||||
size_t admin_key_len)
|
||||
@@ -423,10 +424,15 @@ int opal_setup_ranges(struct crypt_device *cd,
|
||||
assert(vk);
|
||||
assert(admin_key);
|
||||
assert(vk->keylength <= OPAL_KEY_MAX);
|
||||
assert(opal_block_bytes >= SECTOR_SIZE);
|
||||
|
||||
if (admin_key_len > OPAL_KEY_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (((UINT64_MAX / opal_block_bytes) < range_start_blocks) ||
|
||||
((UINT64_MAX / opal_block_bytes) < range_length_blocks))
|
||||
return -EINVAL;
|
||||
|
||||
fd = device_open(cd, dev, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -EIO;
|
||||
@@ -604,8 +610,8 @@ int opal_setup_ranges(struct crypt_device *cd,
|
||||
goto out;
|
||||
}
|
||||
*setup = (struct opal_user_lr_setup) {
|
||||
.range_start = range_start,
|
||||
.range_length = range_length,
|
||||
.range_start = range_start_blocks,
|
||||
.range_length = range_length_blocks,
|
||||
/* Some drives do not enable Locking Ranges on setup. This have some
|
||||
* interesting consequences: Lock command called later below will pass,
|
||||
* but locking range will _not_ be locked at all.
|
||||
@@ -658,9 +664,10 @@ int opal_setup_ranges(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
/* Double check the locking range is locked and the ranges are set up as configured */
|
||||
r = opal_range_check_attributes_fd(cd, fd, segment_number, vk, &range_start,
|
||||
&range_length, &(bool) {true}, &(bool){true},
|
||||
NULL, NULL);
|
||||
r = opal_range_check_attributes_fd(cd, fd, segment_number, vk,
|
||||
&(uint64_t) {range_start_blocks * opal_block_bytes / SECTOR_SIZE},
|
||||
&(uint64_t) {range_length_blocks * opal_block_bytes / SECTOR_SIZE},
|
||||
&(bool) {true}, &(bool){true}, NULL, NULL);
|
||||
out:
|
||||
crypt_safe_free(activate);
|
||||
crypt_safe_free(user_session);
|
||||
@@ -1011,8 +1018,9 @@ void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *op
|
||||
int opal_setup_ranges(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
const struct volume_key *vk,
|
||||
uint64_t range_start,
|
||||
uint64_t range_length,
|
||||
uint64_t range_start_blocks,
|
||||
uint64_t range_length_blocks,
|
||||
uint32_t opal_block_bytes,
|
||||
uint32_t segment_number,
|
||||
const void *admin_key,
|
||||
size_t admin_key_len)
|
||||
|
||||
@@ -29,8 +29,9 @@ struct crypt_lock_handle;
|
||||
int opal_setup_ranges(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
const struct volume_key *vk,
|
||||
uint64_t range_start,
|
||||
uint64_t range_length,
|
||||
uint64_t range_start_blocks,
|
||||
uint64_t range_length_blocks,
|
||||
uint32_t opal_block_bytes,
|
||||
uint32_t segment_number,
|
||||
const void *admin_key,
|
||||
size_t admin_key_len);
|
||||
|
||||
Reference in New Issue
Block a user