Migration streams are untrusted input. A crafted stream can set
blk_len larger than the 512 byte data[] buffer, so a later block
read passes that length to blk_pread() and overflows data[] on
the host heap.

Reject such state in post_load.

Cc: [email protected]
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4725
Reported-by: Karl Mehltretter
Signed-off-by: Harshit Mukhedkar <[email protected]>
---
 hw/sd/sd.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b1b3b1226a..6e7d04e25c 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1073,11 +1073,24 @@ static int sd_vmstate_pre_load(void *opaque)
     return 0;
 }
 
+static int sd_vmstate_post_load(void *opaque, int version_id)
+{
+    SDState *sd = opaque;
+
+    /* Check for blk_len that overflows data[] */
+    if (sd->blk_len > sizeof(sd->data)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
 static const VMStateDescription sd_vmstate = {
     .name = "sd-card",
     .version_id = 2,
     .minimum_version_id = 2,
     .pre_load = sd_vmstate_pre_load,
+    .post_load = sd_vmstate_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_UNUSED(4),
         VMSTATE_INT32(state, SDState),
-- 
2.56.0


Reply via email to