|
|
e2c81d |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
73b8f2 |
From: Frediano Ziglio <fziglio@redhat.com>
|
|
|
73b8f2 |
Date: Wed, 9 Sep 2015 12:45:06 +0100
|
|
|
e2c81d |
Subject: [PATCH] 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.
|