opal: add exclusive lock to avoid race.

Activating LUKS2 device with OPAL support is multistep process.

1) read LR state
2) unlock LR
3) activate dm device
4) in case step 3) failed lock the device
   if in step 1) the device was locked.

Otherwise, in case parallel activation happened on one device
the process that failed to map dm device (device already active)
could relock the LR afterwards and effectively break already active
device.

To avoid that we do steps 1) through 4) protected by exclusive
opal lock unique per data block device configured for use with
LUKS2 OPAL support.
This commit is contained in:
Ondrej Kozina
2023-12-13 15:06:03 +01:00
committed by Milan Broz
parent 2e978c8776
commit 0ca1e680db
5 changed files with 130 additions and 4 deletions

View File

@@ -321,6 +321,7 @@ int crypt_wipe_hw_opal(struct crypt_device *cd,
int r;
struct luks2_hdr *hdr;
uint32_t opal_segment_number;
struct crypt_lock_handle *opal_lh = NULL;
UNUSED(flags);
@@ -362,11 +363,19 @@ int crypt_wipe_hw_opal(struct crypt_device *cd,
} else
opal_segment_number = segment;
r = opal_exclusive_lock(cd, crypt_data_device(cd), &opal_lh);
if (r < 0) {
log_err(cd, _("Failed to acquire opal lock on device %s."), device_path(crypt_data_device(cd)));
return -EINVAL;
}
r = opal_reset_segment(cd,
crypt_data_device(cd),
opal_segment_number,
password,
password_size);
opal_exclusive_unlock(cd, opal_lh);
if (r < 0)
return r;