From dc2deaba4852e3324a4558a8bd29c58ce3299699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 31 May 2021 12:19:28 +0200 Subject: hw/display/virtio-gpu: Fix memory leak (CID 1453811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid leaking memory on the error path, reorder the code as: - check the parameters first - check resource already existing - finally allocate memory Reported-by: Coverity (CID 1453811: RESOURCE_LEAK) Fixes: e0933d91b1c ("virtio-gpu: Add virtio_gpu_resource_create_blob") Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210531101928.1662732-1-philmd@redhat.com> Signed-off-by: Gerd Hoffmann --- hw/display/virtio-gpu.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'hw/display/virtio-gpu.c') diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 6b7f643..990e71f 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -340,37 +340,31 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g, return; } - res = virtio_gpu_find_resource(g, cblob.resource_id); - if (res) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n", - __func__, cblob.resource_id); - cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; - return; - } - - res = g_new0(struct virtio_gpu_simple_resource, 1); - res->resource_id = cblob.resource_id; - res->blob_size = cblob.size; - if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_GUEST && cblob.blob_flags != VIRTIO_GPU_BLOB_FLAG_USE_SHAREABLE) { qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid memory type\n", __func__); cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; - g_free(res); return; } - if (res->iov) { - cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; + if (virtio_gpu_find_resource(g, cblob.resource_id)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n", + __func__, cblob.resource_id); + cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; return; } + res = g_new0(struct virtio_gpu_simple_resource, 1); + res->resource_id = cblob.resource_id; + res->blob_size = cblob.size; + ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob), cmd, &res->addrs, &res->iov, &res->iov_cnt); - if (ret != 0) { + if (ret != 0 || res->iov) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; + g_free(res); return; } -- cgit v1.1