From: Marc-André Lureau <marcandre.lureau@redhat.com>
virgl_cmd_submit_3d() passes the guest-controlled cs.size directly to
g_malloc() without any bounds check. A malicious guest can set this
field to an arbitrarily large value (up to 4GB), causing an OOM abort
that crashes the vhost-user-gpu daemon.
Validate cs.size against the actual descriptor payload size before
allocating, rejecting values that exceed what the virtqueue entry
can carry.
Fixes: d52c454aadc ("contrib: add vhost-user-gpu")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3776
Reported-by: admin@fluentlogic.org
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
contrib/vhost-user-gpu/virgl.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index 51da0e3667f..7b7b660653f 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -197,11 +197,21 @@ virgl_cmd_submit_3d(VuGpu *g,
struct virtio_gpu_ctrl_command *cmd)
{
struct virtio_gpu_cmd_submit cs;
+ size_t iov_len;
void *buf;
size_t s;
VUGPU_FILL_CMD(cs);
+ iov_len = iov_size(cmd->elem.out_sg, cmd->elem.out_num);
+ if (cs.size == 0 || iov_len < sizeof(cs) ||
+ cs.size > iov_len - sizeof(cs)) {
+ g_critical("%s: size out of range (%u/%zu)",
+ __func__, cs.size, iov_len);
+ cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+ return;
+ }
+
buf = g_malloc(cs.size);
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
sizeof(cs), buf, cs.size);
--
2.55.0