Message ID | 20221203001243.16482-1-luca.boccassi@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v2] sed-opal: allow using IOC_OPAL_SAVE for locking too | expand |
On Sat, Dec 03, 2022 at 12:12:43AM +0000, luca.boccassi@gmail.com wrote: > + * Usually when closing a crypto device (eg: dm-crypt with LUKS) the volume As said last time, please correctly format your block comments so that they don't spill out of 80 characters for every single line and become completely unreadable. > + if (lk_unlk->l_state == OPAL_LK && > + lk_unlk->session.opal_key.key_len == 0) { > + struct opal_suspend_data *iter; > + > + setup_opal_dev(dev); > + list_for_each_entry(iter, &dev->unlk_lst, node) { > + if (iter->unlk.save_for_lock && > + iter->lr == lk_unlk->session.opal_key.lr && > + iter->unlk.session.opal_key.key_len > 0) { > + lk_unlk->session.opal_key.key_len = > + iter->unlk.session.opal_key.key_len; > + memcpy(lk_unlk->session.opal_key.key, > + iter->unlk.session.opal_key.key, > + iter->unlk.session.opal_key.key_len); > + break; > + } > + } And please split this logic into a helper. > __u32 l_state; > - __u8 __align[4]; > + __u8 save_for_lock:1; /* if in IOC_OPAL_SAVE will also use key to lock */ Please never use bitfields in ABIs, the psABI rules for them are just a mess to start with, and not filling all of them leads to leaks of stack contents as well. Just turn the entire 4 bytes into a flags field and then just bitmasks.
diff --git a/block/sed-opal.c b/block/sed-opal.c index 9bdb833e5817..3a81754a0fdf 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -2470,6 +2470,38 @@ static int opal_lock_unlock(struct opal_dev *dev, return -EINVAL; mutex_lock(&dev->dev_lock); + + /* + * Usually when closing a crypto device (eg: dm-crypt with LUKS) the volume + * key is not required, as it requires root privileges anyway, and root can + * deny access to a disk in many ways regardless. Requiring the volume key + * to lock the device is a peculiarity of the OPAL specification. + * Given we might already have saved the key if the user requested it via + * the 'IOC_OPAL_SAVE' ioctl, we can use that key to lock the device if no + * key was provided here, the locking range matches and the appropriate + * flag was passed with 'IOC_OPAL_SAVE'. This allows integrating OPAL with + * tools and libraries that are used to the common behaviour and do not ask + * for the volume key when closing a device. + */ + if (lk_unlk->l_state == OPAL_LK && + lk_unlk->session.opal_key.key_len == 0) { + struct opal_suspend_data *iter; + + setup_opal_dev(dev); + list_for_each_entry(iter, &dev->unlk_lst, node) { + if (iter->unlk.save_for_lock && + iter->lr == lk_unlk->session.opal_key.lr && + iter->unlk.session.opal_key.key_len > 0) { + lk_unlk->session.opal_key.key_len = + iter->unlk.session.opal_key.key_len; + memcpy(lk_unlk->session.opal_key.key, + iter->unlk.session.opal_key.key, + iter->unlk.session.opal_key.key_len); + break; + } + } + } + ret = __opal_lock_unlock(dev, lk_unlk); mutex_unlock(&dev->dev_lock); diff --git a/include/uapi/linux/sed-opal.h b/include/uapi/linux/sed-opal.h index 2573772e2fb3..fa604fb07f50 100644 --- a/include/uapi/linux/sed-opal.h +++ b/include/uapi/linux/sed-opal.h @@ -76,7 +76,8 @@ struct opal_user_lr_setup { struct opal_lock_unlock { struct opal_session_info session; __u32 l_state; - __u8 __align[4]; + __u8 save_for_lock:1; /* if in IOC_OPAL_SAVE will also use key to lock */ + __u8 __align[3]; }; struct opal_new_pw {