62 lines
2.4 KiB
Diff
62 lines
2.4 KiB
Diff
|
|
From 56a588dad8d085a89b24fe2103bd623d4260e02d Mon Sep 17 00:00:00 2001
|
||
|
|
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
|
||
|
|
Date: Mon, 8 Jul 2024 10:09:49 +0300
|
||
|
|
Subject: [PATCH] virtio-snd: add max size bounds check in input
|
||
|
|
cb(CVE-2024-7730)
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
cherry-pick from 98e77e3dd8dd6e7aa9a7dffa60f49c8c8a49d4e3
|
||
|
|
|
||
|
|
When reading input audio in the virtio-snd input callback,
|
||
|
|
virtio_snd_pcm_in_cb(), we do not check whether the iov can actually fit
|
||
|
|
the data buffer. This is because we use the buffer->size field as a
|
||
|
|
total-so-far accumulator instead of byte-size-left like in TX buffers.
|
||
|
|
|
||
|
|
This triggers an out of bounds write if the size of the virtio queue
|
||
|
|
element is equal to virtio_snd_pcm_status, which makes the available
|
||
|
|
space for audio data zero. This commit adds a check for reaching the
|
||
|
|
maximum buffer size before attempting any writes.
|
||
|
|
|
||
|
|
Reported-by: Zheyu Ma <zheyuma97@gmail.com>
|
||
|
|
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2427
|
||
|
|
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
|
||
|
|
Message-Id: <virtio-snd-fuzz-2427-fix-v1-manos.pitsidianakis@linaro.org>
|
||
|
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||
|
|
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||
|
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||
|
|
---
|
||
|
|
hw/audio/virtio-snd.c | 7 ++++++-
|
||
|
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
|
||
|
|
index 137fa77a01..15986af41e 100644
|
||
|
|
--- a/hw/audio/virtio-snd.c
|
||
|
|
+++ b/hw/audio/virtio-snd.c
|
||
|
|
@@ -1274,7 +1274,7 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
|
||
|
|
{
|
||
|
|
VirtIOSoundPCMStream *stream = data;
|
||
|
|
VirtIOSoundPCMBuffer *buffer;
|
||
|
|
- size_t size;
|
||
|
|
+ size_t size, max_size;
|
||
|
|
|
||
|
|
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
|
||
|
|
while (!QSIMPLEQ_EMPTY(&stream->queue)) {
|
||
|
|
@@ -1288,7 +1288,12 @@ static void virtio_snd_pcm_in_cb(void *data, int available)
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ max_size = iov_size(buffer->elem->in_sg, buffer->elem->in_num);
|
||
|
|
for (;;) {
|
||
|
|
+ if (buffer->size >= max_size) {
|
||
|
|
+ return_rx_buffer(stream, buffer);
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
size = AUD_read(stream->voice.in,
|
||
|
|
buffer->data + buffer->size,
|
||
|
|
MIN(available, (stream->params.period_bytes -
|
||
|
|
--
|
||
|
|
2.41.0.windows.1
|
||
|
|
|