diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2014-09-09 18:00:30 +0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-09-18 14:06:55 +0200 |
commit | e270edcbfd958d764e84cdbca6d403ff24fef610 (patch) | |
tree | 8d846a345b163a8e5abfa0d57c1656f7c3c4629d /server | |
parent | 2cc42d9358effcac325e63fd2b42766a771bf1bf (diff) | |
download | spice-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.c | 31 |
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); |