mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 06:05:27 +00:00
storage: Fix capacity value for LUKS encrypted volumes
https://bugzilla.redhat.com/show_bug.cgi?id=1371892 The 'capacity' value (e.g. guest logical size) for a LUKS volume is smaller than the 'physical' value of the file in the file system, so we need to account for that. When peeking at the encryption information about the volume add a fetch of the payload_offset which is described as the offset to the start of the volume data (in 512 byte sectors) in QEMU's QCryptoBlockLUKSHeader. Then adjust the ->capacity appropriately when we determine that the volume target encryption has a payload_offset value.
This commit is contained in:
parent
b202c39adc
commit
b7d44f450c
@ -3436,6 +3436,9 @@ storageBackendProbeTarget(virStorageSourcePtr target,
|
|||||||
target->capacity = meta->capacity;
|
target->capacity = meta->capacity;
|
||||||
|
|
||||||
if (encryption && meta->encryption) {
|
if (encryption && meta->encryption) {
|
||||||
|
if (meta->encryption->payload_offset != -1)
|
||||||
|
target->capacity -= meta->encryption->payload_offset * 512;
|
||||||
|
|
||||||
*encryption = meta->encryption;
|
*encryption = meta->encryption;
|
||||||
meta->encryption = NULL;
|
meta->encryption = NULL;
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ typedef struct _virStorageEncryption virStorageEncryption;
|
|||||||
typedef virStorageEncryption *virStorageEncryptionPtr;
|
typedef virStorageEncryption *virStorageEncryptionPtr;
|
||||||
struct _virStorageEncryption {
|
struct _virStorageEncryption {
|
||||||
int format; /* virStorageEncryptionFormatType */
|
int format; /* virStorageEncryptionFormatType */
|
||||||
|
int payload_offset;
|
||||||
|
|
||||||
size_t nsecrets;
|
size_t nsecrets;
|
||||||
virStorageEncryptionSecretPtr *secrets;
|
virStorageEncryptionSecretPtr *secrets;
|
||||||
|
@ -133,6 +133,8 @@ struct FileEncryptionInfo {
|
|||||||
|
|
||||||
int modeOffset; /* Byte offset of the format native encryption mode */
|
int modeOffset; /* Byte offset of the format native encryption mode */
|
||||||
char modeValue; /* Value expected at offset */
|
char modeValue; /* Value expected at offset */
|
||||||
|
|
||||||
|
int payloadOffset; /* start offset of the volume data (in 512 byte sectors) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Either 'magic' or 'extension' *must* be provided */
|
/* Either 'magic' or 'extension' *must* be provided */
|
||||||
@ -212,9 +214,18 @@ qedGetBackingStore(char **, int *, const char *, size_t);
|
|||||||
|
|
||||||
#define LUKS_HDR_MAGIC_LEN 6
|
#define LUKS_HDR_MAGIC_LEN 6
|
||||||
#define LUKS_HDR_VERSION_LEN 2
|
#define LUKS_HDR_VERSION_LEN 2
|
||||||
|
#define LUKS_HDR_CIPHER_NAME_LEN 32
|
||||||
|
#define LUKS_HDR_CIPHER_MODE_LEN 32
|
||||||
|
#define LUKS_HDR_HASH_SPEC_LEN 32
|
||||||
|
#define LUKS_HDR_PAYLOAD_LEN 4
|
||||||
|
|
||||||
/* Format described by qemu commit id '3e308f20e' */
|
/* Format described by qemu commit id '3e308f20e' */
|
||||||
#define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN
|
#define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN
|
||||||
|
#define LUKS_HDR_PAYLOAD_OFFSET (LUKS_HDR_MAGIC_LEN+\
|
||||||
|
LUKS_HDR_VERSION_LEN+\
|
||||||
|
LUKS_HDR_CIPHER_NAME_LEN+\
|
||||||
|
LUKS_HDR_CIPHER_MODE_LEN+\
|
||||||
|
LUKS_HDR_HASH_SPEC_LEN)
|
||||||
|
|
||||||
static struct FileEncryptionInfo const luksEncryptionInfo[] = {
|
static struct FileEncryptionInfo const luksEncryptionInfo[] = {
|
||||||
{
|
{
|
||||||
@ -231,6 +242,8 @@ static struct FileEncryptionInfo const luksEncryptionInfo[] = {
|
|||||||
|
|
||||||
.modeOffset = -1,
|
.modeOffset = -1,
|
||||||
.modeValue = -1,
|
.modeValue = -1,
|
||||||
|
|
||||||
|
.payloadOffset = LUKS_HDR_PAYLOAD_OFFSET,
|
||||||
},
|
},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -249,6 +262,8 @@ static struct FileEncryptionInfo const qcow1EncryptionInfo[] = {
|
|||||||
|
|
||||||
.modeOffset = QCOW1_HDR_CRYPT,
|
.modeOffset = QCOW1_HDR_CRYPT,
|
||||||
.modeValue = 1,
|
.modeValue = 1,
|
||||||
|
|
||||||
|
.payloadOffset = -1,
|
||||||
},
|
},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -267,6 +282,8 @@ static struct FileEncryptionInfo const qcow2EncryptionInfo[] = {
|
|||||||
|
|
||||||
.modeOffset = QCOW2_HDR_CRYPT,
|
.modeOffset = QCOW2_HDR_CRYPT,
|
||||||
.modeValue = 1,
|
.modeValue = 1,
|
||||||
|
|
||||||
|
.payloadOffset = -1,
|
||||||
},
|
},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
@ -921,6 +938,23 @@ virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virStorageFileGetEncryptionPayloadOffset(const struct FileEncryptionInfo *info,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
int payload_offset = -1;
|
||||||
|
|
||||||
|
if (info->payloadOffset != -1) {
|
||||||
|
if (info->endian == LV_LITTLE_ENDIAN)
|
||||||
|
payload_offset = virReadBufInt32LE(buf + info->payloadOffset);
|
||||||
|
else
|
||||||
|
payload_offset = virReadBufInt32BE(buf + info->payloadOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Given a header in BUF with length LEN, as parsed from the storage file
|
/* Given a header in BUF with length LEN, as parsed from the storage file
|
||||||
* assuming it has the given FORMAT, populate information into META
|
* assuming it has the given FORMAT, populate information into META
|
||||||
* with information about the file and its backing store. Return format
|
* with information about the file and its backing store. Return format
|
||||||
@ -967,6 +1001,8 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
meta->encryption->payload_offset =
|
||||||
|
virStorageFileGetEncryptionPayloadOffset(&fileTypeInfo[meta->format].cryptInfo[i], buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3423,6 +3459,9 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr src,
|
|||||||
else
|
else
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (src->encryption && src->encryption->payload_offset != -1)
|
||||||
|
src->capacity -= src->encryption->payload_offset * 512;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user