Check data device offset if it fits data device size in luksFormat.

This commit is contained in:
Milan Broz
2018-12-11 21:28:51 +01:00
parent 7d8003da46
commit 2a1d58ed22
6 changed files with 41 additions and 28 deletions

View File

@@ -112,6 +112,9 @@ size_t device_alignment(struct device *device);
int device_direct_io(const struct device *device);
int device_fallocate(struct device *device, uint64_t size);
void device_sync(struct crypt_device *cd, struct device *device, int devfd);
int device_check_size(struct crypt_device *cd,
struct device *device,
uint64_t req_offset, int falloc);
int device_open_locked(struct crypt_device *cd, struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device);

View File

@@ -359,31 +359,6 @@ static int hdr_write_disk(struct crypt_device *cd,
return r;
}
static int LUKS2_check_device_size(struct crypt_device *cd, struct device *device,
uint64_t hdr_size, int falloc)
{
uint64_t dev_size;
if (device_size(device, &dev_size)) {
log_dbg(cd, "Cannot get device size for device %s.", device_path(device));
return -EIO;
}
log_dbg(cd, "Device size %" PRIu64 ", header size %" PRIu64 ".", dev_size, hdr_size);
if (hdr_size > dev_size) {
/* If it is header file, increase its size */
if (falloc && !device_fallocate(device, hdr_size))
return 0;
log_err(cd, _("Device %s is too small. (LUKS2 requires at least %" PRIu64 " bytes.)"),
device_path(device), hdr_size);
return -EINVAL;
}
return 0;
}
/*
* Convert in-memory LUKS2 header and write it to disk.
* This will increase sequence id, write both header copies and calculate checksum.
@@ -400,7 +375,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
return -EINVAL;
}
r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
r = device_check_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
if (r)
return r;
@@ -665,7 +640,7 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
goto err;
}
r = LUKS2_check_device_size(cd, device, hdr_size, 0);
r = device_check_size(cd, device, hdr_size, 0);
if (r)
goto err;

View File

@@ -1519,6 +1519,10 @@ static int _crypt_format_luks1(struct crypt_device *cd,
if (r < 0)
return r;
r = device_check_size(cd, crypt_data_device(cd), crypt_get_data_offset(cd) * SECTOR_SIZE, 0);
if (r < 0)
return r;
r = LUKS_wipe_header_areas(&cd->u.luks1.hdr, cd);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
@@ -1676,6 +1680,10 @@ static int _crypt_format_luks2(struct crypt_device *cd,
if (r < 0)
goto out;
r = device_check_size(cd, crypt_data_device(cd), crypt_get_data_offset(cd) * SECTOR_SIZE, 0);
if (r < 0)
return r;
if (!integrity && sector_size > SECTOR_SIZE && !device_size(crypt_data_device(cd), &dev_size)) {
dev_size -= (crypt_get_data_offset(cd) * SECTOR_SIZE);
if (dev_size % sector_size) {

View File

@@ -539,6 +539,32 @@ int device_fallocate(struct device *device, uint64_t size)
return r;
}
int device_check_size(struct crypt_device *cd,
struct device *device,
uint64_t req_offset, int falloc)
{
uint64_t dev_size;
if (device_size(device, &dev_size)) {
log_dbg(cd, "Cannot get device size for device %s.", device_path(device));
return -EIO;
}
log_dbg(cd, "Device size %" PRIu64 ", offset %" PRIu64 ".", dev_size, req_offset);
if (req_offset > dev_size) {
/* If it is header file, increase its size */
if (falloc && !device_fallocate(device, req_offset))
return 0;
log_err(cd, _("Device %s is too small. Need at least %" PRIu64 " bytes."),
device_path(device), req_offset);
return -EINVAL;
}
return 0;
}
static int device_info(struct crypt_device *cd,
struct device *device,
enum devcheck device_check,

View File

@@ -263,7 +263,7 @@ static int _setup(void)
fd = loop_attach(&DEVICE_1, IMAGE1, 0, 0, &ro);
close(fd);
_system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=4 2>/dev/null", 1);
_system("dd if=/dev/zero of=" IMAGE_EMPTY " bs=1M count=10 2>/dev/null", 1);
fd = loop_attach(&DEVICE_2, IMAGE_EMPTY, 0, 0, &ro);
close(fd);

View File

@@ -679,6 +679,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --head
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 --offset 8192 >/dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --offset 80000 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --offset 8192 || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --offset 0 || fail
echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail