Commit 259b58e68e for qemu.org
commit 259b58e68ed9ca42331931702cc0f696e1aedee7
Author: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Date: Tue Nov 10 12:19:01 2026 +0200
virtio-snd: cap maximum buffer_bytes to half a GiB
A faulty/malicious guest can try to exhaust host memory. Cap the buffer
size to 500 MiB.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3587
Reviewed-by: Jim MacArthur <jim.macarthur@linaro.org>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index a7d749f24f..a6036d5b75 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -17,6 +17,7 @@
#include "qemu/osdep.h"
#include "qemu/iov.h"
+#include "qemu/units.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "system/runstate.h"
@@ -24,6 +25,8 @@
#include "qapi/error.h"
#include "hw/audio/virtio-snd.h"
+#define MAX_BUFFER_MIB 500
+
#define VIRTIO_SOUND_JACK_DEFAULT 0
#define VIRTIO_SOUND_STREAM_DEFAULT 2
#define VIRTIO_SOUND_CHMAP_DEFAULT 0
@@ -368,6 +371,14 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
& ~(stream->info.features));
return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
}
+ if (le32_to_cpu(params->buffer_bytes) > MAX_BUFFER_MIB * MiB) {
+ error_report("%s: given buffer_bytes value %"PRIu32" "
+ "is too big: over %d MiB",
+ VIRTIO_DEVICE(s)->name,
+ le32_to_cpu(params->buffer_bytes),
+ MAX_BUFFER_MIB);
+ return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
+ }
st_params = virtio_snd_pcm_get_params(s, stream_id);
@@ -1037,6 +1048,8 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
stream = &vsnd->streams[stream_id];
+ size = MIN(stream->params.buffer_bytes, size);
+
if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
goto tx_err;
}