diff --git a/lib/luks2/luks2_luks1_convert.c b/lib/luks2/luks2_luks1_convert.c index 3d9482a3..08a3ddc1 100644 --- a/lib/luks2/luks2_luks1_convert.c +++ b/lib/luks2/luks2_luks1_convert.c @@ -475,6 +475,37 @@ static int luks_header_in_use(struct crypt_device *cd) return r; } +/* Check if there is a luksmeta area (foreign metadata created by the luksmeta package) */ +static int luksmeta_header_present(struct crypt_device *cd, off_t luks1_size) +{ + static const uint8_t LM_MAGIC[] = { 'L', 'U', 'K', 'S', 'M', 'E', 'T', 'A' }; + struct device *device = crypt_metadata_device(cd); + void *buf = NULL; + int devfd, r = 0; + + if (posix_memalign(&buf, crypt_getpagesize(), sizeof(LM_MAGIC))) + return -ENOMEM; + + devfd = device_open(device, O_RDONLY); + if (devfd == -1) { + log_dbg("Cannot open device %s.", device_path(device)); + free(buf); + return -EIO; + } + + /* Note: we must not detect failure as problem here, header can be trimmed. */ + if (read_lseek_blockwise(devfd, device_block_size(device), device_alignment(device), + buf, sizeof(LM_MAGIC), luks1_size) == (ssize_t)sizeof(LM_MAGIC) && + !memcmp(LM_MAGIC, buf, sizeof(LM_MAGIC))) { + log_err(cd, _("Unable to convert header with LUKSMETA additional metadata.\n")); + r = -EBUSY; + } + + close(devfd); + free(buf); + return r; +} + /* Convert LUKS1 -> LUKS2 */ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct luks2_hdr *hdr2) { @@ -497,6 +528,9 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct return -EINVAL; } + if (luksmeta_header_present(cd, luks1_size)) + return -EINVAL; + log_dbg("Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu", max_size, luks1_size, luks1_shift); if ((max_size - luks1_size) < luks1_shift) {