'virStorageFileGetEncryptionPayloadOffset' expects payloadOffset + 4 to
be in buffer bounds which isn't checked anywhere.
For example malicious actor may provide LUKS header with just magic and
version like: '4c554b53 babe 0001'. This example successefully passes
'virStorageFileHasEncryptionFormat' and leads to OOB read of 4 bytes.
So the fix is to add bounds checks.
Fixes: b7d44f450c06803df7df3ad380f7a5c97425c1e6
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/906
Signed-off-by: Sergey Zhidkih <rx1513@altlinux.org>
---
src/storage_file/storage_file_probe.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/storage_file/storage_file_probe.c b/src/storage_file/storage_file_probe.c
index cc5854d360..3ac90d698c 100644
--- a/src/storage_file/storage_file_probe.c
+++ b/src/storage_file/storage_file_probe.c
@@ -938,11 +938,13 @@ virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info,
static int
virStorageFileGetEncryptionPayloadOffset(const struct FileEncryptionInfo *info,
- char *buf)
+ char *buf,
+ size_t len)
{
int payload_offset = -1;
- if (info->payloadOffset != -1) {
+ if (info->payloadOffset != -1 &&
+ len >= info->payloadOffset + sizeof(uint32_t)) {
if (info->endian == LV_LITTLE_ENDIAN)
payload_offset = virReadBufInt32LE(buf + info->payloadOffset);
else
@@ -999,7 +1001,7 @@ virStorageFileProbeGetMetadata(virStorageSource *meta,
}
}
meta->encryption->payload_offset =
- virStorageFileGetEncryptionPayloadOffset(&fileTypeInfo[meta->format].cryptInfo[i], buf);
+ virStorageFileGetEncryptionPayloadOffset(&fileTypeInfo[meta->format].cryptInfo[i], buf, len);
}
}
}
--
2.50.1