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_identical(struct device *device1, struct device *device2);
int device_is_rotational(struct device *device); int device_is_rotational(struct device *device);
size_t device_alignment(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_open_locked(struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device); 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 */ #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_read(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_write(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; 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 { struct {
char magic[LUKS2_MAGIC_L]; char magic[LUKS2_MAGIC_L];
uint16_t version; uint16_t version;
} __attribute__ ((packed)) hdr; } __attribute__ ((packed)) hdr;
struct device *device = crypt_metadata_device(cd); struct device *device = NULL;
int r, devfd, flags; 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) if (!device)
return 0; return 0;
@@ -684,16 +689,18 @@ int LUKS2_hdr_version_unlocked(struct crypt_device *cd)
devfd = open(device_path(device), flags); devfd = open(device_path(device), flags);
if (devfd < 0) if (devfd < 0)
return 0; goto err;
if ((read_lseek_blockwise(devfd, device_block_size(device), if ((read_lseek_blockwise(devfd, device_block_size(device),
device_alignment(device), &hdr, sizeof(hdr), 0) device_alignment(device), &hdr, sizeof(hdr), 0) == sizeof(hdr)) &&
!= sizeof(hdr)) || !memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
r = 0;
else
r = (int)be16_to_cpu(hdr.version); r = (int)be16_to_cpu(hdr.version);
err:
if (devfd != -1)
close(devfd); close(devfd);
if (backup_file)
device_free(device);
return r; 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 */ /* This will return 0 if primary LUKS2 header is damaged */
if (!requested_type) if (!requested_type)
version = LUKS2_hdr_version_unlocked(cd); version = LUKS2_hdr_version_unlocked(cd, NULL);
if (isLUKS1(requested_type) || version == 1) { if (isLUKS1(requested_type) || version == 1) {
if (cd->type && isLUKS2(cd->type)) { if (cd->type && isLUKS2(cd->type)) {
@@ -2162,7 +2162,7 @@ int crypt_header_restore(struct crypt_device *cd,
{ {
struct luks_phdr hdr1; struct luks_phdr hdr1;
struct luks2_hdr hdr2; struct luks2_hdr hdr2;
int r; int r, version;
if (requested_type && !isLUKS(requested_type)) if (requested_type && !isLUKS(requested_type))
return -EINVAL; return -EINVAL;
@@ -2177,15 +2177,21 @@ int crypt_header_restore(struct crypt_device *cd,
log_dbg("Requested header restore to device %s (%s) from " log_dbg("Requested header restore to device %s (%s) from "
"file %s.", mdata_device_path(cd), requested_type ?: "any type", backup_file); "file %s.", mdata_device_path(cd), requested_type ?: "any type", backup_file);
memset(&hdr2, 0, sizeof(hdr2)); version = LUKS2_hdr_version_unlocked(cd, backup_file);
if (!cd->type) { if (!version ||
if (!requested_type || isLUKS2(requested_type)) (requested_type && version == 1 && !isLUKS1(requested_type)) ||
r = LUKS2_hdr_restore(cd, &hdr2, backup_file); (requested_type && version == 2 && !isLUKS2(requested_type))) {
else log_err(cd, _("Header backup file does not contain compatible LUKS header.\n"));
r = -ENOENT; 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); r = LUKS_hdr_restore(backup_file, &hdr1, cd);
else
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
LUKS2_hdr_free(&hdr2); LUKS2_hdr_free(&hdr2);
crypt_memzero(&hdr1, sizeof(hdr1)); crypt_memzero(&hdr1, sizeof(hdr1));

View File

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