@samitouri / QOSamiQemu / commits / e99488c5d4

hw/display/virtio-gpu: handle migration iov allocation failure

An unbounded iov_cnt from the migration stream drives two g_new() allocations whose combined size can exceed available memory, causing GLib to abort the process. Switch to g_try_new() and propagate the failure as a migration error. Fixes: 0c244e50ee12 ("virtio-gpu: add live migration support") Fixes: f66767f75c9c ("virtio-gpu: add virtio-gpu/blob vmstate subsection") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3753 Reported-by: Feifan Qian <bea1e@proton.me> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

Marc-André Lureau committed Jul 7, 2026 at 16:53 UTC e99488c5d4a009a156a29f9ff6a7f12d091c2646
1 file changed +18 -4
hw/display/virtio-gpu.c
+18 -4
@@ -1365,8 +1365,15 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
1365 return -EINVAL;
1366 }
1367
1368 - res->addrs = g_new(uint64_t, res->iov_cnt);
1369 - res->iov = g_new(struct iovec, res->iov_cnt);
1368 + res->addrs = g_try_new(uint64_t, res->iov_cnt);
1369 + res->iov = g_try_new(struct iovec, res->iov_cnt);
1370 + if (res->iov_cnt && (!res->addrs || !res->iov)) {
1371 + pixman_image_unref(res->image);
1372 + g_free(res->addrs);
1373 + g_free(res->iov);
1374 + g_free(res);
1375 + return -EINVAL;
1376 + }
1377
1378 /* read data */
1379 for (i = 0; i < res->iov_cnt; i++) {
@@ -1440,8 +1447,15 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
1447 res->resource_id = resource_id;
1448 res->blob_size = qemu_get_be32(f);
1449 res->iov_cnt = qemu_get_be32(f);
1443 - res->addrs = g_new(uint64_t, res->iov_cnt);
1444 - res->iov = g_new(struct iovec, res->iov_cnt);
1450 +
1451 + res->addrs = g_try_new(uint64_t, res->iov_cnt);
1452 + res->iov = g_try_new(struct iovec, res->iov_cnt);
1453 + if (res->iov_cnt && (!res->addrs || !res->iov)) {
1454 + g_free(res->addrs);
1455 + g_free(res->iov);
1456 + g_free(res);
1457 + return -EINVAL;
1458 + }
1459
1460 /* read data */
1461 for (i = 0; i < res->iov_cnt; i++) {