Blame SOURCES/0040-worker-avoid-double-free-or-double-create-of-surface.patch

73b8f2
From 269e9d112639ab6c54645de217c46ef75617d780 Mon Sep 17 00:00:00 2001
73b8f2
From: Frediano Ziglio <fziglio@redhat.com>
73b8f2
Date: Wed, 9 Sep 2015 12:45:06 +0100
73b8f2
Subject: [PATCH 2/2] worker: avoid double free or double create of surfaces
73b8f2
73b8f2
A driver can overwrite surface state creating a surface with the same
73b8f2
id of a previous one.
73b8f2
Also can try to destroy surfaces that are not created.
73b8f2
Both requests cause invalid internal states that could lead to crashes
73b8f2
or memory corruptions.
73b8f2
73b8f2
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
73b8f2
---
73b8f2
 server/red_worker.c | 9 ++++++++-
73b8f2
 1 file changed, 8 insertions(+), 1 deletion(-)
73b8f2
73b8f2
diff --git a/server/red_worker.c b/server/red_worker.c
73b8f2
index c62dbcb..a7eaab9 100644
73b8f2
--- a/server/red_worker.c
73b8f2
+++ b/server/red_worker.c
73b8f2
@@ -4320,6 +4320,10 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
73b8f2
         int32_t stride = surface->u.surface_create.stride;
73b8f2
         int reloaded_surface = loadvm || (surface->flags & QXL_SURF_FLAG_KEEP_DATA);
73b8f2
 
73b8f2
+        if (red_surface->refs) {
73b8f2
+            spice_warning("avoiding creating a surface twice");
73b8f2
+            break;
73b8f2
+        }
73b8f2
         data = surface->u.surface_create.data;
73b8f2
         if (stride < 0) {
73b8f2
             data -= (int32_t)(stride * (height - 1));
73b8f2
@@ -4333,7 +4337,10 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
73b8f2
         break;
73b8f2
     }
73b8f2
     case QXL_SURFACE_CMD_DESTROY:
73b8f2
-        spice_warn_if(!red_surface->context.canvas);
73b8f2
+        if (!red_surface->refs) {
73b8f2
+            spice_warning("avoiding destroying a surface twice");
73b8f2
+            break;
73b8f2
+        }
73b8f2
         set_surface_release_info(worker, surface_id, 0, surface->release_info, group_id);
73b8f2
         red_handle_depends_on_target_surface(worker, surface_id);
73b8f2
         /* note that red_handle_depends_on_target_surface must be called before red_current_clear.
73b8f2
-- 
73b8f2
2.4.3
73b8f2