mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Detect unsupported zoned devices for LUKS header device.
Zoned device cannot be written with direct-io and cannot be used for LUKS header logic without significant changes. Do not allow to use them for LUKS header but allow it for data device, as dm-crypt supports it. Fixes: #877
This commit is contained in:
@@ -116,6 +116,7 @@ void device_disable_direct_io(struct device *device);
|
|||||||
int device_is_identical(struct device *device1, struct device *device2);
|
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);
|
||||||
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);
|
||||||
@@ -166,6 +167,7 @@ int crypt_confirm(struct crypt_device *cd, const char *msg);
|
|||||||
char *crypt_lookup_dev(const char *dev_id);
|
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_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
@@ -1790,6 +1790,12 @@ static int _crypt_format_luks1(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_is_zoned(crypt_metadata_device(cd)) > 0) {
|
||||||
|
log_err(cd, _("Zoned device %s cannot be used for LUKS header."),
|
||||||
|
device_path(crypt_metadata_device(cd)));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (params && cd->data_offset && params->data_alignment &&
|
if (params && cd->data_offset && params->data_alignment &&
|
||||||
(cd->data_offset % params->data_alignment)) {
|
(cd->data_offset % params->data_alignment)) {
|
||||||
log_err(cd, _("Requested data alignment is not compatible with data offset."));
|
log_err(cd, _("Requested data alignment is not compatible with data offset."));
|
||||||
@@ -2027,6 +2033,12 @@ static int _crypt_format_luks2(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device_is_zoned(crypt_metadata_device(cd)) > 0) {
|
||||||
|
log_err(cd, _("Zoned device %s cannot be used for LUKS header."),
|
||||||
|
device_path(crypt_metadata_device(cd)));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (params && cd->data_offset && params->data_alignment &&
|
if (params && cd->data_offset && params->data_alignment &&
|
||||||
(cd->data_offset % params->data_alignment)) {
|
(cd->data_offset % params->data_alignment)) {
|
||||||
log_err(cd, _("Requested data alignment is not compatible with data offset."));
|
log_err(cd, _("Requested data alignment is not compatible with data offset."));
|
||||||
|
|||||||
@@ -1007,6 +1007,22 @@ int device_is_dax(struct device *device)
|
|||||||
return crypt_dev_is_dax(major(st.st_rdev), minor(st.st_rdev));
|
return crypt_dev_is_dax(major(st.st_rdev), minor(st.st_rdev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_is_zoned(struct device *device)
|
||||||
|
{
|
||||||
|
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_zoned(major(st.st_rdev), minor(st.st_rdev));
|
||||||
|
}
|
||||||
|
|
||||||
size_t device_alignment(struct device *device)
|
size_t device_alignment(struct device *device)
|
||||||
{
|
{
|
||||||
int devfd;
|
int devfd;
|
||||||
|
|||||||
@@ -210,6 +210,23 @@ static int _path_get_uint64(const char *sysfs_path, uint64_t *value, const char
|
|||||||
return _read_uint64(path, value);
|
return _read_uint64(path, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _sysfs_get_string(int major, int minor, char *buf, size_t buf_size, const char *attr)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int fd, r;
|
||||||
|
|
||||||
|
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/%s",
|
||||||
|
major, minor, attr) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((fd = open(path, O_RDONLY)) < 0)
|
||||||
|
return 0;
|
||||||
|
r = read(fd, buf, buf_size);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return r < 0 ? 0 : r;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_dev_get_partition_number(const char *dev_path)
|
int crypt_dev_get_partition_number(const char *dev_path)
|
||||||
{
|
{
|
||||||
uint64_t partno;
|
uint64_t partno;
|
||||||
@@ -248,6 +265,16 @@ int crypt_dev_is_dax(int major, int minor)
|
|||||||
return val ? 1 : 0;
|
return val ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int crypt_dev_is_zoned(int major, int minor)
|
||||||
|
{
|
||||||
|
char buf[32] = {};
|
||||||
|
|
||||||
|
if (!_sysfs_get_string(major, minor, buf, sizeof(buf), "queue/zoned"))
|
||||||
|
return 0; /* if failed, expect non-zoned device */
|
||||||
|
|
||||||
|
return strncmp(buf, "none", 4) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int crypt_dev_is_partition(const char *dev_path)
|
int crypt_dev_is_partition(const char *dev_path)
|
||||||
{
|
{
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|||||||
@@ -1604,5 +1604,16 @@ dmsetup resume $DEV_NAME || fail
|
|||||||
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
|
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
|
||||||
dmsetup remove --retry $DEV_NAME || fail
|
dmsetup remove --retry $DEV_NAME || fail
|
||||||
|
|
||||||
|
prepare "[47] Zoned device is unusable for LUKS header" wipe
|
||||||
|
add_scsi_device dev_size_mb=32 sector_size=4096 zbc=host-managed
|
||||||
|
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $DEV > /dev/null 2>&1 && fail
|
||||||
|
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT --header $HEADER_IMG $DEV >/dev/null || fail
|
||||||
|
echo $PWD1 | $CRYPTSETUP open --header $HEADER_IMG $DEV $DEV_NAME || fail
|
||||||
|
$CRYPTSETUP close $DEV_NAME || fail
|
||||||
|
echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $DEV > /dev/null 2>&1 && fail
|
||||||
|
echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT --header $HEADER_IMG $DEV >/dev/null || fail
|
||||||
|
echo $PWD1 | $CRYPTSETUP open --header $HEADER_IMG $DEV $DEV_NAME || fail
|
||||||
|
$CRYPTSETUP close $DEV_NAME || fail
|
||||||
|
|
||||||
remove_mapping
|
remove_mapping
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user