Commit fa9c0c9f71 for qemu.org
commit fa9c0c9f716e39309ffdd95a5b7afc33cc0692d8
Author: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Date: Mon Apr 20 08:07:06 2026 +0300
virtio-snd: check for overflow before g_malloc0
Coverity points out one g_malloc0 overflow, but it seems to be a false
positive. Add a check to it regardless to fortify the code, and also add
checks for every other g_malloc0 use.
Resolves: Coverity CID 1547527
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260420-virtio-fixups-v3-2-07aef1eff9d2@linaro.org>
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 93fbcfb43f..694bcebb60 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -850,7 +850,7 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
- size_t msg_sz, size;
+ size_t msg_sz, size, tmp;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
@@ -880,6 +880,8 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
if (msg_sz != sizeof(virtio_snd_pcm_xfer)) {
goto tx_err;
}
+ assert(iov_size(elem->out_sg, elem->out_num) >= msg_sz);
+ size = iov_size(elem->out_sg, elem->out_num) - msg_sz;
stream_id = le32_to_cpu(hdr.stream_id);
if (stream_id >= vsnd->snd_conf.streams
@@ -892,9 +894,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
goto tx_err;
}
+ /* Check for g_malloc0 overflow. */
+ if (!g_size_checked_add(&tmp, sizeof(VirtIOSoundPCMBuffer), size)) {
+ goto tx_err;
+ }
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
- size = iov_size(elem->out_sg, elem->out_num) - msg_sz;
-
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer) + size);
buffer->elem = elem;
buffer->populated = false;
@@ -932,7 +936,7 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
- size_t msg_sz, size;
+ size_t msg_sz, size, tmp;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
@@ -977,6 +981,10 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
goto rx_err;
}
size -= sizeof(virtio_snd_pcm_status);
+ /* Check for g_malloc0 overflow. */
+ if (!g_size_checked_add(&tmp, sizeof(VirtIOSoundPCMBuffer), size)) {
+ goto rx_err;
+ }
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer) + size);
buffer->elem = elem;