[PATCH] vhost-user-scmi: free vhost virtqueue array on cleanup

zhaoguohan@kylinos.cn posted 1 patch 3 weeks, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260630072728.3025097-1-zhaoguohan@kylinos.cn
Maintainers: Milan Zamazal <mzamazal@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>
hw/virtio/vhost-user-scmi.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
[PATCH] vhost-user-scmi: free vhost virtqueue array on cleanup
Posted by zhaoguohan@kylinos.cn 3 weeks, 5 days ago
From: GuoHan Zhao <zhaoguohan@kylinos.cn>

vhost-user-scmi allocates vhost_dev.vqs during realize, but the
cleanup helper frees scmi->vhost_dev.vqs after vhost_dev_cleanup() has
cleared struct vhost_dev. This turns the free into g_free(NULL), leaking
the allocated vhost virtqueue array.

Keep a copy of the vhost_dev.vqs pointer across vhost_dev_cleanup() and
free that saved pointer from the common cleanup helper.

Fixes: a5dab090e142 (hw/virtio: Add boilerplate for vhost-user-scmi device)
Signed-off-by: GuoHan Zhao <zhaoguohan@kylinos.cn>
---
 hw/virtio/vhost-user-scmi.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c
index 9470f68c1f3c..02dc088ea982 100644
--- a/hw/virtio/vhost-user-scmi.c
+++ b/hw/virtio/vhost-user-scmi.c
@@ -220,11 +220,12 @@ static void vu_scmi_event(void *opaque, QEMUChrEvent event)
     }
 }
 
-static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi)
+static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi,
+                                  struct vhost_virtqueue *vhost_vqs)
 {
     virtio_delete_queue(scmi->cmd_vq);
     virtio_delete_queue(scmi->event_vq);
-    g_free(scmi->vhost_dev.vqs);
+    g_free(vhost_vqs);
     virtio_cleanup(vdev);
     vhost_user_cleanup(&scmi->vhost_user);
 }
@@ -233,6 +234,7 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
+    struct vhost_virtqueue *vhost_vqs;
     int ret;
 
     if (!scmi->chardev.chr) {
@@ -252,13 +254,14 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
     scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output);
     scmi->vhost_dev.nvqs = 2;
     scmi->vhost_dev.vqs = g_new0(struct vhost_virtqueue, scmi->vhost_dev.nvqs);
+    vhost_vqs = scmi->vhost_dev.vqs;
 
     ret = vhost_dev_init(&scmi->vhost_dev, &scmi->vhost_user,
                          VHOST_BACKEND_TYPE_USER, 0, errp);
     if (ret < 0) {
         error_setg_errno(errp, -ret,
                          "vhost-user-scmi: vhost_dev_init() failed");
-        do_vhost_user_cleanup(vdev, scmi);
+        do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
         return;
     }
 
@@ -270,10 +273,11 @@ static void vu_scmi_device_unrealize(DeviceState *dev)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
+    struct vhost_virtqueue *vhost_vqs = scmi->vhost_dev.vqs;
 
     vu_scmi_set_status(vdev, 0);
     vhost_dev_cleanup(&scmi->vhost_dev);
-    do_vhost_user_cleanup(vdev, scmi);
+    do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
 }
 
 static const VMStateDescription vu_scmi_vmstate = {
-- 
2.43.0