@samitouri / QOSamiQemu / commits / cecd7a11df

vhost-user-scmi: free vhost virtqueue array on cleanup

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> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260630072728.3025097-1-zhaoguohan@kylinos.cn>

GuoHan Zhao committed Jun 30, 2026 at 15:27 UTC cecd7a11df7b7fdfccc60fe50cc78e75635db886
1 file changed +8 -4
hw/virtio/vhost-user-scmi.c
+8 -4
@@ -220,11 +220,12 @@ static void vu_scmi_event(void *opaque, QEMUChrEvent event)
220 }
221 }
222
223 -static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi)
223 +static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserSCMI *scmi,
224 + struct vhost_virtqueue *vhost_vqs)
225 {
226 virtio_delete_queue(scmi->cmd_vq);
227 virtio_delete_queue(scmi->event_vq);
227 - g_free(scmi->vhost_dev.vqs);
228 + g_free(vhost_vqs);
229 virtio_cleanup(vdev);
230 vhost_user_cleanup(&scmi->vhost_user);
231 }
@@ -233,6 +234,7 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
234 {
235 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
236 VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
237 + struct vhost_virtqueue *vhost_vqs;
238 int ret;
239
240 if (!scmi->chardev.chr) {
@@ -252,13 +254,14 @@ static void vu_scmi_device_realize(DeviceState *dev, Error **errp)
254 scmi->event_vq = virtio_add_queue(vdev, 256, vu_scmi_handle_output);
255 scmi->vhost_dev.nvqs = 2;
256 scmi->vhost_dev.vqs = g_new0(struct vhost_virtqueue, scmi->vhost_dev.nvqs);
257 + vhost_vqs = scmi->vhost_dev.vqs;
258
259 ret = vhost_dev_init(&scmi->vhost_dev, &scmi->vhost_user,
260 VHOST_BACKEND_TYPE_USER, 0, errp);
261 if (ret < 0) {
262 error_setg_errno(errp, -ret,
263 "vhost-user-scmi: vhost_dev_init() failed");
261 - do_vhost_user_cleanup(vdev, scmi);
264 + do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
265 return;
266 }
267
@@ -270,10 +273,11 @@ static void vu_scmi_device_unrealize(DeviceState *dev)
273 {
274 VirtIODevice *vdev = VIRTIO_DEVICE(dev);
275 VHostUserSCMI *scmi = VHOST_USER_SCMI(dev);
276 + struct vhost_virtqueue *vhost_vqs = scmi->vhost_dev.vqs;
277
278 vu_scmi_set_status(vdev, 0);
279 vhost_dev_cleanup(&scmi->vhost_dev);
276 - do_vhost_user_cleanup(vdev, scmi);
280 + do_vhost_user_cleanup(vdev, scmi, vhost_vqs);
281 }
282
283 static const VMStateDescription vu_scmi_vmstate = {