summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2014-09-09 18:00:30 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2014-09-18 14:06:55 +0200
commite270edcbfd958d764e84cdbca6d403ff24fef610 (patch)
tree8d846a345b163a8e5abfa0d57c1656f7c3c4629d /server
parent2cc42d9358effcac325e63fd2b42766a771bf1bf (diff)
downloadspice-e270edcbfd958d764e84cdbca6d403ff24fef610.tar.gz
spice-e270edcbfd958d764e84cdbca6d403ff24fef610.tar.xz
spice-e270edcbfd958d764e84cdbca6d403ff24fef610.zip
Validate surface bounding box before using it
It's possible for a buggy guest driver to pass invalid bounding box dimensions in QXL commands, which would then cause spice-server to segfault. This patch checks the size of the bounding box of the QXL command right after it has been parsed. This fixes rhbz#1135372
Diffstat (limited to 'server')
-rw-r--r--server/red_worker.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/server/red_worker.c b/server/red_worker.c
index dcd8b774..e177b683 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1250,6 +1250,33 @@ static inline void __validate_surface(RedWorker *worker, uint32_t surface_id)
spice_warn_if(surface_id >= worker->n_surfaces);
}
+static int validate_drawable_bbox(RedWorker *worker, RedDrawable *drawable)
+{
+ DrawContext *context;
+ uint32_t surface_id = drawable->surface_id;
+
+ /* surface_id must be validated before calling into
+ * validate_drawable_bbox
+ */
+ __validate_surface(worker, surface_id);
+ context = &worker->surfaces[surface_id].context;
+
+ if (drawable->bbox.top < 0)
+ return FALSE;
+ if (drawable->bbox.left < 0)
+ return FALSE;
+ if (drawable->bbox.bottom < 0)
+ return FALSE;
+ if (drawable->bbox.right < 0)
+ return FALSE;
+ if (drawable->bbox.bottom > context->height)
+ return FALSE;
+ if (drawable->bbox.right > context->width)
+ return FALSE;
+
+ return TRUE;
+}
+
static inline int validate_surface(RedWorker *worker, uint32_t surface_id)
{
spice_warn_if(surface_id >= worker->n_surfaces);
@@ -4073,6 +4100,10 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *re
VALIDATE_SURFACE_RETVAL(worker, drawable->surfaces_dest[x], NULL)
}
}
+ if (!validate_drawable_bbox(worker, red_drawable)) {
+ rendering_incorrect(__func__);
+ return NULL;
+ }
ring_init(&drawable->pipes);
ring_init(&drawable->glz_ring);