Do not try to load LUKS2 header if backup_file is LUKS1.

Also do not allow header restore if a different version is requested.
This commit is contained in:
Milan Broz
2017-10-06 12:17:30 +02:00
parent cc5c91158d
commit de2f07b82f
5 changed files with 36 additions and 22 deletions

View File

@@ -103,7 +103,7 @@ void device_disable_direct_io(struct device *device);
int device_is_identical(struct device *device1, struct device *device2);
int device_is_rotational(struct device *device);
size_t device_alignment(struct device *device);
int device_direct_io(struct device *device);
int device_direct_io(const struct device *device);
int device_open_locked(struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device);

View File

@@ -109,7 +109,8 @@ struct luks2_hdr {
#define LUKS2_MAX_KEYSLOTS_SIZE 0x8000000 /* 128 MiB */
int LUKS2_hdr_version_unlocked(struct crypt_device *cd);
int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
const char *backup_file);
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr);

View File

@@ -666,14 +666,19 @@ err:
return r;
}
int LUKS2_hdr_version_unlocked(struct crypt_device *cd)
int LUKS2_hdr_version_unlocked(struct crypt_device *cd, const char *backup_file)
{
struct {
char magic[LUKS2_MAGIC_L];
uint16_t version;
} __attribute__ ((packed)) hdr;
struct device *device = crypt_metadata_device(cd);
int r, devfd, flags;
struct device *device = NULL;
int r = 0, devfd = -1, flags;
if (!backup_file)
device = crypt_metadata_device(cd);
else if (device_alloc(&device, backup_file) < 0)
return 0;
if (!device)
return 0;
@@ -684,16 +689,18 @@ int LUKS2_hdr_version_unlocked(struct crypt_device *cd)
devfd = open(device_path(device), flags);
if (devfd < 0)
return 0;
goto err;
if ((read_lseek_blockwise(devfd, device_block_size(device),
device_alignment(device), &hdr, sizeof(hdr), 0)
!= sizeof(hdr)) ||
memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
r = 0;
else
device_alignment(device), &hdr, sizeof(hdr), 0) == sizeof(hdr)) &&
!memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
r = (int)be16_to_cpu(hdr.version);
err:
if (devfd != -1)
close(devfd);
if (backup_file)
device_free(device);
return r;
}

View File

@@ -724,7 +724,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
/* This will return 0 if primary LUKS2 header is damaged */
if (!requested_type)
version = LUKS2_hdr_version_unlocked(cd);
version = LUKS2_hdr_version_unlocked(cd, NULL);
if (isLUKS1(requested_type) || version == 1) {
if (cd->type && isLUKS2(cd->type)) {
@@ -2162,7 +2162,7 @@ int crypt_header_restore(struct crypt_device *cd,
{
struct luks_phdr hdr1;
struct luks2_hdr hdr2;
int r;
int r, version;
if (requested_type && !isLUKS(requested_type))
return -EINVAL;
@@ -2177,15 +2177,21 @@ int crypt_header_restore(struct crypt_device *cd,
log_dbg("Requested header restore to device %s (%s) from "
"file %s.", mdata_device_path(cd), requested_type ?: "any type", backup_file);
memset(&hdr2, 0, sizeof(hdr2));
if (!cd->type) {
if (!requested_type || isLUKS2(requested_type))
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
else
r = -ENOENT;
version = LUKS2_hdr_version_unlocked(cd, backup_file);
if (!version ||
(requested_type && version == 1 && !isLUKS1(requested_type)) ||
(requested_type && version == 2 && !isLUKS2(requested_type))) {
log_err(cd, _("Header backup file does not contain compatible LUKS header.\n"));
return -EINVAL;
}
if (r && (!requested_type || isLUKS1(requested_type)))
memset(&hdr2, 0, sizeof(hdr2));
if (!cd->type) {
if (version == 1)
r = LUKS_hdr_restore(backup_file, &hdr1, cd);
else
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
LUKS2_hdr_free(&hdr2);
crypt_memzero(&hdr1, sizeof(hdr1));

View File

@@ -693,7 +693,7 @@ void device_disable_direct_io(struct device *device)
device->o_direct = 0;
}
int device_direct_io(struct device *device)
int device_direct_io(const struct device *device)
{
return device->o_direct;
}