diff options
author | Frediano Ziglio <fziglio@redhat.com> | 2015-09-09 12:45:06 +0100 |
---|---|---|
committer | Frediano Ziglio <fziglio@redhat.com> | 2015-10-06 11:07:15 +0100 |
commit | 097c638b121e595d9daf79285c447088027a58e2 (patch) | |
tree | 91627425620400bd2363b873675bc60c23a50abb /server/red_worker.c | |
parent | dd558bb833254fb49069eca052b92ae1abe3e8ff (diff) | |
download | spice-097c638b121e595d9daf79285c447088027a58e2.tar.gz spice-097c638b121e595d9daf79285c447088027a58e2.tar.xz spice-097c638b121e595d9daf79285c447088027a58e2.zip |
worker: avoid double free or double create of surfaces
A driver can overwrite surface state creating a surface with the same
id of a previous one.
Also can try to destroy surfaces that are not created.
Both requests cause invalid internal states that could lead to crashes
or memory corruptions.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Diffstat (limited to 'server/red_worker.c')
-rw-r--r-- | server/red_worker.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/server/red_worker.c b/server/red_worker.c index 7a60cd12..babb597f 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -4278,6 +4278,10 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface int32_t stride = surface->u.surface_create.stride; int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA); + if (red_surface->refs) { + spice_warning("avoiding creating a surface twice"); + break; + } data = surface->u.surface_create.data; if (stride < 0) { data -= (int32_t)(stride * (height - 1)); @@ -4291,7 +4295,10 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface break; } case QXL_SURFACE_CMD_DESTROY: - spice_warn_if(!red_surface->context.canvas); + if (!red_surface->refs) { + spice_warning("avoiding destroying a surface twice"); + break; + } set_surface_release_info(&red_surface->destroy, surface->release_info, group_id); red_handle_depends_on_target_surface(worker, surface_id); /* note that red_handle_depends_on_target_surface must be called before red_current_clear. |