@samitouri / QOSamiQemu / commits / bb3e0daaf8

vhost-user-base: clean up vhost_dev on realize failure

Failures after vhost_dev_init() currently skip vhost_dev_cleanup(), leaking initialized vhost_dev state. Add a separate unwind label for those paths. Keep a copy of vhost_dev.vqs so the array can still be freed after vhost_dev_cleanup() clears struct vhost_dev. Fixes: 6608dca74ecf (vhost-user-device: Add shared memory BAR) Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260630012058.2663259-1-zhaoguohan@kylinos.cn>

GuoHan Zhao committed Jun 30, 2026 at 09:20 UTC bb3e0daaf8ea0bc98697c11a15bc30d7fa0b6173
1 file changed +8 -3
hw/virtio/vhost-user-base.c
+8 -3
@@ -287,6 +287,7 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
287 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
288 VHostUserBase *vub = VHOST_USER_BASE(dev);
289 uint64_t memory_sizes[VIRTIO_MAX_SHMEM_REGIONS];
290 + struct vhost_virtqueue *vhost_vqs = NULL;
291 int i, ret, nregions, regions_processed = 0;
292
293 if (!vub->chardev.chr) {
@@ -338,6 +339,7 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
339
340 vub->vhost_dev.nvqs = vub->num_vqs;
341 vub->vhost_dev.vqs = g_new0(struct vhost_virtqueue, vub->vhost_dev.nvqs);
342 + vhost_vqs = vub->vhost_dev.vqs;
343
344 /* connect to backend */
345 ret = vhost_dev_init(&vub->vhost_dev, &vub->vhost_user,
@@ -353,7 +355,7 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
355 errp);
356
357 if (ret < 0) {
356 - goto err;
358 + goto err_vhost_dev;
359 }
360
361 for (i = 0; i < VIRTIO_MAX_SHMEM_REGIONS && regions_processed < nregions; i++) {
@@ -368,14 +370,14 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
370 errp);
371
372 if (ret < 0) {
371 - goto err;
373 + goto err_vhost_dev;
374 }
375 }
376
377 if (memory_sizes[i] % qemu_real_host_page_size() != 0) {
378 error_setg(errp, "Shared memory %d size must be a multiple of "
379 "the host page size", i);
378 - goto err;
380 + goto err_vhost_dev;
381 }
382
383 virtio_new_shmem_region(vdev, i, memory_sizes[i]);
@@ -385,7 +387,10 @@ static void vub_device_realize(DeviceState *dev, Error **errp)
387 qemu_chr_fe_set_handlers(&vub->chardev, NULL, NULL, vub_event, NULL,
388 dev, NULL, true);
389 return;
390 +err_vhost_dev:
391 + vhost_dev_cleanup(&vub->vhost_dev);
392 err:
393 + g_free(vhost_vqs);
394 do_vhost_user_cleanup(vdev, vub);
395 }
396