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++) {