mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
integrity: Detect PI/DIF capable devices in inline mode.
And print better error if not.
This commit is contained in:
@@ -116,6 +116,7 @@ int device_is_identical(struct device *device1, struct device *device2);
|
|||||||
int device_is_rotational(struct device *device);
|
int device_is_rotational(struct device *device);
|
||||||
int device_is_dax(struct device *device);
|
int device_is_dax(struct device *device);
|
||||||
int device_is_zoned(struct device *device);
|
int device_is_zoned(struct device *device);
|
||||||
|
int device_is_nop_dif(struct device *device, uint32_t *tag_size);
|
||||||
size_t device_alignment(struct device *device);
|
size_t device_alignment(struct device *device);
|
||||||
int device_direct_io(const struct device *device);
|
int device_direct_io(const struct device *device);
|
||||||
int device_fallocate(struct device *device, uint64_t size);
|
int device_fallocate(struct device *device, uint64_t size);
|
||||||
@@ -167,6 +168,7 @@ char *crypt_lookup_dev(const char *dev_id);
|
|||||||
int crypt_dev_is_rotational(int major, int minor);
|
int crypt_dev_is_rotational(int major, int minor);
|
||||||
int crypt_dev_is_dax(int major, int minor);
|
int crypt_dev_is_dax(int major, int minor);
|
||||||
int crypt_dev_is_zoned(int major, int minor);
|
int crypt_dev_is_zoned(int major, int minor);
|
||||||
|
int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size);
|
||||||
int crypt_dev_is_partition(const char *dev_path);
|
int crypt_dev_is_partition(const char *dev_path);
|
||||||
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
|
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
|
||||||
int crypt_dev_get_partition_number(const char *dev_path);
|
int crypt_dev_get_partition_number(const char *dev_path);
|
||||||
|
|||||||
12
lib/setup.c
12
lib/setup.c
@@ -3068,6 +3068,7 @@ int crypt_format_inline(struct crypt_device *cd,
|
|||||||
void *params)
|
void *params)
|
||||||
{
|
{
|
||||||
const struct crypt_params_integrity *iparams;
|
const struct crypt_params_integrity *iparams;
|
||||||
|
uint32_t device_tag_size;
|
||||||
struct device *idevice;
|
struct device *idevice;
|
||||||
size_t sector_size, required_sector_size;
|
size_t sector_size, required_sector_size;
|
||||||
int r;
|
int r;
|
||||||
@@ -3113,6 +3114,17 @@ int crypt_format_inline(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!device_is_nop_dif(crypt_metadata_device(cd), &device_tag_size)) {
|
||||||
|
log_err(cd, _("Device %s does not provide inline integrity data fields."), mdata_device_path(cd));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_tag_size < iparams->tag_size) {
|
||||||
|
log_err(cd, _("Inline tag size %" PRIu32 " [bytes] is larger than %" PRIu32 " provided by device %s."),
|
||||||
|
iparams->tag_size, device_tag_size, mdata_device_path(cd));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (isINTEGRITY(type))
|
if (isINTEGRITY(type))
|
||||||
r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, true);
|
r = _crypt_format_integrity(cd, uuid, params, volume_key, volume_key_size, true);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1017,6 +1017,22 @@ int device_is_zoned(struct device *device)
|
|||||||
return crypt_dev_is_zoned(major(st.st_rdev), minor(st.st_rdev));
|
return crypt_dev_is_zoned(major(st.st_rdev), minor(st.st_rdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_is_nop_dif(struct device *device, uint32_t *tag_size)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (stat(device_path(device), &st) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!S_ISBLK(st.st_mode))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return crypt_dev_is_nop_dif(major(st.st_rdev), minor(st.st_rdev), tag_size);
|
||||||
|
}
|
||||||
|
|
||||||
size_t device_alignment(struct device *device)
|
size_t device_alignment(struct device *device)
|
||||||
{
|
{
|
||||||
int devfd;
|
int devfd;
|
||||||
|
|||||||
@@ -262,6 +262,29 @@ int crypt_dev_is_zoned(int major, int minor)
|
|||||||
return strncmp(buf, "none", 4) ? 1 : 0;
|
return strncmp(buf, "none", 4) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size)
|
||||||
|
{
|
||||||
|
char buf[64] = {};
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
if (!_sysfs_get_string(major, minor, buf, sizeof(buf), "integrity/format"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strncmp(buf, "nop", 3))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* this field is currently supported only for NVMe */
|
||||||
|
_sysfs_get_uint64(major, minor, &val, "metadata_bytes");
|
||||||
|
|
||||||
|
/* tag_size should be 0, but it is set by dm-integrity, try it as a fallback */
|
||||||
|
if (val == 0)
|
||||||
|
_sysfs_get_uint64(major, minor, &val, "integrity/tag_size");
|
||||||
|
|
||||||
|
/* we can still return 0 and support metadata, caller must handle it */
|
||||||
|
*tag_size = (uint32_t)val;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_dev_is_partition(const char *dev_path)
|
int crypt_dev_is_partition(const char *dev_path)
|
||||||
{
|
{
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|||||||
Reference in New Issue
Block a user