[PATCH] storage: check bounds before accessing encryption payload offset

Sergey Zhidkih posted 1 patch 1 week, 3 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/20260814110725.237134-1-rx1513@altlinux.org
src/storage_file/storage_file_probe.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
[PATCH] storage: check bounds before accessing encryption payload offset
Posted by Sergey Zhidkih 1 week, 3 days ago
'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
Re: [PATCH] storage: check bounds before accessing encryption payload offset
Posted by Peter Krempa via Devel 4 days, 12 hours ago
On Fri, Aug 14, 2026 at 14:07:25 +0300, Sergey Zhidkih wrote:
> '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(-)

Reviewed-by: Peter Krempa <pkrempa@redhat.com>

and pushed