summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2015-09-09 12:45:06 +0100
committerFrediano Ziglio <fziglio@redhat.com>2015-10-06 11:07:15 +0100
commit097c638b121e595d9daf79285c447088027a58e2 (patch)
tree91627425620400bd2363b873675bc60c23a50abb
parentdd558bb833254fb49069eca052b92ae1abe3e8ff (diff)
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>
-rw-r--r--server/red_worker.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/server/red_worker.c b/server/red_worker.c
index 7a60cd1..babb597 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.