diff --git a/.gitignore b/.gitignore
index a0cd66b..657c9f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/spice-0.12.4.tar.bz2
+SOURCES/spice-0.12.8.tar.bz2
diff --git a/.spice.metadata b/.spice.metadata
index d2692cd..fc820d6 100644
--- a/.spice.metadata
+++ b/.spice.metadata
@@ -1 +1 @@
-5825cfcf8a786697e45a43aaf372f23b5c441336 SOURCES/spice-0.12.4.tar.bz2
+5f19057c5c17c1b6d601c386e6404b44ec77461f SOURCES/spice-0.12.8.tar.bz2
diff --git a/SOURCES/0001-Call-migrate_end_complete-after-falling-back-to-swit.patch b/SOURCES/0001-Call-migrate_end_complete-after-falling-back-to-swit.patch
new file mode 100644
index 0000000..f9470ab
--- /dev/null
+++ b/SOURCES/0001-Call-migrate_end_complete-after-falling-back-to-swit.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Wed, 20 Jul 2016 17:16:31 +0400
+Subject: [PATCH] Call migrate_end_complete() after falling back to switch-host
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Eventually, during a seamless migration, qemu may finish to migrate
+before the spice client even finished to connect all channels to
+destination and informed the server. In this case,
+main_channel_client_migrate_src_complete() will fall back to
+switch-host method, and reds_mig_fill_wait_disconnect() is called to
+complete the migration (disconnecting all channels).
+
+reds_mig_cleanup() is called when all channels are disconnected, but
+reds->mig_wait_connect is still TRUE, and it will call
+migrate_connect_complete() instead of the expected
+migrate_end_complete(). Setting reds->mig_wait_connect to FALSE when
+reds_mig_fill_wait_disconnect() solves the issue.
+
+Fixes:
+https://bugzilla.redhat.com/show_bug.cgi?id=1352836
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+---
+ server/reds.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/server/reds.c b/server/reds.c
+index 61bf735..f40b65c 100644
+--- a/server/reds.c
++++ b/server/reds.c
+@@ -2816,6 +2816,7 @@ static void reds_mig_fill_wait_disconnect(void)
+         wait_client->client = client;
+         ring_add(&reds->mig_wait_disconnect_clients, &wait_client->link);
+     }
++    reds->mig_wait_connect = FALSE;
+     reds->mig_wait_disconnect = TRUE;
+     core->timer_start(reds->mig_timer, MIGRATE_TIMEOUT);
+ }
diff --git a/SOURCES/0001-red_channel-prevent-adding-and-pushing-pipe-items-af.patch b/SOURCES/0001-red_channel-prevent-adding-and-pushing-pipe-items-af.patch
deleted file mode 100644
index a324677..0000000
--- a/SOURCES/0001-red_channel-prevent-adding-and-pushing-pipe-items-af.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 24 Jul 2013 14:54:23 -0400
-Subject: [PATCH] red_channel: prevent adding and pushing pipe items after a
- channel_client has diconnected
-
-Fixes: leaks of pipe items & "red_client_destroy: assertion `rcc->send_data.size == 0'"
-
-red_channel_disconnect clears the pipe. It is called only once. After,
-it was called, not items should be added to the pipe.
-
-An example of when this assert can occur:
-on_new_cursor_channel (red_worker.c), pushes 2 pipe items.
-When it pushes the first pipe item, if the client has disconnected,
-it can hit a socket error, and then, red_channel_client_disconnect is called.
-The second call to adding a pipe item, will add the item to
-the pipe. red_channel_client_pipe_add_type also calls
-red_channel_client_push, which will update the send_data.size.
-Then, the push will also hit a socket error, but red_channel_client_disconnect
-won't clear the pending pipe item again, since it was already called.
-When red_client_destory is called, we hit assertion `rcc->send_data.size
-== 0'.
-Note that if a pipe item is added to the pipe after
-red_channel_client_disconnect was called, but without pushing it,
-we should hit "spice_assert(rcc->pipe_size == 0)".
----
- server/red_channel.c | 30 ++++++++++++++++++++++++------
- 1 file changed, 24 insertions(+), 6 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 85d7ebc..fa4db7b 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -1515,9 +1515,23 @@ void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type)
-     item->type = type;
- }
- 
--void red_channel_client_pipe_add(RedChannelClient *rcc, PipeItem *item)
-+static inline int validate_pipe_add(RedChannelClient *rcc, PipeItem *item)
- {
-     spice_assert(rcc && item);
-+    if (SPICE_UNLIKELY(!red_channel_client_is_connected(rcc))) {
-+        spice_debug("rcc is disconnected %p", rcc);
-+        red_channel_client_release_item(rcc, item, FALSE);
-+        return FALSE;
-+    }
-+    return TRUE;
-+}
-+
-+void red_channel_client_pipe_add(RedChannelClient *rcc, PipeItem *item)
-+{
-+
-+    if (!validate_pipe_add(rcc, item)) {
-+        return;
-+    }
-     rcc->pipe_size++;
-     ring_add(&rcc->pipe, &item->link);
- }
-@@ -1531,10 +1545,10 @@ void red_channel_client_pipe_add_push(RedChannelClient *rcc, PipeItem *item)
- void red_channel_client_pipe_add_after(RedChannelClient *rcc,
-                                        PipeItem *item, PipeItem *pos)
- {
--    spice_assert(rcc);
-     spice_assert(pos);
--    spice_assert(item);
--
-+    if (!validate_pipe_add(rcc, item)) {
-+        return;
-+    }
-     rcc->pipe_size++;
-     ring_add_after(&item->link, &pos->link);
- }
-@@ -1548,14 +1562,18 @@ int red_channel_client_pipe_item_is_linked(RedChannelClient *rcc,
- void red_channel_client_pipe_add_tail_no_push(RedChannelClient *rcc,
-                                               PipeItem *item)
- {
--    spice_assert(rcc);
-+    if (!validate_pipe_add(rcc, item)) {
-+        return;
-+    }
-     rcc->pipe_size++;
-     ring_add_before(&item->link, &rcc->pipe);
- }
- 
- void red_channel_client_pipe_add_tail(RedChannelClient *rcc, PipeItem *item)
- {
--    spice_assert(rcc);
-+    if (!validate_pipe_add(rcc, item)) {
-+        return;
-+    }
-     rcc->pipe_size++;
-     ring_add_before(&item->link, &rcc->pipe);
-     red_channel_client_push(rcc);
diff --git a/SOURCES/0002-Prevent-possible-DoS-attempts-during-protocol-handsh.patch b/SOURCES/0002-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
new file mode 100644
index 0000000..70339b3
--- /dev/null
+++ b/SOURCES/0002-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
@@ -0,0 +1,54 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Mon, 28 Nov 2016 13:15:58 +0000
+Subject: [PATCH] Prevent possible DoS attempts during protocol handshake
+
+The limit for link message is specified using a 32 bit unsigned integer.
+This could cause possible DoS due to excessive memory allocations and
+some possible crashes.
+For instance a value >= 2^31 causes a spice_assert to be triggered in
+async_read_handler (reds-stream.c) due to an integer overflow at this
+line:
+
+   int n = async->end - async->now;
+
+This could be easily triggered with a program like
+
+  #!/usr/bin/env python
+
+  import socket
+  import time
+  from struct import pack
+
+  server = '127.0.0.1'
+  port = 5900
+
+  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+  s.connect((server, port))
+  data = pack('<4sIII', 'REDQ', 2, 2, 0xaaaaaaaa)
+  s.send(data)
+
+  time.sleep(1)
+
+without requiring any authentication (the same can be done
+with TLS).
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ server/reds.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/server/reds.c b/server/reds.c
+index f40b65c..86a33d5 100644
+--- a/server/reds.c
++++ b/server/reds.c
+@@ -2202,7 +2202,8 @@ static void reds_handle_read_header_done(void *opaque)
+ 
+     reds->peer_minor_version = header->minor_version;
+ 
+-    if (header->size < sizeof(SpiceLinkMess)) {
++    /* the check for 4096 is to avoid clients to cause arbitrary big memory allocations */
++    if (header->size < sizeof(SpiceLinkMess) || header->size > 4096) {
+         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
+         spice_warning("bad size %u", header->size);
+         reds_link_free(link);
diff --git a/SOURCES/0002-red_channel-add-ref-count-to-RedClient.patch b/SOURCES/0002-red_channel-add-ref-count-to-RedClient.patch
deleted file mode 100644
index 9cf3d1f..0000000
--- a/SOURCES/0002-red_channel-add-ref-count-to-RedClient.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Fri, 26 Jul 2013 13:45:16 -0400
-Subject: [PATCH] red_channel: add ref count to RedClient
-
----
- server/red_channel.c | 23 ++++++++++++++++++++---
- server/red_channel.h | 17 +++++++++++++++--
- 2 files changed, 35 insertions(+), 5 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index fa4db7b..9433bef 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -1920,10 +1920,29 @@ RedClient *red_client_new(int migrated)
-     pthread_mutex_init(&client->lock, NULL);
-     client->thread_id = pthread_self();
-     client->during_target_migrate = migrated;
-+    client->refs = 1;
- 
-     return client;
- }
- 
-+RedClient *red_client_ref(RedClient *client)
-+{
-+    spice_assert(client);
-+    client->refs++;
-+    return client;
-+}
-+
-+RedClient *red_client_unref(RedClient *client)
-+{
-+    if (!--client->refs) {
-+        spice_debug("release client=%p", client);
-+        pthread_mutex_destroy(&client->lock);
-+        free(client);
-+        return NULL;
-+    }
-+    return client;
-+}
-+
- /* client mutex should be locked before this call */
- static void red_channel_client_set_migration_seamless(RedChannelClient *rcc)
- {
-@@ -2000,9 +2019,7 @@ void red_client_destroy(RedClient *client)
-         spice_assert(rcc->send_data.size == 0);
-         red_channel_client_destroy(rcc);
-     }
--
--    pthread_mutex_destroy(&client->lock);
--    free(client);
-+    red_client_unref(client);
- }
- 
- /* client->lock should be locked */
-diff --git a/server/red_channel.h b/server/red_channel.h
-index ba299b6..0dd73ea 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -561,10 +561,25 @@ struct RedClient {
-                                   is called */
-     int seamless_migrate;
-     int num_migrated_channels; /* for seamless - number of channels that wait for migrate data*/
-+    int refs;
- };
- 
- RedClient *red_client_new(int migrated);
- 
-+/*
-+ * disconnects all the client's channels (should be called from the client's thread)
-+ */
-+void red_client_destroy(RedClient *client);
-+
-+RedClient *red_client_ref(RedClient *client);
-+
-+/*
-+ * releases the client resources when refs == 0.
-+ * We assume the red_client_derstroy was called before
-+ * we reached refs==0
-+ */
-+RedClient *red_client_unref(RedClient *client);
-+
- MainChannelClient *red_client_get_main(RedClient *client);
- // main should be set once before all the other channels are created
- void red_client_set_main(RedClient *client, MainChannelClient *mcc);
-@@ -580,7 +595,5 @@ void red_client_semi_seamless_migrate_complete(RedClient *client); /* dst side *
- int red_client_during_migrate_at_target(RedClient *client);
- 
- void red_client_migrate(RedClient *client);
--// disconnects all the client's channels (should be called from the client's thread)
--void red_client_destroy(RedClient *client);
- 
- #endif
diff --git a/SOURCES/0003-Prevent-integer-overflows-in-capability-checks.patch b/SOURCES/0003-Prevent-integer-overflows-in-capability-checks.patch
new file mode 100644
index 0000000..5571a12
--- /dev/null
+++ b/SOURCES/0003-Prevent-integer-overflows-in-capability-checks.patch
@@ -0,0 +1,37 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Mon, 28 Nov 2016 13:15:58 +0000
+Subject: [PATCH] Prevent integer overflows in capability checks
+
+The limits for capabilities are specified using 32 bit unsigned integers.
+This could cause possible integer overflows causing buffer overflows.
+For instance the sum of num_common_caps and num_caps can be 0 avoiding
+additional checks.
+As the link message is now capped to 4096 and the capabilities are
+contained in the link message, this commit limits the capabilities
+to 1024 (capabilities are expressed in number of uint32_t items).
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ server/reds.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/server/reds.c b/server/reds.c
+index 86a33d5..c639aa3 100644
+--- a/server/reds.c
++++ b/server/reds.c
+@@ -2113,6 +2113,14 @@ static void reds_handle_read_link_done(void *opaque)
+     num_caps = link_mess->num_common_caps + link_mess->num_channel_caps;
+     caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset);
+ 
++    /* Prevent integer overflows. Currently we defined only 13 capabilities,
++     * I expect 1024 to be valid for quite a lot time */
++    if (link_mess->num_channel_caps > 1024 || link_mess->num_common_caps > 1024) {
++        reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
++        reds_link_free(link);
++        return;
++    }
++
+     if (num_caps && (num_caps * sizeof(uint32_t) + link_mess->caps_offset >
+                      link->link_header.size ||
+                      link_mess->caps_offset < sizeof(*link_mess))) {
diff --git a/SOURCES/0003-main_dispatcher-add-ref-count-protection-to-RedClien.patch b/SOURCES/0003-main_dispatcher-add-ref-count-protection-to-RedClien.patch
deleted file mode 100644
index 67b05c2..0000000
--- a/SOURCES/0003-main_dispatcher-add-ref-count-protection-to-RedClien.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Fri, 26 Jul 2013 13:49:24 -0400
-Subject: [PATCH] main_dispatcher: add ref count protection to RedClient
- instances
-
----
- server/main_dispatcher.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/server/main_dispatcher.c b/server/main_dispatcher.c
-index e7a451a..bf160dd 100644
---- a/server/main_dispatcher.c
-+++ b/server/main_dispatcher.c
-@@ -97,6 +97,7 @@ static void main_dispatcher_handle_migrate_complete(void *opaque,
-     MainDispatcherMigrateSeamlessDstCompleteMessage *mig_complete = payload;
- 
-     reds_on_client_seamless_migrate_complete(mig_complete->client);
-+    red_client_unref(mig_complete->client);
- }
- 
- static void main_dispatcher_handle_mm_time_latency(void *opaque,
-@@ -104,6 +105,7 @@ static void main_dispatcher_handle_mm_time_latency(void *opaque,
- {
-     MainDispatcherMmTimeLatencyMessage *msg = payload;
-     reds_set_client_mm_time_latency(msg->client, msg->latency);
-+    red_client_unref(msg->client);
- }
- 
- void main_dispatcher_seamless_migrate_dst_complete(RedClient *client)
-@@ -115,7 +117,7 @@ void main_dispatcher_seamless_migrate_dst_complete(RedClient *client)
-         return;
-     }
- 
--    msg.client = client;
-+    msg.client = red_client_ref(client);
-     dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
-                             &msg);
- }
-@@ -129,7 +131,7 @@ void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency)
-         return;
-     }
- 
--    msg.client = client;
-+    msg.client = red_client_ref(client);
-     msg.latency = latency;
-     dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
-                             &msg);
diff --git a/SOURCES/0004-decouple-disconnection-of-the-main-channel-from-clie.patch b/SOURCES/0004-decouple-disconnection-of-the-main-channel-from-clie.patch
deleted file mode 100644
index eb015b9..0000000
--- a/SOURCES/0004-decouple-disconnection-of-the-main-channel-from-clie.patch
+++ /dev/null
@@ -1,235 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Thu, 25 Jul 2013 14:19:21 -0400
-Subject: [PATCH] decouple disconnection of the main channel from client
- destruction
-
-Fixes rhbz#918169
-
-Some channels make direct calls to reds/main_channel routines. If
-these routines try to read/write to the socket, and they get socket
-error, main_channel_client_on_disconnect is called, and triggers
-red_client_destroy. In order to prevent accessing expired references
-to RedClient, RedChannelClient, or other objects (inside the original call, after
-red_client_destroy has been called) I made the call to
-red_client_destroy asynchronous with respect to main_channel_client_on_disconnect.
-I added MAIN_DISPATCHER_CLIENT_DISCONNECT to main_dispatcher.
-main_channel_client_on_disconnect pushes this msg to the dispatcher,
-instead of calling directly to reds_client_disconnect.
-
-The patch uses RedClient ref-count in order to handle a case where
-reds_client_disconnect is called directly (e.g., when a new client connects while
-another one is connected), while there is already CLIENT_DISCONNECT msg
-pending in the main_dispatcher.
-
-Examples:
-(1) snd_worker.c
-
-    snd_disconnect_channel()
-        channel->cleanup() //snd_playback_cleanup
-            reds_enable_mm_timer()
-                .
-                .
-                main_channel_push_multi_media_time()...socket_error
-                    .
-                    .
-                    red_client_destory()
-                        .
-                        .
-                        snd_disconnect_channel()
-                            channel->cleanup()
-                                celt051_encoder_destroy()
-            celt051_encoder_destory() // double release
-
-Note that this bug could have been solved by changing the order of
-calls: e.g., channel->stream = NULL before calling cleanup, and
-some other changes + reference counting. However, I found other
-places in the code with similar problems, and I looked for a general
-solution, at least till we redesign red_channel to handle reference
-counting more consistently.
-
-(2) inputs_channel.c
-
-    inputs_connect()
-        main_channel_client_push_notify()...socket_error
-                .
-                .
-            red_client_destory()
-                .
-                .
-        red_channel_client_create() // refers to client which is already destroyed
-
-(3) reds.c
-
-    reds_handle_main_link()
-       main_channel_push_init() ...socket error
-                .
-                .
-            red_client_destory()
-                .
-                .
-       main_channel_client_start_net_test(mcc) // refers to mcc which is already destroyed
-
-    This can explain the assert in rhbz#964136, comment #1 (but not the hang that occurred before).
----
- server/main_channel.c    |  9 +++++----
- server/main_dispatcher.c | 37 +++++++++++++++++++++++++++++++++++++
- server/main_dispatcher.h |  7 +++++++
- server/reds.c            |  1 +
- server/reds.h            |  2 ++
- 5 files changed, 52 insertions(+), 4 deletions(-)
-
-diff --git a/server/main_channel.c b/server/main_channel.c
-index 233e633..fe032a6 100644
---- a/server/main_channel.c
-+++ b/server/main_channel.c
-@@ -46,6 +46,7 @@
- #include "red_common.h"
- #include "reds.h"
- #include "migration_protocol.h"
-+#include "main_dispatcher.h"
- 
- #define ZERO_BUF_SIZE 4096
- 
-@@ -175,13 +176,13 @@ int main_channel_is_connected(MainChannel *main_chan)
-     return red_channel_is_connected(&main_chan->base);
- }
- 
--// when disconnection occurs, let reds shutdown all channels. This will trigger the
--// real disconnection of main channel
-+/*
-+ * When the main channel is disconnected, disconnect the entire client.
-+ */
- static void main_channel_client_on_disconnect(RedChannelClient *rcc)
- {
-     spice_printerr("rcc=%p", rcc);
--    reds_client_disconnect(rcc->client);
--//    red_channel_client_disconnect(rcc);
-+    main_dispatcher_client_disconnect(rcc->client);
- }
- 
- RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t connection_id)
-diff --git a/server/main_dispatcher.c b/server/main_dispatcher.c
-index bf160dd..dbe1037 100644
---- a/server/main_dispatcher.c
-+++ b/server/main_dispatcher.c
-@@ -41,6 +41,7 @@ enum {
-     MAIN_DISPATCHER_CHANNEL_EVENT = 0,
-     MAIN_DISPATCHER_MIGRATE_SEAMLESS_DST_COMPLETE,
-     MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
-+    MAIN_DISPATCHER_CLIENT_DISCONNECT,
- 
-     MAIN_DISPATCHER_NUM_MESSAGES
- };
-@@ -59,6 +60,10 @@ typedef struct MainDispatcherMmTimeLatencyMessage {
-     uint32_t latency;
- } MainDispatcherMmTimeLatencyMessage;
- 
-+typedef struct MainDispatcherClientDisconnectMessage {
-+    RedClient *client;
-+} MainDispatcherClientDisconnectMessage;
-+
- /* channel_event - calls core->channel_event, must be done in main thread */
- static void main_dispatcher_self_handle_channel_event(
-                                                 int event,
-@@ -108,6 +113,16 @@ static void main_dispatcher_handle_mm_time_latency(void *opaque,
-     red_client_unref(msg->client);
- }
- 
-+static void main_dispatcher_handle_client_disconnect(void *opaque,
-+                                                     void *payload)
-+{
-+    MainDispatcherClientDisconnectMessage *msg = payload;
-+
-+    spice_debug("client=%p", msg->client);
-+    reds_client_disconnect(msg->client);
-+    red_client_unref(msg->client);
-+}
-+
- void main_dispatcher_seamless_migrate_dst_complete(RedClient *client)
- {
-     MainDispatcherMigrateSeamlessDstCompleteMessage msg;
-@@ -137,6 +152,20 @@ void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency)
-                             &msg);
- }
- 
-+void main_dispatcher_client_disconnect(RedClient *client)
-+{
-+    MainDispatcherClientDisconnectMessage msg;
-+
-+    if (!client->disconnecting) {
-+        spice_debug("client %p", client);
-+        msg.client = red_client_ref(client);
-+        dispatcher_send_message(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
-+                                &msg);
-+    } else {
-+        spice_debug("client %p already during disconnection", client);
-+    }
-+}
-+
- static void dispatcher_handle_read(int fd, int event, void *opaque)
- {
-     Dispatcher *dispatcher = opaque;
-@@ -144,6 +173,11 @@ static void dispatcher_handle_read(int fd, int event, void *opaque)
-     dispatcher_handle_recv_read(dispatcher);
- }
- 
-+/*
-+ * FIXME:
-+ * Reds routines shouldn't be exposed. Instead reds.c should register the callbacks,
-+ * and the corresponding operations should be made only via main_dispatcher.
-+ */
- void main_dispatcher_init(SpiceCoreInterface *core)
- {
-     memset(&main_dispatcher, 0, sizeof(main_dispatcher));
-@@ -160,4 +194,7 @@ void main_dispatcher_init(SpiceCoreInterface *core)
-     dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_SET_MM_TIME_LATENCY,
-                                 main_dispatcher_handle_mm_time_latency,
-                                 sizeof(MainDispatcherMmTimeLatencyMessage), 0 /* no ack */);
-+    dispatcher_register_handler(&main_dispatcher.base, MAIN_DISPATCHER_CLIENT_DISCONNECT,
-+                                main_dispatcher_handle_client_disconnect,
-+                                sizeof(MainDispatcherClientDisconnectMessage), 0 /* no ack */);
- }
-diff --git a/server/main_dispatcher.h b/server/main_dispatcher.h
-index 0c79ca8..522c7f9 100644
---- a/server/main_dispatcher.h
-+++ b/server/main_dispatcher.h
-@@ -7,6 +7,13 @@
- void main_dispatcher_channel_event(int event, SpiceChannelEventInfo *info);
- void main_dispatcher_seamless_migrate_dst_complete(RedClient *client);
- void main_dispatcher_set_mm_time_latency(RedClient *client, uint32_t latency);
-+/*
-+ * Disconnecting the client is always executed asynchronously,
-+ * in order to protect from expired references in the routines
-+ * that triggered the client destruction.
-+ */
-+void main_dispatcher_client_disconnect(RedClient *client);
-+
- void main_dispatcher_init(SpiceCoreInterface *core);
- 
- #endif //MAIN_DISPATCHER_H
-diff --git a/server/reds.c b/server/reds.c
-index 30d0652..c66ddc4 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -537,6 +537,7 @@ void reds_client_disconnect(RedClient *client)
-     }
- 
-     if (!client || client->disconnecting) {
-+        spice_debug("client %p already during disconnection", client);
-         return;
-     }
- 
-diff --git a/server/reds.h b/server/reds.h
-index c5c557d..1c5ae84 100644
---- a/server/reds.h
-+++ b/server/reds.h
-@@ -136,6 +136,8 @@ void reds_handle_agent_mouse_event(const VDAgentMouseState *mouse_state); // use
- extern struct SpiceCoreInterface *core;
- 
- // Temporary measures to make splitting reds.c to inputs_channel.c easier
-+
-+/* should be called only from main_dispatcher */
- void reds_client_disconnect(RedClient *client);
- 
- // Temporary (?) for splitting main channel
diff --git a/SOURCES/0004-main-channel-Prevent-overflow-reading-messages-from-.patch b/SOURCES/0004-main-channel-Prevent-overflow-reading-messages-from-.patch
new file mode 100644
index 0000000..b5d265a
--- /dev/null
+++ b/SOURCES/0004-main-channel-Prevent-overflow-reading-messages-from-.patch
@@ -0,0 +1,27 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Tue, 29 Nov 2016 16:46:56 +0000
+Subject: [PATCH] main-channel: Prevent overflow reading messages from client
+
+Caller is supposed the function return a buffer able to store
+size bytes.
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+---
+ server/main_channel.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/server/main_channel.c b/server/main_channel.c
+index 0ecc9df..1fc3915 100644
+--- a/server/main_channel.c
++++ b/server/main_channel.c
+@@ -1026,6 +1026,9 @@ static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
+ 
+     if (type == SPICE_MSGC_MAIN_AGENT_DATA) {
+         return reds_get_agent_data_buffer(mcc, size);
++    } else if (size > sizeof(main_chan->recv_buf)) {
++        /* message too large, caller will log a message and close the connection */
++        return NULL;
+     } else {
+         return main_chan->recv_buf;
+     }
diff --git a/SOURCES/0005-reds-Check-link-header-magic-without-waiting-for-the.patch b/SOURCES/0005-reds-Check-link-header-magic-without-waiting-for-the.patch
new file mode 100644
index 0000000..70e183d
--- /dev/null
+++ b/SOURCES/0005-reds-Check-link-header-magic-without-waiting-for-the.patch
@@ -0,0 +1,71 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Frediano Ziglio <fziglio@redhat.com>
+Date: Thu, 26 Jan 2017 15:53:18 +0000
+Subject: [PATCH] reds: Check link header magic without waiting for the whole
+ header
+
+This allows the connection to early fail in case initial bytes
+are not correct.
+This allows for instance VNC client to graceful fail connecting
+to a spice-server. This happens easily as the two protocols
+share the same range of ports.
+
+This resolves rhbz#1416692.
+
+Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
+Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+---
+ server/reds.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/server/reds.c b/server/reds.c
+index c639aa3..57a93c9 100644
+--- a/server/reds.c
++++ b/server/reds.c
+@@ -2192,12 +2192,6 @@ static void reds_handle_read_header_done(void *opaque)
+     header->minor_version = GUINT32_FROM_LE(header->minor_version);
+     header->size = GUINT32_FROM_LE(header->size);
+ 
+-    if (header->magic != SPICE_MAGIC) {
+-        reds_send_link_error(link, SPICE_LINK_ERR_INVALID_MAGIC);
+-        reds_link_free(link);
+-        return;
+-    }
+-
+     if (header->major_version != SPICE_VERSION_MAJOR) {
+         if (header->major_version > 0) {
+             reds_send_link_error(link, SPICE_LINK_ERR_VERSION_MISMATCH);
+@@ -2227,13 +2221,31 @@ static void reds_handle_read_header_done(void *opaque)
+                            link);
+ }
+ 
++static void reds_handle_read_magic_done(void *opaque)
++{
++    RedLinkInfo *link = (RedLinkInfo *)opaque;
++    const SpiceLinkHeader *header = &link->link_header;
++
++    if (header->magic != SPICE_MAGIC) {
++        reds_send_link_error(link, SPICE_LINK_ERR_INVALID_MAGIC);
++        reds_link_free(link);
++        return;
++    }
++
++    reds_stream_async_read(link->stream,
++                           ((uint8_t *)&link->link_header) + sizeof(header->magic),
++                           sizeof(SpiceLinkHeader) - sizeof(header->magic),
++                           reds_handle_read_header_done,
++                           link);
++}
++
+ static void reds_handle_new_link(RedLinkInfo *link)
+ {
+     reds_stream_set_async_error_handler(link->stream, reds_handle_link_error);
+     reds_stream_async_read(link->stream,
+                            (uint8_t *)&link->link_header,
+-                           sizeof(SpiceLinkHeader),
+-                           reds_handle_read_header_done,
++                           sizeof(link->link_header.magic),
++                           reds_handle_read_magic_done,
+                            link);
+ }
+ 
diff --git a/SOURCES/0005-reds-s-red_client_disconnect-red_channel_client_shut.patch b/SOURCES/0005-reds-s-red_client_disconnect-red_channel_client_shut.patch
deleted file mode 100644
index e9851ed..0000000
--- a/SOURCES/0005-reds-s-red_client_disconnect-red_channel_client_shut.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Thu, 25 Jul 2013 14:25:24 -0400
-Subject: [PATCH] reds: s/red_client_disconnect/red_channel_client_shutdown
- inside callbacks
-
-When we want to disconnect the main channel from a callback, it is
-safer to use red_channel_client_shutdown, instead of directly
-destroying the client. It is also more consistent with how other
-channels treat errors.
-red_channel_client_shutdown will trigger socket error in the main channel.
-Then, main_channel_client_on_disconnect will be called,
-and eventually, main_dispatcher_client_disconnect.
-
-I didn't replace calls to reds_disconnect/reds_client_disconnect in
-places where those calls were safe && that might need immediate client
-disconnection.
----
- server/reds.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index c66ddc4..ae87c90 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -879,7 +879,8 @@ static void vdi_port_on_free_self_token(void *opaque)
- 
- static void vdi_port_remove_client(RedClient *client, void *opaque)
- {
--    reds_client_disconnect(client);
-+    red_channel_client_shutdown(main_channel_client_get_base(
-+                                    red_client_get_main(client)));
- }
- 
- /****************************************************************************/
-@@ -1009,7 +1010,7 @@ void reds_on_main_agent_start(MainChannelClient *mcc, uint32_t num_tokens)
- 
-         if (!client_added) {
-             spice_warning("failed to add client to agent");
--            reds_client_disconnect(rcc->client);
-+            red_channel_client_shutdown(rcc);
-             return;
-         }
-     } else {
-@@ -1126,7 +1127,7 @@ void reds_on_main_agent_data(MainChannelClient *mcc, void *message, size_t size)
-         reds_on_main_agent_monitors_config(mcc, message, size);
-         return;
-     case AGENT_MSG_FILTER_PROTO_ERROR:
--        reds_disconnect();
-+        red_channel_client_shutdown(main_channel_client_get_base(mcc));
-         return;
-     }
- 
diff --git a/SOURCES/0006-snd_worker-fix-memory-leak-of-PlaybackChannel.patch b/SOURCES/0006-snd_worker-fix-memory-leak-of-PlaybackChannel.patch
deleted file mode 100644
index da9d6f1..0000000
--- a/SOURCES/0006-snd_worker-fix-memory-leak-of-PlaybackChannel.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Thu, 25 Jul 2013 14:49:33 -0400
-Subject: [PATCH] snd_worker: fix memory leak of PlaybackChannel
-
-When the sequence of calls bellow occurs, the PlaybackChannel
-is not released (snd_channel_put is not called for the
-samples that refer to the channel).
-
-    spice_server_playback_get_buffer
-    snd_channel_disconnect
-    spice_server_playback_put_samples
----
- server/snd_worker.c | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index d6ec47a..849f002 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -1097,14 +1097,13 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
-     PlaybackChannel *playback_channel;
-     AudioFrame *frame;
- 
--    if (!sin->st->worker.connection) {
--        return;
--    }
--
-     frame = SPICE_CONTAINEROF(samples, AudioFrame, samples);
-     playback_channel = frame->channel;
--    if (!snd_channel_put(&playback_channel->base) || !playback_channel->base.worker->connection) {
-+    spice_assert(playback_channel);
-+    if (!snd_channel_put(&playback_channel->base) ||
-+        sin->st->worker.connection != &playback_channel->base) {
-         /* lost last reference, channel has been destroyed previously */
-+        spice_info("audio samples belong to a disconnected channel");
-         return;
-     }
-     spice_assert(playback_channel->base.active);
diff --git a/SOURCES/0007-snd_worker-snd_disconnect_channel-don-t-call-snd_cha.patch b/SOURCES/0007-snd_worker-snd_disconnect_channel-don-t-call-snd_cha.patch
deleted file mode 100644
index 5243444..0000000
--- a/SOURCES/0007-snd_worker-snd_disconnect_channel-don-t-call-snd_cha.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Thu, 25 Jul 2013 15:07:43 -0400
-Subject: [PATCH] snd_worker/snd_disconnect_channel: don't call snd_channel_put
- if the channel has already been disconnected
-
-The snd channels has one reference as long as their socket is active.
-The playback channel has an additional reference for each frame that is
-currently filled by the sound device.
-Once the channel is disconnected (the socket has been freed and the
-first reference is released) snd_disconnect_channel shouldn't release
-a reference again.
----
- server/snd_worker.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index 849f002..3827416 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -212,21 +212,20 @@ static void snd_disconnect_channel(SndChannel *channel)
- {
-     SndWorker *worker;
- 
--    if (!channel) {
-+    if (!channel || !channel->stream) {
-         spice_debug("not connected");
-         return;
-     }
-     spice_debug("%p", channel);
-     worker = channel->worker;
--    if (channel->stream) {
--        channel->cleanup(channel);
--        red_channel_client_disconnect(worker->connection->channel_client);
--        core->watch_remove(channel->stream->watch);
--        channel->stream->watch = NULL;
--        reds_stream_free(channel->stream);
--        channel->stream = NULL;
--        spice_marshaller_destroy(channel->send_data.marshaller);
--    }
-+    channel->cleanup(channel);
-+    red_channel_client_disconnect(worker->connection->channel_client);
-+    worker->connection->channel_client = NULL;
-+    core->watch_remove(channel->stream->watch);
-+    channel->stream->watch = NULL;
-+    reds_stream_free(channel->stream);
-+    channel->stream = NULL;
-+    spice_marshaller_destroy(channel->send_data.marshaller);
-     snd_channel_put(channel);
-     worker->connection = NULL;
- }
-@@ -897,6 +896,7 @@ static SndChannel *__new_channel(SndWorker *worker, int size, uint32_t channel_i
-     int tos;
-     MainChannelClient *mcc = red_client_get_main(client);
- 
-+    spice_assert(stream);
-     if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
-         spice_printerr("accept failed, %s", strerror(errno));
-         goto error1;
diff --git a/SOURCES/0008-log-improve-debug-information-related-to-client-disc.patch b/SOURCES/0008-log-improve-debug-information-related-to-client-disc.patch
deleted file mode 100644
index 900ffdf..0000000
--- a/SOURCES/0008-log-improve-debug-information-related-to-client-disc.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Fri, 26 Jul 2013 12:15:00 -0400
-Subject: [PATCH] log: improve debug information related to client
- disconnection
-
----
- server/red_channel.c | 9 ++++++---
- server/snd_worker.c  | 7 ++++---
- 2 files changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 9433bef..1a57db5 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -1100,6 +1100,7 @@ static void red_channel_client_ref(RedChannelClient *rcc)
- static void red_channel_client_unref(RedChannelClient *rcc)
- {
-     if (!--rcc->refs) {
-+        spice_debug("destroy rcc=%p", rcc);
-         if (rcc->send_data.main.marshaller) {
-             spice_marshaller_destroy(rcc->send_data.main.marshaller);
-         }
-@@ -1696,6 +1697,8 @@ static void red_channel_client_disconnect_dummy(RedChannelClient *rcc)
- {
-     spice_assert(rcc->dummy);
-     if (ring_item_is_linked(&rcc->channel_link)) {
-+        spice_printerr("rcc=%p (channel=%p type=%d id=%d)", rcc, rcc->channel,
-+                       rcc->channel->type, rcc->channel->id);
-         red_channel_remove_client(rcc);
-     }
-     rcc->dummy_connected = FALSE;
-@@ -1703,8 +1706,6 @@ static void red_channel_client_disconnect_dummy(RedChannelClient *rcc)
- 
- void red_channel_client_disconnect(RedChannelClient *rcc)
- {
--    spice_printerr("%p (channel %p type %d id %d)", rcc, rcc->channel,
--                                                rcc->channel->type, rcc->channel->id);
-     if (rcc->dummy) {
-         red_channel_client_disconnect_dummy(rcc);
-         return;
-@@ -1712,6 +1713,8 @@ void red_channel_client_disconnect(RedChannelClient *rcc)
-     if (!red_channel_client_is_connected(rcc)) {
-         return;
-     }
-+    spice_printerr("rcc=%p (channel=%p type=%d id=%d)", rcc, rcc->channel,
-+                   rcc->channel->type, rcc->channel->id);
-     red_channel_client_pipe_clear(rcc);
-     if (rcc->stream->watch) {
-         rcc->channel->core->watch_remove(rcc->stream->watch);
-@@ -1995,7 +1998,7 @@ void red_client_destroy(RedClient *client)
-     RingItem *link, *next;
-     RedChannelClient *rcc;
- 
--    spice_printerr("destroy client with #channels %d", client->channels_num);
-+    spice_printerr("destroy client %p with #channels=%d", client, client->channels_num);
-     if (!pthread_equal(pthread_self(), client->thread_id)) {
-         spice_warning("client->thread_id (0x%lx) != pthread_self (0x%lx)."
-                       "If one of the threads is != io-thread && != vcpu-thread,"
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index 3827416..ebddfcd 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -201,8 +201,8 @@ static SndChannel *snd_channel_get(SndChannel *channel)
- static SndChannel *snd_channel_put(SndChannel *channel)
- {
-     if (!--channel->refs) {
-+        spice_printerr("SndChannel=%p freed", channel);
-         free(channel);
--        spice_printerr("sound channel freed");
-         return NULL;
-     }
-     return channel;
-@@ -216,7 +216,8 @@ static void snd_disconnect_channel(SndChannel *channel)
-         spice_debug("not connected");
-         return;
-     }
--    spice_debug("%p", channel);
-+    spice_debug("SndChannel=%p rcc=%p type=%d",
-+                 channel, channel->channel_client, channel->channel_client->channel->type);
-     worker = channel->worker;
-     channel->cleanup(channel);
-     red_channel_client_disconnect(worker->connection->channel_client);
-@@ -976,11 +977,11 @@ static void snd_disconnect_channel_client(RedChannelClient *rcc)
- {
-     SndWorker *worker;
- 
--    spice_debug(NULL);
-     spice_assert(rcc->channel);
-     spice_assert(rcc->channel->data);
-     worker = (SndWorker *)rcc->channel->data;
- 
-+    spice_debug("channel-type=%d", rcc->channel->type);
-     if (worker->connection) {
-         spice_assert(worker->connection->channel_client == rcc);
-         snd_disconnect_channel(worker->connection);
diff --git a/SOURCES/0009-red_worker-decrease-the-timeout-when-flushing-comman.patch b/SOURCES/0009-red_worker-decrease-the-timeout-when-flushing-comman.patch
deleted file mode 100644
index fb53c25..0000000
--- a/SOURCES/0009-red_worker-decrease-the-timeout-when-flushing-comman.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Mon, 5 Aug 2013 12:10:15 -0400
-Subject: [PATCH] red_worker: decrease the timeout when flushing commands and
- waiting for the client.
-
-150 seconds is way too long period for holding the guest driver and
-waiting for a response for the client. This timeout was 15 seconds, but
-when off-screen surfaces ware introduced it was arbitrarily multiplied by
-10.
-Other existing related bugs emphasize why it is important to decrease
-the timeout:
-(1) 994211 - the qxl driver waits for an async-io reponse for 60 seconds
-    and after that, it switches to sync-io mode. Not only that the
-    driver might use invalid data (since it didn't wait for the query to
-    complete), falling back to sync-io mode introduces other errors.
-(2) 994175 - spice server sometimes doesn't recognize that the client
-             has disconnected.
-(3) There might be cache inconsistency between the client and the server,
-and then the display channel waits indefinitely for a cache item (e.g., bug
-977998)
-
-This patch changes the timeout to 30 seconds. I tested it under wifi +emulating 2.5Mbps network,
-together with playing video on the guest and changing resolutions in a loop. The timeout didn't expired
-during my tests.
-
-This bug is related to rhbz#964136 (but from rhbz#964136 info it is still not
-clear why the client wasn't responsive).
----
- server/red_worker.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 73fe866..a4f0663 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -103,7 +103,7 @@
- #define CHANNEL_PUSH_TIMEOUT 30000000000ULL //nano
- #define CHANNEL_PUSH_SLEEP_DURATION 10000 //micro
- 
--#define DISPLAY_CLIENT_TIMEOUT 15000000000ULL //nano
-+#define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
- #define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec
- #define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro
- 
-@@ -9721,7 +9721,7 @@ static inline void flush_display_commands(RedWorker *worker)
-         if (ring_is_empty) {
-             break;
-         }
--        end_time = red_now() + DISPLAY_CLIENT_TIMEOUT * 10;
-+        end_time = red_now() + DISPLAY_CLIENT_TIMEOUT;
-         int sleep_count = 0;
-         for (;;) {
-             red_channel_push(&worker->display_channel->common.base);
-@@ -9765,7 +9765,7 @@ static inline void flush_cursor_commands(RedWorker *worker)
-         if (ring_is_empty) {
-             break;
-         }
--        end_time = red_now() + DISPLAY_CLIENT_TIMEOUT * 10;
-+        end_time = red_now() + DISPLAY_CLIENT_TIMEOUT;
-         int sleep_count = 0;
-         for (;;) {
-             red_channel_push(&worker->cursor_channel->common.base);
diff --git a/SOURCES/0010-Fix-buffer-overflow-when-decrypting-client-SPICE-tic.patch b/SOURCES/0010-Fix-buffer-overflow-when-decrypting-client-SPICE-tic.patch
deleted file mode 100644
index 6cc2375..0000000
--- a/SOURCES/0010-Fix-buffer-overflow-when-decrypting-client-SPICE-tic.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Fri, 23 Aug 2013 11:29:44 +0200
-Subject: [PATCH] Fix buffer overflow when decrypting client SPICE ticket
-
-reds_handle_ticket uses a fixed size 'password' buffer for the decrypted
-password whose size is SPICE_MAX_PASSWORD_LENGTH. However,
-RSA_private_decrypt which we call for the decryption expects the
-destination buffer to be at least RSA_size(link->tiTicketing.rsa)
-bytes long. On my spice-server build, SPICE_MAX_PASSWORD_LENGTH
-is 60 while RSA_size() is 128, so we end up overflowing 'password'
-when using long passwords (this was reproduced using the string:
-'fullscreen=1proxy=#enter proxy here; e.g spice_proxy = http://[proxy]:[port]'
-as a password).
-
-When the overflow occurs, QEMU dies with:
-*** stack smashing detected ***: qemu-system-x86_64 terminated
-
-This commit ensures we use a corectly sized 'password' buffer,
-and that it's correctly nul-terminated so that we can use strcmp
-instead of strncmp. To keep using strncmp, we'd need to figure out
-which one of 'password' and 'taTicket.password' is the smaller buffer,
-and use that size.
-
-This fixes rhbz#999839
----
- server/reds.c | 44 ++++++++++++++++++++++++++++++++------------
- 1 file changed, 32 insertions(+), 12 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index ae87c90..f9f185d 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1933,39 +1933,59 @@ static void reds_handle_link(RedLinkInfo *link)
- static void reds_handle_ticket(void *opaque)
- {
-     RedLinkInfo *link = (RedLinkInfo *)opaque;
--    char password[SPICE_MAX_PASSWORD_LENGTH];
-+    char *password;
-     time_t ltime;
-+    int password_size;
- 
-     //todo: use monotonic time
-     time(&ltime);
--    RSA_private_decrypt(link->tiTicketing.rsa_size,
--                        link->tiTicketing.encrypted_ticket.encrypted_data,
--                        (unsigned char *)password, link->tiTicketing.rsa, RSA_PKCS1_OAEP_PADDING);
-+    if (RSA_size(link->tiTicketing.rsa) < SPICE_MAX_PASSWORD_LENGTH) {
-+        spice_warning("RSA modulus size is smaller than SPICE_MAX_PASSWORD_LENGTH (%d < %d), "
-+                      "SPICE ticket sent from client may be truncated",
-+                      RSA_size(link->tiTicketing.rsa), SPICE_MAX_PASSWORD_LENGTH);
-+    }
-+
-+    password = g_malloc0(RSA_size(link->tiTicketing.rsa) + 1);
-+    password_size = RSA_private_decrypt(link->tiTicketing.rsa_size,
-+                                        link->tiTicketing.encrypted_ticket.encrypted_data,
-+                                        (unsigned char *)password,
-+                                        link->tiTicketing.rsa,
-+                                        RSA_PKCS1_OAEP_PADDING);
-+    if (password_size == -1) {
-+        spice_warning("failed to decrypt RSA encrypted password: %s",
-+                      ERR_error_string(ERR_get_error(), NULL));
-+        goto error;
-+    }
-+    password[password_size] = '\0';
- 
-     if (ticketing_enabled && !link->skip_auth) {
-         int expired =  taTicket.expiration_time < ltime;
- 
-         if (strlen(taTicket.password) == 0) {
--            reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED);
-             spice_warning("Ticketing is enabled, but no password is set. "
--                        "please set a ticket first");
--            reds_link_free(link);
--            return;
-+                          "please set a ticket first");
-+            goto error;
-         }
- 
--        if (expired || strncmp(password, taTicket.password, SPICE_MAX_PASSWORD_LENGTH) != 0) {
-+        if (expired || strcmp(password, taTicket.password) != 0) {
-             if (expired) {
-                 spice_warning("Ticket has expired");
-             } else {
-                 spice_warning("Invalid password");
-             }
--            reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED);
--            reds_link_free(link);
--            return;
-+            goto error;
-         }
-     }
- 
-     reds_handle_link(link);
-+    goto end;
-+
-+error:
-+    reds_send_link_result(link, SPICE_LINK_ERR_PERMISSION_DENIED);
-+    reds_link_free(link);
-+
-+end:
-+    g_free(password);
- }
- 
- static inline void async_read_clear_handlers(AsyncRead *obj)
diff --git a/SOURCES/0011-server-move-three-functions-to-red_channel.patch b/SOURCES/0011-server-move-three-functions-to-red_channel.patch
deleted file mode 100644
index c541150..0000000
--- a/SOURCES/0011-server-move-three-functions-to-red_channel.patch
+++ /dev/null
@@ -1,382 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Mon, 12 Aug 2013 15:01:42 +0300
-Subject: [PATCH] server: move three functions to red_channel
-
-Three blocking functions, one was split to leave the display channel
-specific referencing of the DrawablePipeItem being sent inside
-red_worker, but the rest (most) of the timeout logic was moved to
-red_channel, including the associated constants.
-
-Moved functions:
-red_channel_client_wait_pipe_item_sent
-red_wait_outgoing_item
-red_wait_all_sent
-
-Introduces red_time.h & red_time.c for a small helper function dealing
-with time.h
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016795
-Conflicts:
-	server/red_worker.c
----
- server/red_channel.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
- server/red_channel.h |  10 +++++
- server/red_time.c    |   1 +
- server/red_time.h    |  15 +++++++
- server/red_worker.c  | 121 +--------------------------------------------------
- 5 files changed, 134 insertions(+), 119 deletions(-)
- create mode 100644 server/red_time.c
- create mode 100644 server/red_time.h
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 1a57db5..555d376 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -38,6 +38,7 @@
- #include "red_channel.h"
- #include "reds.h"
- #include "main_dispatcher.h"
-+#include "red_time.h"
- 
- typedef struct EmptyMsgPipeItem {
-     PipeItem base;
-@@ -47,6 +48,12 @@ typedef struct EmptyMsgPipeItem {
- #define PING_TEST_TIMEOUT_MS 15000
- #define PING_TEST_IDLE_NET_TIMEOUT_MS 100
- 
-+#define DETACH_TIMEOUT 15000000000ULL //nano
-+#define DETACH_SLEEP_DURATION 10000 //micro
-+
-+#define CHANNEL_PUSH_TIMEOUT 30000000000ULL //nano
-+#define CHANNEL_PUSH_SLEEP_DURATION 10000 //micro
-+
- enum QosPingState {
-     PING_STATE_NONE,
-     PING_STATE_TIMER,
-@@ -2183,3 +2190,102 @@ uint32_t red_channel_sum_pipes_size(RedChannel *channel)
-     }
-     return sum;
- }
-+
-+void red_wait_outgoing_item(RedChannelClient *rcc)
-+{
-+    uint64_t end_time;
-+    int blocked;
-+
-+    if (!red_channel_client_blocked(rcc)) {
-+        return;
-+    }
-+    end_time = red_now() + DETACH_TIMEOUT;
-+    spice_info("blocked");
-+
-+    do {
-+        usleep(DETACH_SLEEP_DURATION);
-+        red_channel_client_receive(rcc);
-+        red_channel_client_send(rcc);
-+    } while ((blocked = red_channel_client_blocked(rcc)) && red_now() < end_time);
-+
-+    if (blocked) {
-+        spice_warning("timeout");
-+        // TODO - shutting down the socket but we still need to trigger
-+        // disconnection. Right now we wait for main channel to error for that.
-+        red_channel_client_shutdown(rcc);
-+    } else {
-+        spice_assert(red_channel_client_no_item_being_sent(rcc));
-+    }
-+}
-+
-+/* TODO: more evil sync stuff. anything with the word wait in it's name. */
-+void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
-+                                            PipeItem *item)
-+{
-+    uint64_t end_time;
-+    int item_in_pipe;
-+
-+    spice_info(NULL);
-+
-+    end_time = red_now() + CHANNEL_PUSH_TIMEOUT;
-+
-+    rcc->channel->channel_cbs.hold_item(rcc, item);
-+
-+    if (red_channel_client_blocked(rcc)) {
-+        red_channel_client_receive(rcc);
-+        red_channel_client_send(rcc);
-+    }
-+    red_channel_client_push(rcc);
-+
-+    while((item_in_pipe = ring_item_is_linked(&item->link)) && (red_now() < end_time)) {
-+        usleep(CHANNEL_PUSH_SLEEP_DURATION);
-+        red_channel_client_receive(rcc);
-+        red_channel_client_send(rcc);
-+        red_channel_client_push(rcc);
-+    }
-+
-+    if (item_in_pipe) {
-+        spice_warning("timeout");
-+        red_channel_client_disconnect(rcc);
-+    } else {
-+        red_wait_outgoing_item(rcc);
-+    }
-+    red_channel_client_release_item(rcc, item, TRUE);
-+}
-+
-+static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
-+{
-+    if (red_channel_client_blocked(rcc) || rcc->pipe_size > 0) {
-+        red_channel_client_shutdown(rcc);
-+    } else {
-+        spice_assert(red_channel_client_no_item_being_sent(rcc));
-+    }
-+}
-+
-+void red_wait_all_sent(RedChannel *channel)
-+{
-+    uint64_t end_time;
-+    uint32_t max_pipe_size;
-+    int blocked = FALSE;
-+
-+    end_time = red_now() + DETACH_TIMEOUT;
-+
-+    red_channel_push(channel);
-+    while (((max_pipe_size = red_channel_max_pipe_size(channel)) ||
-+           (blocked = red_channel_any_blocked(channel))) &&
-+           red_now() < end_time) {
-+        spice_debug("pipe-size %u blocked %d", max_pipe_size, blocked);
-+        usleep(DETACH_SLEEP_DURATION);
-+        red_channel_receive(channel);
-+        red_channel_send(channel);
-+        red_channel_push(channel);
-+    }
-+
-+    if (max_pipe_size || blocked) {
-+        spice_printerr("timeout: pending out messages exist (pipe-size %u, blocked %d)",
-+                       max_pipe_size, blocked);
-+        red_channel_apply_clients(channel, rcc_shutdown_if_pending_send);
-+    } else {
-+        spice_assert(red_channel_no_item_being_sent(channel));
-+    }
-+}
-diff --git a/server/red_channel.h b/server/red_channel.h
-index 0dd73ea..b2a3a6a 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -596,4 +596,14 @@ int red_client_during_migrate_at_target(RedClient *client);
- 
- void red_client_migrate(RedClient *client);
- 
-+/* blocking function */
-+void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
-+                                            PipeItem *item);
-+
-+/* blocking function */
-+void red_wait_outgoing_item(RedChannelClient *rcc);
-+
-+/* blocking function */
-+void red_wait_all_sent(RedChannel *channel);
-+
- #endif
-diff --git a/server/red_time.c b/server/red_time.c
-new file mode 100644
-index 0000000..8b13789
---- /dev/null
-+++ b/server/red_time.c
-@@ -0,0 +1 @@
-+
-diff --git a/server/red_time.h b/server/red_time.h
-new file mode 100644
-index 0000000..ffa97f2
---- /dev/null
-+++ b/server/red_time.h
-@@ -0,0 +1,15 @@
-+#ifndef H_RED_TIME
-+#define H_RED_TIME
-+
-+#include <time.h>
-+
-+static inline uint64_t red_now(void)
-+{
-+    struct timespec time;
-+
-+    clock_gettime(CLOCK_MONOTONIC, &time);
-+
-+    return ((uint64_t) time.tv_sec) * 1000000000 + time.tv_nsec;
-+}
-+
-+#endif
-diff --git a/server/red_worker.c b/server/red_worker.c
-index a4f0663..b3a957e 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -82,6 +82,7 @@
- #include "migration_protocol.h"
- #include "spice_timer_queue.h"
- #include "main_dispatcher.h"
-+#include "red_time.h"
- 
- //#define COMPRESS_STAT
- //#define DUMP_BITMAP
-@@ -97,12 +98,6 @@
- #define CMD_RING_POLL_TIMEOUT 10 //milli
- #define CMD_RING_POLL_RETRIES 200
- 
--#define DETACH_TIMEOUT 15000000000ULL //nano
--#define DETACH_SLEEP_DURATION 10000 //micro
--
--#define CHANNEL_PUSH_TIMEOUT 30000000000ULL //nano
--#define CHANNEL_PUSH_SLEEP_DURATION 10000 //micro
--
- #define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
- #define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec
- #define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro
-@@ -1098,14 +1093,12 @@ static void cursor_channel_client_release_item_before_push(CursorChannelClient *
-                                                            PipeItem *item);
- static void cursor_channel_client_release_item_after_push(CursorChannelClient *ccc,
-                                                           PipeItem *item);
--static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item);
- 
- #ifdef DUMP_BITMAP
- static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_id);
- #endif
- 
- static void red_push_monitors_config(DisplayChannelClient *dcc);
--static inline uint64_t red_now(void);
- 
- /*
-  * Macros to make iterating over stuff easier
-@@ -2098,12 +2091,10 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
-     }
- 
-     if (item) {
--        red_wait_pipe_item_sent(&dcc->common.base, item);
-+        red_channel_client_wait_pipe_item_sent(&dcc->common.base, item);
-     }
- }
- 
--static void red_wait_outgoing_item(RedChannelClient *rcc);
--
- static void red_clear_surface_drawables_from_pipes(RedWorker *worker, int surface_id,
-     int force, int wait_for_outgoing_item)
- {
-@@ -5088,15 +5079,6 @@ static void qxl_process_cursor(RedWorker *worker, RedCursorCmd *cursor_cmd, uint
-     red_release_cursor(worker, cursor_item);
- }
- 
--static inline uint64_t red_now(void)
--{
--    struct timespec time;
--
--    clock_gettime(CLOCK_MONOTONIC, &time);
--
--    return ((uint64_t) time.tv_sec) * 1000000000 + time.tv_nsec;
--}
--
- static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ring_is_empty)
- {
-     QXLCommandExt ext_cmd;
-@@ -10988,105 +10970,6 @@ typedef struct __attribute__ ((__packed__)) CursorData {
-     SpiceCursor _cursor;
- } CursorData;
- 
--static void red_wait_outgoing_item(RedChannelClient *rcc)
--{
--    uint64_t end_time;
--    int blocked;
--
--    if (!red_channel_client_blocked(rcc)) {
--        return;
--    }
--    end_time = red_now() + DETACH_TIMEOUT;
--    spice_info("blocked");
--
--    do {
--        usleep(DETACH_SLEEP_DURATION);
--        red_channel_client_receive(rcc);
--        red_channel_client_send(rcc);
--    } while ((blocked = red_channel_client_blocked(rcc)) && red_now() < end_time);
--
--    if (blocked) {
--        spice_warning("timeout");
--        // TODO - shutting down the socket but we still need to trigger
--        // disconnection. Right now we wait for main channel to error for that.
--        red_channel_client_shutdown(rcc);
--    } else {
--        spice_assert(red_channel_client_no_item_being_sent(rcc));
--    }
--}
--
--static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
--{
--    if (red_channel_client_blocked(rcc) || rcc->pipe_size > 0) {
--        red_channel_client_shutdown(rcc);
--    } else {
--        spice_assert(red_channel_client_no_item_being_sent(rcc));
--    }
--}
--
--static void red_wait_all_sent(RedChannel *channel)
--{
--    uint64_t end_time;
--    uint32_t max_pipe_size;
--    int blocked = FALSE;
--
--    end_time = red_now() + DETACH_TIMEOUT;
--
--    red_channel_push(channel);
--    while (((max_pipe_size = red_channel_max_pipe_size(channel)) ||
--           (blocked = red_channel_any_blocked(channel))) &&
--           red_now() < end_time) {
--        spice_debug("pipe-size %u blocked %d", max_pipe_size, blocked);
--        usleep(DETACH_SLEEP_DURATION);
--        red_channel_receive(channel);
--        red_channel_send(channel);
--        red_channel_push(channel);
--    }
--
--    if (max_pipe_size || blocked) {
--        spice_printerr("timeout: pending out messages exist (pipe-size %u, blocked %d)",
--                       max_pipe_size, blocked);
--        red_channel_apply_clients(channel, rcc_shutdown_if_pending_send);
--    } else {
--        spice_assert(red_channel_no_item_being_sent(channel));
--    }
--}
--
--/* TODO: more evil sync stuff. anything with the word wait in it's name. */
--static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
--{
--    DrawablePipeItem *dpi;
--    uint64_t end_time;
--    int item_in_pipe;
--
--    spice_info(NULL);
--    dpi = SPICE_CONTAINEROF(item, DrawablePipeItem, dpi_pipe_item);
--    ref_drawable_pipe_item(dpi);
--
--    end_time = red_now() + CHANNEL_PUSH_TIMEOUT;
--
--    if (red_channel_client_blocked(rcc)) {
--        red_channel_client_receive(rcc);
--        red_channel_client_send(rcc);
--    }
--    red_channel_client_push(rcc);
--
--    while((item_in_pipe = ring_item_is_linked(&item->link)) && (red_now() < end_time)) {
--        usleep(CHANNEL_PUSH_SLEEP_DURATION);
--        red_channel_client_receive(rcc);
--        red_channel_client_send(rcc);
--        red_channel_client_push(rcc);
--    }
--
--    if (item_in_pipe) {
--        spice_warning("timeout");
--        red_channel_client_disconnect(rcc);
--    } else {
--        red_wait_outgoing_item(rcc);
--    }
--    put_drawable_pipe_item(dpi);
--}
--
- static void surface_dirty_region_to_rects(RedSurface *surface,
-                                           QXLRect *qxl_dirty_rects,
-                                           uint32_t num_dirty_rects,
diff --git a/SOURCES/0012-server-s-red_wait_all_sent-red_channel_wait_all_sent.patch b/SOURCES/0012-server-s-red_wait_all_sent-red_channel_wait_all_sent.patch
deleted file mode 100644
index 1a44cf0..0000000
--- a/SOURCES/0012-server-s-red_wait_all_sent-red_channel_wait_all_sent.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Alon Levy <alevy@redhat.com>
-Date: Mon, 12 Aug 2013 19:48:24 +0300
-Subject: [PATCH] server: s/red_wait_all_sent/red_channel_wait_all_sent/
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016795
-(cherry picked from commit 9b8ff0428468b7f081fe6f2b27774af2d0b4dadf)
----
- server/red_channel.c | 2 +-
- server/red_channel.h | 2 +-
- server/red_worker.c  | 6 +++---
- 3 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 555d376..6e43e0a 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -2262,7 +2262,7 @@ static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
-     }
- }
- 
--void red_wait_all_sent(RedChannel *channel)
-+void red_channel_wait_all_sent(RedChannel *channel)
- {
-     uint64_t end_time;
-     uint32_t max_pipe_size;
-diff --git a/server/red_channel.h b/server/red_channel.h
-index b2a3a6a..9021b3f 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -604,6 +604,6 @@ void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
- void red_wait_outgoing_item(RedChannelClient *rcc);
- 
- /* blocking function */
--void red_wait_all_sent(RedChannel *channel);
-+void red_channel_wait_all_sent(RedChannel *channel);
- 
- #endif
-diff --git a/server/red_worker.c b/server/red_worker.c
-index b3a957e..b93796c 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -11138,7 +11138,7 @@ static inline void red_cursor_reset(RedWorker *worker)
-         if (!worker->cursor_channel->common.during_target_migrate) {
-             red_pipes_add_verb(&worker->cursor_channel->common.base, SPICE_MSG_CURSOR_RESET);
-         }
--        red_wait_all_sent(&worker->cursor_channel->common.base);
-+        red_channel_wait_all_sent(&worker->cursor_channel->common.base);
-     }
- }
- 
-@@ -11421,8 +11421,8 @@ void handle_dev_stop(void *opaque, void *payload)
-      * purge the pipe, send destroy_all_surfaces
-      * to the client (there is no such message right now), and start
-      * from scratch on the destination side */
--    red_wait_all_sent(&worker->display_channel->common.base);
--    red_wait_all_sent(&worker->cursor_channel->common.base);
-+    red_channel_wait_all_sent(&worker->display_channel->common.base);
-+    red_channel_wait_all_sent(&worker->cursor_channel->common.base);
- }
- 
- static int display_channel_wait_for_migrate_data(DisplayChannel *display)
diff --git a/SOURCES/0013-red_worker-cleanup-red_clear_surface_drawables_from_.patch b/SOURCES/0013-red_worker-cleanup-red_clear_surface_drawables_from_.patch
deleted file mode 100644
index b0c8bcc..0000000
--- a/SOURCES/0013-red_worker-cleanup-red_clear_surface_drawables_from_.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 11 Sep 2013 13:39:35 -0400
-Subject: [PATCH] red_worker: cleanup red_clear_surface_drawables_from_pipes
-
-(1) merge 'force' and 'wait_for_outgoing_item' to one parameter.
-    'wait_for_outgoing_item' is a derivative of 'force'.
-(2) move the call to red_wait_outgoing_item to red_clear_surface_drawables_from_pipe
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016795
----
- server/red_worker.c | 30 ++++++++++++++++++------------
- 1 file changed, 18 insertions(+), 12 deletions(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index b93796c..f2c9220 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -2032,7 +2032,7 @@ static void red_current_clear(RedWorker *worker, int surface_id)
- }
- 
- static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id,
--                                                  int force)
-+                                                  int wait_if_used)
- {
-     Ring *ring;
-     PipeItem *item;
-@@ -2082,7 +2082,7 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
- 
-         if (depend_found) {
-             spice_debug("surface %d dependent item found %p, %p", surface_id, drawable, item);
--            if (force) {
-+            if (wait_if_used) {
-                 break;
-             } else {
-                 return;
-@@ -2090,24 +2090,30 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
-         }
-     }
- 
-+    if (!wait_if_used) {
-+        return;
-+    }
-+
-     if (item) {
-         red_channel_client_wait_pipe_item_sent(&dcc->common.base, item);
-+    } else {
-+        /*
-+         * in case that the pipe didn't contain any item that is dependent on the surface, but
-+         * there is one during sending.
-+         */
-+        red_wait_outgoing_item(&dcc->common.base);
-     }
- }
- 
--static void red_clear_surface_drawables_from_pipes(RedWorker *worker, int surface_id,
--    int force, int wait_for_outgoing_item)
-+static void red_clear_surface_drawables_from_pipes(RedWorker *worker,
-+                                                   int surface_id,
-+                                                   int wait_if_used)
- {
-     RingItem *item, *next;
-     DisplayChannelClient *dcc;
- 
-     WORKER_FOREACH_DCC_SAFE(worker, item, next, dcc) {
--        red_clear_surface_drawables_from_pipe(dcc, surface_id, force);
--        if (wait_for_outgoing_item) {
--            // in case that the pipe didn't contain any item that is dependent on the surface, but
--            // there is one during sending.
--            red_wait_outgoing_item(&dcc->common.base);
--        }
-+        red_clear_surface_drawables_from_pipe(dcc, surface_id, wait_if_used);
-     }
- }
- 
-@@ -4292,7 +4298,7 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
-            otherwise "current" will hold items that other drawables may depend on, and then
-            red_current_clear will remove them from the pipe. */
-         red_current_clear(worker, surface_id);
--        red_clear_surface_drawables_from_pipes(worker, surface_id, FALSE, FALSE);
-+        red_clear_surface_drawables_from_pipes(worker, surface_id, FALSE);
-         red_destroy_surface(worker, surface_id);
-         break;
-     default:
-@@ -11099,7 +11105,7 @@ static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
-        otherwise "current" will hold items that other drawables may depend on, and then
-        red_current_clear will remove them from the pipe. */
-     red_current_clear(worker, surface_id);
--    red_clear_surface_drawables_from_pipes(worker, surface_id, TRUE, TRUE);
-+    red_clear_surface_drawables_from_pipes(worker, surface_id, TRUE);
- }
- 
- static void dev_destroy_surface_wait(RedWorker *worker, uint32_t surface_id)
diff --git a/SOURCES/0014-red_channel-cleanup-of-red_channel_client-blocking-m.patch b/SOURCES/0014-red_channel-cleanup-of-red_channel_client-blocking-m.patch
deleted file mode 100644
index d70f4a6..0000000
--- a/SOURCES/0014-red_channel-cleanup-of-red_channel_client-blocking-m.patch
+++ /dev/null
@@ -1,330 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 11 Sep 2013 13:31:21 -0400
-Subject: [PATCH] red_channel: cleanup of red_channel_client blocking methods
-
-(1) receive timeout as a parameter.
-(2) add a return value and pass the handling
-    of failures to the calling routine.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016795
-(cherry picked from commit bcf9e64f134a6073c1e404efc8892c1cb453bd8a)
----
- server/red_channel.c | 73 ++++++++++++++++++++++++++--------------------------
- server/red_channel.h | 22 ++++++++++------
- server/red_worker.c  | 55 ++++++++++++++++++++++++++++++---------
- 3 files changed, 93 insertions(+), 57 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 6e43e0a..228669b 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -48,11 +48,7 @@ typedef struct EmptyMsgPipeItem {
- #define PING_TEST_TIMEOUT_MS 15000
- #define PING_TEST_IDLE_NET_TIMEOUT_MS 100
- 
--#define DETACH_TIMEOUT 15000000000ULL //nano
--#define DETACH_SLEEP_DURATION 10000 //micro
--
--#define CHANNEL_PUSH_TIMEOUT 30000000000ULL //nano
--#define CHANNEL_PUSH_SLEEP_DURATION 10000 //micro
-+#define CHANNEL_BLOCKED_SLEEP_DURATION 10000 //micro
- 
- enum QosPingState {
-     PING_STATE_NONE,
-@@ -2191,43 +2187,49 @@ uint32_t red_channel_sum_pipes_size(RedChannel *channel)
-     return sum;
- }
- 
--void red_wait_outgoing_item(RedChannelClient *rcc)
-+int red_channel_client_wait_outgoing_item(RedChannelClient *rcc,
-+                                          int64_t timeout)
- {
-     uint64_t end_time;
-     int blocked;
- 
-     if (!red_channel_client_blocked(rcc)) {
--        return;
-+        return TRUE;
-+    }
-+    if (timeout != -1) {
-+        end_time = red_now() + timeout;
-     }
--    end_time = red_now() + DETACH_TIMEOUT;
-     spice_info("blocked");
- 
-     do {
--        usleep(DETACH_SLEEP_DURATION);
-+        usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
-         red_channel_client_receive(rcc);
-         red_channel_client_send(rcc);
--    } while ((blocked = red_channel_client_blocked(rcc)) && red_now() < end_time);
-+    } while ((blocked = red_channel_client_blocked(rcc)) &&
-+             (timeout == -1 || red_now() < end_time));
- 
-     if (blocked) {
-         spice_warning("timeout");
--        // TODO - shutting down the socket but we still need to trigger
--        // disconnection. Right now we wait for main channel to error for that.
--        red_channel_client_shutdown(rcc);
-+        return FALSE;
-     } else {
-         spice_assert(red_channel_client_no_item_being_sent(rcc));
-+        return TRUE;
-     }
- }
- 
- /* TODO: more evil sync stuff. anything with the word wait in it's name. */
--void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
--                                            PipeItem *item)
-+int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
-+                                           PipeItem *item,
-+                                           int64_t timeout)
- {
-     uint64_t end_time;
-     int item_in_pipe;
- 
-     spice_info(NULL);
- 
--    end_time = red_now() + CHANNEL_PUSH_TIMEOUT;
-+    if (timeout != -1) {
-+        end_time = red_now() + timeout;
-+    }
- 
-     rcc->channel->channel_cbs.hold_item(rcc, item);
- 
-@@ -2237,55 +2239,52 @@ void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
-     }
-     red_channel_client_push(rcc);
- 
--    while((item_in_pipe = ring_item_is_linked(&item->link)) && (red_now() < end_time)) {
--        usleep(CHANNEL_PUSH_SLEEP_DURATION);
-+    while((item_in_pipe = ring_item_is_linked(&item->link)) &&
-+          (timeout == -1 || red_now() < end_time)) {
-+        usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
-         red_channel_client_receive(rcc);
-         red_channel_client_send(rcc);
-         red_channel_client_push(rcc);
-     }
- 
-+    red_channel_client_release_item(rcc, item, TRUE);
-     if (item_in_pipe) {
-         spice_warning("timeout");
--        red_channel_client_disconnect(rcc);
--    } else {
--        red_wait_outgoing_item(rcc);
--    }
--    red_channel_client_release_item(rcc, item, TRUE);
--}
--
--static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
--{
--    if (red_channel_client_blocked(rcc) || rcc->pipe_size > 0) {
--        red_channel_client_shutdown(rcc);
-+        return FALSE;
-     } else {
--        spice_assert(red_channel_client_no_item_being_sent(rcc));
-+        return red_channel_client_wait_outgoing_item(rcc,
-+                                                     timeout == -1 ? -1 : end_time - red_now());
-     }
- }
- 
--void red_channel_wait_all_sent(RedChannel *channel)
-+int red_channel_wait_all_sent(RedChannel *channel,
-+                              int64_t timeout)
- {
-     uint64_t end_time;
-     uint32_t max_pipe_size;
-     int blocked = FALSE;
- 
--    end_time = red_now() + DETACH_TIMEOUT;
-+    if (timeout != -1) {
-+        end_time = red_now() + timeout;
-+    }
- 
-     red_channel_push(channel);
-     while (((max_pipe_size = red_channel_max_pipe_size(channel)) ||
-            (blocked = red_channel_any_blocked(channel))) &&
--           red_now() < end_time) {
-+           (timeout == -1 || red_now() < end_time)) {
-         spice_debug("pipe-size %u blocked %d", max_pipe_size, blocked);
--        usleep(DETACH_SLEEP_DURATION);
-+        usleep(CHANNEL_BLOCKED_SLEEP_DURATION);
-         red_channel_receive(channel);
-         red_channel_send(channel);
-         red_channel_push(channel);
-     }
- 
-     if (max_pipe_size || blocked) {
--        spice_printerr("timeout: pending out messages exist (pipe-size %u, blocked %d)",
--                       max_pipe_size, blocked);
--        red_channel_apply_clients(channel, rcc_shutdown_if_pending_send);
-+        spice_warning("timeout: pending out messages exist (pipe-size %u, blocked %d)",
-+                      max_pipe_size, blocked);
-+        return FALSE;
-     } else {
-         spice_assert(red_channel_no_item_being_sent(channel));
-+        return TRUE;
-     }
- }
-diff --git a/server/red_channel.h b/server/red_channel.h
-index 9021b3f..fa11505 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -596,14 +596,20 @@ int red_client_during_migrate_at_target(RedClient *client);
- 
- void red_client_migrate(RedClient *client);
- 
--/* blocking function */
--void red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
--                                            PipeItem *item);
--
--/* blocking function */
--void red_wait_outgoing_item(RedChannelClient *rcc);
-+/*
-+ * blocking functions.
-+ *
-+ * timeout is in nano sec. -1 for no timeout.
-+ *
-+ * Return: TRUE if waiting succeeded. FALSE if timeout expired.
-+ */
- 
--/* blocking function */
--void red_channel_wait_all_sent(RedChannel *channel);
-+int red_channel_client_wait_pipe_item_sent(RedChannelClient *rcc,
-+                                           PipeItem *item,
-+                                           int64_t timeout);
-+int red_channel_client_wait_outgoing_item(RedChannelClient *rcc,
-+                                          int64_t timeout);
-+int red_channel_wait_all_sent(RedChannel *channel,
-+                              int64_t timeout);
- 
- #endif
-diff --git a/server/red_worker.c b/server/red_worker.c
-index f2c9220..31f3cbb 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -98,6 +98,7 @@
- #define CMD_RING_POLL_TIMEOUT 10 //milli
- #define CMD_RING_POLL_RETRIES 200
- 
-+#define DISPLAY_CLIENT_SHORT_TIMEOUT 15000000000ULL //nano
- #define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
- #define DISPLAY_CLIENT_MIGRATE_DATA_TIMEOUT 10000000000ULL //nano, 10 sec
- #define DISPLAY_CLIENT_RETRY_INTERVAL 10000 //micro
-@@ -2031,8 +2032,12 @@ static void red_current_clear(RedWorker *worker, int surface_id)
-     }
- }
- 
--static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id,
--                                                  int wait_if_used)
-+/*
-+ * Return: TRUE if wait_if_used == FALSE, or otherwise, if all of the pipe items that
-+ * are related to the surface have been cleared (or sent) from the pipe.
-+ */
-+static int red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int surface_id,
-+                                                 int wait_if_used)
- {
-     Ring *ring;
-     PipeItem *item;
-@@ -2040,7 +2045,7 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
-     RedChannelClient *rcc;
- 
-     if (!dcc) {
--        return;
-+        return TRUE;
-     }
- 
-     /* removing the newest drawables that their destination is surface_id and
-@@ -2085,24 +2090,27 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
-             if (wait_if_used) {
-                 break;
-             } else {
--                return;
-+                return TRUE;
-             }
-         }
-     }
- 
-     if (!wait_if_used) {
--        return;
-+        return TRUE;
-     }
- 
-     if (item) {
--        red_channel_client_wait_pipe_item_sent(&dcc->common.base, item);
-+        return red_channel_client_wait_pipe_item_sent(&dcc->common.base, item,
-+                                                      DISPLAY_CLIENT_TIMEOUT);
-     } else {
-         /*
-          * in case that the pipe didn't contain any item that is dependent on the surface, but
--         * there is one during sending.
-+         * there is one during sending. Use a shorter timeout, since it is just one item
-          */
--        red_wait_outgoing_item(&dcc->common.base);
-+        return red_channel_client_wait_outgoing_item(&dcc->common.base,
-+                                                     DISPLAY_CLIENT_SHORT_TIMEOUT);
-     }
-+    return TRUE;
- }
- 
- static void red_clear_surface_drawables_from_pipes(RedWorker *worker,
-@@ -2113,7 +2121,9 @@ static void red_clear_surface_drawables_from_pipes(RedWorker *worker,
-     DisplayChannelClient *dcc;
- 
-     WORKER_FOREACH_DCC_SAFE(worker, item, next, dcc) {
--        red_clear_surface_drawables_from_pipe(dcc, surface_id, wait_if_used);
-+        if (!red_clear_surface_drawables_from_pipe(dcc, surface_id, wait_if_used)) {
-+            red_channel_client_disconnect(&dcc->common.base);
-+        }
-     }
- }
- 
-@@ -11127,6 +11137,15 @@ void handle_dev_destroy_surface_wait(void *opaque, void *payload)
-     dev_destroy_surface_wait(worker, msg->surface_id);
- }
- 
-+static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
-+{
-+    if (red_channel_client_blocked(rcc) || rcc->pipe_size > 0) {
-+        red_channel_client_shutdown(rcc);
-+    } else {
-+        spice_assert(red_channel_client_no_item_being_sent(rcc));
-+    }
-+}
-+
- static inline void red_cursor_reset(RedWorker *worker)
- {
-     if (worker->cursor) {
-@@ -11144,7 +11163,11 @@ static inline void red_cursor_reset(RedWorker *worker)
-         if (!worker->cursor_channel->common.during_target_migrate) {
-             red_pipes_add_verb(&worker->cursor_channel->common.base, SPICE_MSG_CURSOR_RESET);
-         }
--        red_channel_wait_all_sent(&worker->cursor_channel->common.base);
-+        if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
-+                                       DISPLAY_CLIENT_TIMEOUT)) {
-+            red_channel_apply_clients(&worker->cursor_channel->common.base,
-+                                      rcc_shutdown_if_pending_send);
-+        }
-     }
- }
- 
-@@ -11427,8 +11450,16 @@ void handle_dev_stop(void *opaque, void *payload)
-      * purge the pipe, send destroy_all_surfaces
-      * to the client (there is no such message right now), and start
-      * from scratch on the destination side */
--    red_channel_wait_all_sent(&worker->display_channel->common.base);
--    red_channel_wait_all_sent(&worker->cursor_channel->common.base);
-+    if (!red_channel_wait_all_sent(&worker->display_channel->common.base,
-+                                   DISPLAY_CLIENT_TIMEOUT)) {
-+        red_channel_apply_clients(&worker->display_channel->common.base,
-+                                  rcc_shutdown_if_pending_send);
-+    }
-+    if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
-+                                   DISPLAY_CLIENT_TIMEOUT)) {
-+        red_channel_apply_clients(&worker->cursor_channel->common.base,
-+                                  rcc_shutdown_if_pending_send);
-+    }
- }
- 
- static int display_channel_wait_for_migrate_data(DisplayChannel *display)
diff --git a/SOURCES/0015-red_worker-disconnect-the-channel-instead-of-shutdow.patch b/SOURCES/0015-red_worker-disconnect-the-channel-instead-of-shutdow.patch
deleted file mode 100644
index adadd9e..0000000
--- a/SOURCES/0015-red_worker-disconnect-the-channel-instead-of-shutdow.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 11 Sep 2013 15:02:23 -0400
-Subject: [PATCH] red_worker: disconnect the channel instead of shutdown in
- case of a blocking method failure
-
-rhbz#1004443
-
-The methods that trigger waitings on the client pipe require that
-the waiting will succeed in order to continue, or otherwise, that
-all the living pipe items will be released (e.g., when
-we must destroy a surface, we need that all its related pipe items will
-be released). Shutdown of the socket will eventually trigger
-red_channel_client_disconnect (*), which will empty the pipe. However,
-if the blocking method failed, we need to empty the pipe synchronously.
-It is not safe(**) to call red_channel_client_disconnect from ChannelCbs
-, but all the blocking calls in red_worker are done from callbacks that
-are triggered from the device.
-To summarize, calling red_channel_client_disconnect instead of calling
-red_channel_client_shutdown will immediately release all the pipe items that are
-held by the channel client (by calling red_channel_client_pipe_clear).
-If red_clear_surface_drawables_from_pipe timeouts,
-red_channel_client_disconnect will make sure that the surface we wish to
-release is not referenced by any pipe-item.
-
-(*) After a shutdown of a socket, we expect that later, when
-red_peer_handle_incoming is called, it will encounter a socket
-error and will call the channel's on_error callback which calls
-red_channel_client_disconnect.
-
-(**) I believe it was not safe before commit 2d2121a17038bc0 (before adding ref
-count to ChannelClient). However, I think it might still be unsafe, because
-red_channel_client_disconnect sets rcc->stream to NULL, and rcc->stream
-may be referred later inside a red_channel_client method unsafely. So instead
-of checking if (stream != NULL) after calling callbacks, we try to avoid
-calling red_channel_client_disconnect from callbacks.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016795
-(cherry picked from commit 90a4761249f84421b27d67a85262b1423b24fe04)
----
- server/red_worker.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 31f3cbb..7a1c2d9 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -11137,10 +11137,10 @@ void handle_dev_destroy_surface_wait(void *opaque, void *payload)
-     dev_destroy_surface_wait(worker, msg->surface_id);
- }
- 
--static void rcc_shutdown_if_pending_send(RedChannelClient *rcc)
-+static void rcc_disconnect_if_pending_send(RedChannelClient *rcc)
- {
-     if (red_channel_client_blocked(rcc) || rcc->pipe_size > 0) {
--        red_channel_client_shutdown(rcc);
-+        red_channel_client_disconnect(rcc);
-     } else {
-         spice_assert(red_channel_client_no_item_being_sent(rcc));
-     }
-@@ -11166,7 +11166,7 @@ static inline void red_cursor_reset(RedWorker *worker)
-         if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
-                                        DISPLAY_CLIENT_TIMEOUT)) {
-             red_channel_apply_clients(&worker->cursor_channel->common.base,
--                                      rcc_shutdown_if_pending_send);
-+                                      rcc_disconnect_if_pending_send);
-         }
-     }
- }
-@@ -11453,12 +11453,12 @@ void handle_dev_stop(void *opaque, void *payload)
-     if (!red_channel_wait_all_sent(&worker->display_channel->common.base,
-                                    DISPLAY_CLIENT_TIMEOUT)) {
-         red_channel_apply_clients(&worker->display_channel->common.base,
--                                  rcc_shutdown_if_pending_send);
-+                                  rcc_disconnect_if_pending_send);
-     }
-     if (!red_channel_wait_all_sent(&worker->cursor_channel->common.base,
-                                    DISPLAY_CLIENT_TIMEOUT)) {
-         red_channel_apply_clients(&worker->cursor_channel->common.base,
--                                  rcc_shutdown_if_pending_send);
-+                                  rcc_disconnect_if_pending_send);
-     }
- }
- 
diff --git a/SOURCES/0016-spice_timer_queue-don-t-call-timers-repeatedly.patch b/SOURCES/0016-spice_timer_queue-don-t-call-timers-repeatedly.patch
deleted file mode 100644
index df997da..0000000
--- a/SOURCES/0016-spice_timer_queue-don-t-call-timers-repeatedly.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Tue, 13 Aug 2013 15:40:16 -0400
-Subject: [PATCH] spice_timer_queue: don't call timers repeatedly
-
-For channels that don't run as part of the main loop, we use
-spice_timer_queue, while for the other channels we use
-qemu timers support. The callbacks for setting timers are supplied to
-red_channel via SpiceCoreInterface, and their behavior should be
-consistent. qemu timers are called only once per each call to
-timer_start. This patch assigns the same behaviour to spice_timer_queue.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016790
-(cherry picked from commit c1c08c289883455f025836f14eda7bfd86442ed7)
----
- server/spice_timer_queue.c | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
-diff --git a/server/spice_timer_queue.c b/server/spice_timer_queue.c
-index 833ab1d..8f6e9c8 100644
---- a/server/spice_timer_queue.c
-+++ b/server/spice_timer_queue.c
-@@ -261,9 +261,7 @@ void spice_timer_queue_cb(void)
-             break;
-         } else {
-             timer->func(timer->opaque);
--            if (timer->is_active) {
--                _spice_timer_set(timer, timer->ms, now_ms);
--            }
-+            spice_timer_cancel(timer);
-         }
-     }
- }
diff --git a/SOURCES/0017-red_channel-add-on_input-callback-for-tracing-incomi.patch b/SOURCES/0017-red_channel-add-on_input-callback-for-tracing-incomi.patch
deleted file mode 100644
index 1906655..0000000
--- a/SOURCES/0017-red_channel-add-on_input-callback-for-tracing-incomi.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 14 Aug 2013 09:38:12 -0400
-Subject: [PATCH] red_channel: add on_input callback for tracing incoming bytes
-
-The callback will be used in the next patch.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016790
-(cherry picked from commit d1e7142a0f90e2b977d2a73d26dc5b09d7771826)
----
- server/red_channel.c | 7 +++++++
- server/red_channel.h | 2 ++
- 2 files changed, 9 insertions(+)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 228669b..bc6ac8d 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -244,6 +244,7 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
-                 handler->cb->on_error(handler->opaque);
-                 return;
-             }
-+            handler->cb->on_input(handler->opaque, bytes_read);
-             handler->header_pos += bytes_read;
- 
-             if (handler->header_pos != handler->header.header_size) {
-@@ -271,6 +272,7 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle
-                 handler->cb->on_error(handler->opaque);
-                 return;
-             }
-+            handler->cb->on_input(handler->opaque, bytes_read);
-             handler->msg_pos += bytes_read;
-             if (handler->msg_pos != msg_size) {
-                 return;
-@@ -383,6 +385,10 @@ static void red_channel_client_on_output(void *opaque, int n)
-     stat_inc_counter(rcc->channel->out_bytes_counter, n);
- }
- 
-+static void red_channel_client_on_input(void *opaque, int n)
-+{
-+}
-+
- static void red_channel_client_default_peer_on_error(RedChannelClient *rcc)
- {
-     red_channel_client_disconnect(rcc);
-@@ -919,6 +925,7 @@ RedChannel *red_channel_create(int size,
-     channel->incoming_cb.handle_message = (handle_message_proc)handle_message;
-     channel->incoming_cb.on_error =
-         (on_incoming_error_proc)red_channel_client_default_peer_on_error;
-+    channel->incoming_cb.on_input = red_channel_client_on_input;
-     channel->outgoing_cb.get_msg_size = red_channel_client_peer_get_out_msg_size;
-     channel->outgoing_cb.prepare = red_channel_client_peer_prepare_out_msg;
-     channel->outgoing_cb.on_block = red_channel_client_peer_on_out_block;
-diff --git a/server/red_channel.h b/server/red_channel.h
-index fa11505..64befff 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -74,6 +74,7 @@ typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, uint16_t type, uint32_
- typedef void (*release_msg_recv_buf_proc)(void *opaque,
-                                           uint16_t type, uint32_t size, uint8_t *msg);
- typedef void (*on_incoming_error_proc)(void *opaque);
-+typedef void (*on_input_proc)(void *opaque, int n);
- 
- typedef struct IncomingHandlerInterface {
-     handle_message_proc handle_message;
-@@ -83,6 +84,7 @@ typedef struct IncomingHandlerInterface {
-     // The following is an optional alternative to handle_message, used if not null
-     spice_parse_channel_func_t parser;
-     handle_parsed_proc handle_parsed;
-+    on_input_proc on_input;
- } IncomingHandlerInterface;
- 
- typedef struct IncomingHandler {
diff --git a/SOURCES/0018-red_channel-add-option-to-monitor-whether-a-channel-.patch b/SOURCES/0018-red_channel-add-option-to-monitor-whether-a-channel-.patch
deleted file mode 100644
index 77b2c62..0000000
--- a/SOURCES/0018-red_channel-add-option-to-monitor-whether-a-channel-.patch
+++ /dev/null
@@ -1,237 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 14 Aug 2013 10:10:37 -0400
-Subject: [PATCH] red_channel: add option to monitor whether a channel client
- is alive
-
-rhbz#994175
-
-When a client connection is closed surprisingly (i.e., without a FIN
-segment), we cannot identify it by a socket error (which is the only
-way by which we identified disconnections so far).
-This patch allows a channel client to periodically check the state of
-the connection and identify surprise disconnections.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016790
-(cherry picked from commit c8b808bb8211e756a5e2280da173010984b71680)
----
- server/red_channel.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++
- server/red_channel.h |  14 ++++++
- 2 files changed, 133 insertions(+)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index bc6ac8d..5df8f14 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -57,6 +57,13 @@ enum QosPingState {
-     PING_STATE_LATENCY,
- };
- 
-+enum ConnectivityState {
-+    CONNECTIVITY_STATE_CONNECTED,
-+    CONNECTIVITY_STATE_BLOCKED,
-+    CONNECTIVITY_STATE_WAIT_PONG,
-+    CONNECTIVITY_STATE_DISCONNECTED,
-+};
-+
- static void red_channel_client_start_ping_timer(RedChannelClient *rcc, uint32_t timeout);
- static void red_channel_client_cancel_ping_timer(RedChannelClient *rcc);
- static void red_channel_client_restart_ping_timer(RedChannelClient *rcc);
-@@ -66,6 +73,7 @@ static void red_client_add_channel(RedClient *client, RedChannelClient *rcc);
- static void red_client_remove_channel(RedChannelClient *rcc);
- static RedChannelClient *red_client_get_channel(RedClient *client, int type, int id);
- static void red_channel_client_restore_main_sender(RedChannelClient *rcc);
-+static inline int red_channel_client_waiting_for_ack(RedChannelClient *rcc);
- 
- /*
-  * Lifetime of RedChannel, RedChannelClient and RedClient:
-@@ -382,11 +390,19 @@ static void red_channel_client_on_output(void *opaque, int n)
- {
-     RedChannelClient *rcc = opaque;
- 
-+    if (rcc->connectivity_monitor.timer) {
-+        rcc->connectivity_monitor.out_bytes += n;
-+    }
-     stat_inc_counter(rcc->channel->out_bytes_counter, n);
- }
- 
- static void red_channel_client_on_input(void *opaque, int n)
- {
-+    RedChannelClient *rcc = opaque;
-+
-+    if (rcc->connectivity_monitor.timer) {
-+        rcc->connectivity_monitor.in_bytes += n;
-+    }
- }
- 
- static void red_channel_client_default_peer_on_error(RedChannelClient *rcc)
-@@ -743,6 +759,97 @@ static void red_channel_client_ping_timer(void *opaque)
-     }
- }
- 
-+/*
-+ * When a connection is not alive (and we can't detect it via a socket error), we
-+ * reach one of these 2 states:
-+ * (1) Sending msgs is blocked: either writes return EAGAIN
-+ *     or we are missing MSGC_ACK from the client.
-+ * (2) MSG_PING was sent without receiving a MSGC_PONG in reply.
-+ *
-+ * The connectivity_timer callback tests if the channel's state matches one of the above.
-+ * In case it does, on the next time the timer is called, it checks if the connection has
-+ * been idle during the time that passed since the previous timer call. If the connection
-+ * has been idle, we consider the client as disconnected.
-+ */
-+static void red_channel_client_connectivity_timer(void *opaque)
-+{
-+    RedChannelClient *rcc = opaque;
-+    RedChannelClientConnectivityMonitor *monitor = &rcc->connectivity_monitor;
-+    int is_alive = TRUE;
-+
-+    if (monitor->state == CONNECTIVITY_STATE_BLOCKED) {
-+        if (monitor->in_bytes == 0 && monitor->out_bytes == 0) {
-+            if (!rcc->send_data.blocked && !red_channel_client_waiting_for_ack(rcc)) {
-+                spice_error("mismatch between rcc-state and connectivity-state");
-+            }
-+            spice_debug("rcc is blocked; connection is idle");
-+            is_alive = FALSE;
-+        }
-+    } else if (monitor->state == CONNECTIVITY_STATE_WAIT_PONG) {
-+        if (monitor->in_bytes == 0) {
-+            if (rcc->latency_monitor.state != PING_STATE_WARMUP &&
-+                rcc->latency_monitor.state != PING_STATE_LATENCY) {
-+                spice_error("mismatch between rcc-state and connectivity-state");
-+            }
-+            spice_debug("rcc waits for pong; connection is idle");
-+            is_alive = FALSE;
-+        }
-+    }
-+
-+    if (is_alive) {
-+        monitor->in_bytes = 0;
-+        monitor->out_bytes = 0;
-+        if (rcc->send_data.blocked || red_channel_client_waiting_for_ack(rcc)) {
-+            monitor->state = CONNECTIVITY_STATE_BLOCKED;
-+        } else if (rcc->latency_monitor.state == PING_STATE_WARMUP ||
-+                   rcc->latency_monitor.state == PING_STATE_LATENCY) {
-+            monitor->state = CONNECTIVITY_STATE_WAIT_PONG;
-+        } else {
-+             monitor->state = CONNECTIVITY_STATE_CONNECTED;
-+        }
-+        rcc->channel->core->timer_start(rcc->connectivity_monitor.timer,
-+                                        rcc->connectivity_monitor.timeout);
-+    } else {
-+        monitor->state = CONNECTIVITY_STATE_DISCONNECTED;
-+        spice_debug("rcc %p has not been responsive for more than %u ms, disconnecting",
-+                    rcc, monitor->timeout);
-+        red_channel_client_disconnect(rcc);
-+    }
-+}
-+
-+void red_channel_client_start_connectivity_monitoring(RedChannelClient *rcc, uint32_t timeout_ms)
-+{
-+    if (!red_channel_client_is_connected(rcc)) {
-+        return;
-+    }
-+    spice_debug(NULL);
-+    spice_assert(timeout_ms > 0);
-+    /*
-+     * If latency_monitor is not active, we activate it in order to enable
-+     * periodic ping messages so that we will be be able to identify a disconnected
-+     * channel-client even if there are no ongoing channel specific messages
-+     * on this channel.
-+     */
-+    if (rcc->latency_monitor.timer == NULL) {
-+        rcc->latency_monitor.timer = rcc->channel->core->timer_add(
-+            red_channel_client_ping_timer, rcc);
-+        if (!rcc->client->during_target_migrate) {
-+            red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS);
-+        }
-+        rcc->latency_monitor.roundtrip = -1;
-+    }
-+    if (rcc->connectivity_monitor.timer == NULL) {
-+        rcc->connectivity_monitor.state = CONNECTIVITY_STATE_CONNECTED;
-+        rcc->connectivity_monitor.timer = rcc->channel->core->timer_add(
-+            red_channel_client_connectivity_timer, rcc);
-+        rcc->connectivity_monitor.timeout = timeout_ms;
-+        if (!rcc->client->during_target_migrate) {
-+           rcc->channel->core->timer_start(rcc->connectivity_monitor.timer,
-+                                           rcc->connectivity_monitor.timeout);
-+        }
-+    }
-+}
-+
- RedChannelClient *red_channel_client_create(int size, RedChannel *channel, RedClient  *client,
-                                             RedsStream *stream,
-                                             int monitor_latency,
-@@ -843,6 +950,10 @@ static void red_channel_client_seamless_migration_done(RedChannelClient *rcc)
-         if (rcc->latency_monitor.timer) {
-             red_channel_client_start_ping_timer(rcc, PING_TEST_IDLE_NET_TIMEOUT_MS);
-         }
-+        if (rcc->connectivity_monitor.timer) {
-+            rcc->channel->core->timer_start(rcc->connectivity_monitor.timer,
-+                                            rcc->connectivity_monitor.timeout);
-+        }
-     }
-     pthread_mutex_unlock(&rcc->client->lock);
- }
-@@ -889,6 +1000,10 @@ void red_channel_client_default_migrate(RedChannelClient *rcc)
-         rcc->channel->core->timer_remove(rcc->latency_monitor.timer);
-         rcc->latency_monitor.timer = NULL;
-     }
-+    if (rcc->connectivity_monitor.timer) {
-+       rcc->channel->core->timer_remove(rcc->connectivity_monitor.timer);
-+        rcc->connectivity_monitor.timer = NULL;
-+    }
-     red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_MIGRATE);
- }
- 
-@@ -1736,6 +1851,10 @@ void red_channel_client_disconnect(RedChannelClient *rcc)
-         rcc->channel->core->timer_remove(rcc->latency_monitor.timer);
-         rcc->latency_monitor.timer = NULL;
-     }
-+    if (rcc->connectivity_monitor.timer) {
-+        rcc->channel->core->timer_remove(rcc->connectivity_monitor.timer);
-+        rcc->connectivity_monitor.timer = NULL;
-+    }
-     red_channel_remove_client(rcc);
-     rcc->channel->channel_cbs.on_disconnect(rcc);
- }
-diff --git a/server/red_channel.h b/server/red_channel.h
-index 64befff..9e54dce 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -236,6 +236,14 @@ typedef struct RedChannelClientLatencyMonitor {
-     int64_t roundtrip;
- } RedChannelClientLatencyMonitor;
- 
-+typedef struct RedChannelClientConnectivityMonitor {
-+    int state;
-+    uint32_t out_bytes;
-+    uint32_t in_bytes;
-+    uint32_t timeout;
-+    SpiceTimer *timer;
-+} RedChannelClientConnectivityMonitor;
-+
- struct RedChannelClient {
-     RingItem channel_link;
-     RingItem client_link;
-@@ -289,6 +297,7 @@ struct RedChannelClient {
-     int wait_migrate_flush_mark;
- 
-     RedChannelClientLatencyMonitor latency_monitor;
-+    RedChannelClientConnectivityMonitor connectivity_monitor;
- };
- 
- struct RedChannel {
-@@ -448,6 +457,11 @@ SpiceMarshaller *red_channel_client_switch_to_urgent_sender(RedChannelClient *rc
- /* returns -1 if we don't have an estimation */
- int red_channel_client_get_roundtrip_ms(RedChannelClient *rcc);
- 
-+/*
-+ * Checks periodically if the connection is still alive
-+ */
-+void red_channel_client_start_connectivity_monitoring(RedChannelClient *rcc, uint32_t timeout_ms);
-+
- void red_channel_pipe_item_init(RedChannel *channel, PipeItem *item, int type);
- 
- // TODO: add back the channel_pipe_add functionality - by adding reference counting
diff --git a/SOURCES/0019-main_channel-monitoring-client-connection-status.patch b/SOURCES/0019-main_channel-monitoring-client-connection-status.patch
deleted file mode 100644
index 7f1b99c..0000000
--- a/SOURCES/0019-main_channel-monitoring-client-connection-status.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Yonit Halperin <yhalperi@redhat.com>
-Date: Wed, 14 Aug 2013 10:56:44 -0400
-Subject: [PATCH] main_channel: monitoring client connection status
-
-rhbz#994175
-
-Start monitoring if the client connection is alive after completing
-the bit-rate test.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1016790
-(cherry picked from commit ed1f70c6d16ff55adf73a08f063f5d7955f4c488)
----
- server/main_channel.c | 27 +++++++++++++++++++++------
- server/main_channel.h |  2 +-
- server/reds.c         |  3 +--
- 3 files changed, 23 insertions(+), 9 deletions(-)
-
-diff --git a/server/main_channel.c b/server/main_channel.c
-index fe032a6..54718ba 100644
---- a/server/main_channel.c
-+++ b/server/main_channel.c
-@@ -55,6 +55,8 @@
- 
- #define PING_INTERVAL (1000 * 10)
- 
-+#define CLIENT_CONNECTIVITY_TIMEOUT (30*1000) // 30 seconds
-+
- static uint8_t zero_page[ZERO_BUF_SIZE] = {0};
- 
- enum {
-@@ -201,16 +203,20 @@ RedClient *main_channel_get_client_by_link_id(MainChannel *main_chan, uint32_t c
- 
- static int main_channel_client_push_ping(MainChannelClient *mcc, int size);
- 
--void main_channel_client_start_net_test(MainChannelClient *mcc)
-+void main_channel_client_start_net_test(MainChannelClient *mcc, int test_rate)
- {
-     if (!mcc || mcc->net_test_id) {
-         return;
-     }
--    if (main_channel_client_push_ping(mcc, NET_TEST_WARMUP_BYTES)
--        && main_channel_client_push_ping(mcc, 0)
--        && main_channel_client_push_ping(mcc, NET_TEST_BYTES)) {
--        mcc->net_test_id = mcc->ping_id - 2;
--        mcc->net_test_stage = NET_TEST_STAGE_WARMUP;
-+    if (test_rate) {
-+        if (main_channel_client_push_ping(mcc, NET_TEST_WARMUP_BYTES)
-+            && main_channel_client_push_ping(mcc, 0)
-+            && main_channel_client_push_ping(mcc, NET_TEST_BYTES)) {
-+            mcc->net_test_id = mcc->ping_id - 2;
-+            mcc->net_test_stage = NET_TEST_STAGE_WARMUP;
-+        }
-+    } else {
-+        red_channel_client_start_connectivity_monitoring(&mcc->base, CLIENT_CONNECTIVITY_TIMEOUT);
-     }
- }
- 
-@@ -970,6 +976,8 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
-                     spice_printerr("net test: invalid values, latency %" PRIu64
-                                " roundtrip %" PRIu64 ". assuming high"
-                                "bandwidth", mcc->latency, roundtrip);
-+                    red_channel_client_start_connectivity_monitoring(&mcc->base,
-+                                                                     CLIENT_CONNECTIVITY_TIMEOUT);
-                     break;
-                 }
-                 mcc->bitrate_per_sec = (uint64_t)(NET_TEST_BYTES * 8) * 1000000
-@@ -980,6 +988,8 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
-                            mcc->bitrate_per_sec,
-                            (double)mcc->bitrate_per_sec / 1024 / 1024,
-                            main_channel_client_is_low_bandwidth(mcc) ? " LOW BANDWIDTH" : "");
-+                red_channel_client_start_connectivity_monitoring(&mcc->base,
-+                                                                 CLIENT_CONNECTIVITY_TIMEOUT);
-                 break;
-             default:
-                 spice_printerr("invalid net test stage, ping id %d test id %d stage %d",
-@@ -989,6 +999,11 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint
-                 mcc->net_test_stage = NET_TEST_STAGE_INVALID;
-             }
-             break;
-+        } else {
-+            /*
-+             * channel client monitors the connectivity using ping-pong messages
-+             */
-+            red_channel_client_handle_message(rcc, size, type, message);
-         }
- #ifdef RED_STATISTICS
-         reds_update_stat_value(roundtrip);
-diff --git a/server/main_channel.h b/server/main_channel.h
-index 27367a4..29eb8d4 100644
---- a/server/main_channel.h
-+++ b/server/main_channel.h
-@@ -54,7 +54,7 @@ void main_channel_push_agent_disconnected(MainChannel *main_chan);
- void main_channel_client_push_agent_tokens(MainChannelClient *mcc, uint32_t num_tokens);
- void main_channel_client_push_agent_data(MainChannelClient *mcc, uint8_t* data, size_t len,
-                                          spice_marshaller_item_free_func free_data, void *opaque);
--void main_channel_client_start_net_test(MainChannelClient *mcc);
-+void main_channel_client_start_net_test(MainChannelClient *mcc, int test_rate);
- // TODO: huge. Consider making a reds_* interface for these functions
- // and calling from main.
- void main_channel_push_init(MainChannelClient *mcc, int display_channels_hint,
-diff --git a/server/reds.c b/server/reds.c
-index f9f185d..7b7f262 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1718,11 +1718,10 @@ static void reds_handle_main_link(RedLinkInfo *link)
-             main_channel_push_name(mcc, spice_name);
-         if (spice_uuid_is_set)
-             main_channel_push_uuid(mcc, spice_uuid);
--
--        main_channel_client_start_net_test(mcc);
-     } else {
-         reds_mig_target_client_add(client);
-     }
-+    main_channel_client_start_net_test(mcc, !mig_target);
- }
- 
- #define RED_MOUSE_STATE_TO_LOCAL(state)     \
diff --git a/SOURCES/0020-Fix-crash-when-clearing-surface-memory.patch b/SOURCES/0020-Fix-crash-when-clearing-surface-memory.patch
deleted file mode 100644
index 46e831d..0000000
--- a/SOURCES/0020-Fix-crash-when-clearing-surface-memory.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Wed, 6 Aug 2014 18:34:56 +0200
-Subject: [PATCH] Fix crash when clearing surface memory
-
-The beginning of the surface data needs to be computed correctly if the
-stride is negative, otherwise, it should point already to the beginning
-of the surface data. This bug seems to exists since 4a208b (0.5.2)
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1029646
----
- server/red_worker.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 7a1c2d9..d7962c5 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -9654,7 +9654,11 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id, ui
-     surface->context.stride = stride;
-     surface->context.line_0 = line_0;
-     if (!data_is_valid) {
--        memset((char *)line_0 + (int32_t)(stride * (height - 1)), 0, height*abs(stride));
-+        char *data = line_0;
-+        if (stride < 0) {
-+            data -= abs(stride) * (height - 1);
-+        }
-+        memset(data, 0, height*abs(stride));
-     }
-     surface->create.info = NULL;
-     surface->destroy.info = NULL;
diff --git a/SOURCES/0021-Fix-assert-in-mjpeg_encoder_adjust_params_to_bit_rat.patch b/SOURCES/0021-Fix-assert-in-mjpeg_encoder_adjust_params_to_bit_rat.patch
deleted file mode 100644
index 1fc1729..0000000
--- a/SOURCES/0021-Fix-assert-in-mjpeg_encoder_adjust_params_to_bit_rat.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jonathon Jongsma <jjongsma@redhat.com>
-Date: Fri, 30 May 2014 13:45:02 -0500
-Subject: [PATCH] Fix assert in mjpeg_encoder_adjust_params_to_bit_rate()
-
-If mjpeg_encoder_reset_quality() is called with the same quality as currently
-set, it will not reset last_enc_size but not reset num_recent_enc_frames,
-violating some assumptions in _adjust_params_to_bit_rate(). To avoid aborting
-the server, simply return early from this function.
-
-Resolves: rhbz#1070028
-(cherry picked from commit 284cca2a5ebc98257275585083321a7100fb89b3)
----
- server/mjpeg_encoder.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
-index 04b244e..223fe64 100644
---- a/server/mjpeg_encoder.c
-+++ b/server/mjpeg_encoder.c
-@@ -624,7 +624,10 @@ static void mjpeg_encoder_adjust_params_to_bit_rate(MJpegEncoder *encoder)
-         return;
-     }
- 
--    spice_assert(rate_control->num_recent_enc_frames);
-+    if (!rate_control->num_recent_enc_frames) {
-+        spice_debug("No recent encoded frames");
-+        return;
-+    }
- 
-     if (rate_control->num_recent_enc_frames < MJPEG_AVERAGE_SIZE_WINDOW &&
-         rate_control->num_recent_enc_frames < rate_control->fps) {
diff --git a/SOURCES/0022-reds-lookup-corresponding-channel-id.patch b/SOURCES/0022-reds-lookup-corresponding-channel-id.patch
deleted file mode 100644
index 723acbe..0000000
--- a/SOURCES/0022-reds-lookup-corresponding-channel-id.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Mon, 18 Nov 2013 11:28:25 +0100
-Subject: [PATCH] reds: lookup corresponding channel id
-
-In reds_send_link_ack(), lookup the channel with the same id as the link
-message.
-
-The bug was found during code review a while ago.
-
-A reproducer bug was later reported:
-https://bugzilla.redhat.com/show_bug.cgi?id=1058625
-
-(cherry picked from commit a434543eb1243db1e52ca6a4e0cdfb425c277e56)
----
- server/reds.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 7b7f262..464552a 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1459,7 +1459,8 @@ static int reds_send_link_ack(RedLinkInfo *link)
- 
-     ack.error = SPICE_LINK_ERR_OK;
- 
--    channel = reds_find_channel(link->link_mess->channel_type, 0);
-+    channel = reds_find_channel(link->link_mess->channel_type,
-+                                link->link_mess->channel_id);
-     if (!channel) {
-         spice_assert(link->link_mess->channel_type == SPICE_CHANNEL_MAIN);
-         spice_assert(reds->main_channel);
diff --git a/SOURCES/0023-dispatcher-lower-a-monitor-config-warning-to-a-debug.patch b/SOURCES/0023-dispatcher-lower-a-monitor-config-warning-to-a-debug.patch
deleted file mode 100644
index 39f7288..0000000
--- a/SOURCES/0023-dispatcher-lower-a-monitor-config-warning-to-a-debug.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Fri, 29 Aug 2014 13:14:08 +0200
-Subject: [PATCH] dispatcher: lower a monitor-config warning to a debug level
-
-Some QXLInterface implementations might not have or succeed
-with client_monitors_config(). Thus, lower warning to debug
-level.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1119220
-(cherry picked from commit 5972452b287a7b1831411595896e69db2ea991ac)
----
- server/red_dispatcher.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
-index ef47c28..2ebde63 100644
---- a/server/red_dispatcher.c
-+++ b/server/red_dispatcher.c
-@@ -330,8 +330,8 @@ void red_dispatcher_client_monitors_config(VDAgentMonitorsConfig *monitors_confi
-         if (!now->qxl->st->qif->client_monitors_config ||
-             !now->qxl->st->qif->client_monitors_config(now->qxl,
-                                                        monitors_config)) {
--            spice_warning("spice bug: QXLInterface::client_monitors_config"
--                          " failed/missing unexpectedly\n");
-+            /* this is a normal condition, some qemu devices might not implement it */
-+            spice_debug("QXLInterface::client_monitors_config failed\n");
-         }
-         now = now->next;
-     }
diff --git a/SOURCES/0024-mjpeg-Don-t-warn-on-unsupported-image-formats.patch b/SOURCES/0024-mjpeg-Don-t-warn-on-unsupported-image-formats.patch
deleted file mode 100644
index e77bf6e..0000000
--- a/SOURCES/0024-mjpeg-Don-t-warn-on-unsupported-image-formats.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Wed, 26 Feb 2014 15:40:55 +0100
-Subject: [PATCH] mjpeg: Don't warn on unsupported image formats
-
-When trying to start mjpeg compression mode, mjpeg_encoder_start_frame()
-tests the image format as its only able to compress 24/32bpp images. On
-images with lower bit depths, we return MJPEG_ENCODER_FRAME_UNSUPPORTED to
-indicate this is not a format we can compress. However, this return goes
-with a spice_warning("unsupported format"). As the rest of the code can
-cope with this unsupported format by not doing mjpeg compression, it's
-nicer to downgrade this spice_warning() to spice_debug().
-
-This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1070028
-
-(cherry picked from commit 67be56ad8a6b10a5307939a700115d6be3fb8433)
----
- server/mjpeg_encoder.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/mjpeg_encoder.c b/server/mjpeg_encoder.c
-index 223fe64..ea9f3af 100644
---- a/server/mjpeg_encoder.c
-+++ b/server/mjpeg_encoder.c
-@@ -799,7 +799,7 @@ int mjpeg_encoder_start_frame(MJpegEncoder *encoder, SpiceBitmapFmt format,
- #endif
-         break;
-     default:
--        spice_warning("unsupported format %d", format);
-+        spice_debug("unsupported format %d", format);
-         return MJPEG_ENCODER_FRAME_UNSUPPORTED;
-     }
- 
diff --git a/SOURCES/0025-server-Don-t-dump-the-bitmap-when-the-format-is-inva.patch b/SOURCES/0025-server-Don-t-dump-the-bitmap-when-the-format-is-inva.patch
deleted file mode 100644
index e3ee4f5..0000000
--- a/SOURCES/0025-server-Don-t-dump-the-bitmap-when-the-format-is-inva.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 00:38:36 +0200
-Subject: [PATCH] server: Don't dump the bitmap when the format is invalid
-
-Caught by covscan:
-spice/server/spice_bitmap_utils.c:54: var_decl: Declaring variable "n_pixel_bits" without initializer.
-spice/server/spice_bitmap_utils.c:106: uninit_use: Using uninitialized value "n_pixel_bits".
-
-Resolves: rhbz#885717
-(cherry picked from commit 94edda22553ba351c869b58cd984a79cfc6c2180)
----
- server/red_worker.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index d7962c5..945f4f1 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -12296,6 +12296,7 @@ static void dump_bitmap(RedWorker *worker, SpiceBitmap *bitmap, uint32_t group_i
-         break;
-     default:
-         spice_error("invalid bitmap format  %u", bitmap->format);
-+        return;
-     }
- 
-     if (!rgb) {
diff --git a/SOURCES/0026-Fix-Wunused-parameter.patch b/SOURCES/0026-Fix-Wunused-parameter.patch
deleted file mode 100644
index 0cb1219..0000000
--- a/SOURCES/0026-Fix-Wunused-parameter.patch
+++ /dev/null
@@ -1,327 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:24:55 +0200
-Subject: [PATCH] Fix -Wunused-parameter
-
-(cherry picked from commit 5ea7de3bccafa21963548abcb5b7061de4c59910)
----
- server/tests/test_display_base.c               | 37 +++++++++++++++++---------
- server/tests/test_display_base.h               |  1 +
- server/tests/test_display_no_ssl.c             |  2 +-
- server/tests/test_display_resolution_changes.c |  3 ++-
- server/tests/test_display_width_stride.c       |  9 ++++---
- server/tests/test_empty_success.c              | 24 +++++++++++------
- server/tests/test_playback.c                   |  2 +-
- server/tests/test_vdagent.c                    | 13 ++++++---
- 8 files changed, 60 insertions(+), 31 deletions(-)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index 20c0e47..602691b 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -64,7 +64,7 @@ static int rects = 16; //number of rects that will be draw
- static int has_automated_tests = 0; //automated test flag
- 
- __attribute__((noreturn))
--static void sigchld_handler(int signal_num) // wait for the child process and exit
-+static void sigchld_handler(SPICE_GNUC_UNUSED int signal_num) // wait for the child process and exit
- {
-     int status;
-     wait(&status);
-@@ -412,19 +412,22 @@ static void attache_worker(QXLInstance *qin, QXLWorker *_qxl_worker)
-     test->qxl_worker->start(test->qxl_worker);
- }
- 
--static void set_compression_level(QXLInstance *qin, int level)
-+static void set_compression_level(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                                  SPICE_GNUC_UNUSED int level)
- {
-     printf("%s\n", __func__);
- }
- 
--static void set_mm_time(QXLInstance *qin, uint32_t mm_time)
-+static void set_mm_time(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                        SPICE_GNUC_UNUSED uint32_t mm_time)
- {
- }
- 
- // we now have a secondary surface
- #define MAX_SURFACE_NUM 2
- 
--static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
-+static void get_init_info(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                          QXLDevInitInfo *info)
- {
-     memset(info, 0, sizeof(*info));
-     info->num_memslots = 1;
-@@ -467,7 +470,8 @@ static int get_num_commands(void)
- }
- 
- // called from spice_server thread (i.e. red_worker thread)
--static int get_command(QXLInstance *qin, struct QXLCommandExt *ext)
-+static int get_command(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                       struct QXLCommandExt *ext)
- {
-     if (get_num_commands() == 0) {
-         return FALSE;
-@@ -617,7 +621,8 @@ static void do_wakeup(void *opaque)
-     test->qxl_worker->wakeup(test->qxl_worker);
- }
- 
--static void release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_info)
-+static void release_resource(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                             struct QXLReleaseInfoExt release_info)
- {
-     QXLCommandExt *ext = (QXLCommandExt*)(unsigned long)release_info.info->id;
-     //printf("%s\n", __func__);
-@@ -713,24 +718,25 @@ static int get_cursor_command(QXLInstance *qin, struct QXLCommandExt *ext)
-     return TRUE;
- }
- 
--static int req_cursor_notification(QXLInstance *qin)
-+static int req_cursor_notification(SPICE_GNUC_UNUSED QXLInstance *qin)
- {
-     printf("%s\n", __func__);
-     return TRUE;
- }
- 
--static void notify_update(QXLInstance *qin, uint32_t update_id)
-+static void notify_update(SPICE_GNUC_UNUSED QXLInstance *qin,
-+                          SPICE_GNUC_UNUSED uint32_t update_id)
- {
-     printf("%s\n", __func__);
- }
- 
--static int flush_resources(QXLInstance *qin)
-+static int flush_resources(SPICE_GNUC_UNUSED QXLInstance *qin)
- {
-     printf("%s\n", __func__);
-     return TRUE;
- }
- 
--static int client_monitors_config(QXLInstance *qin,
-+static int client_monitors_config(SPICE_GNUC_UNUSED QXLInstance *qin,
-                                   VDAgentMonitorsConfig *monitors_config)
- {
-     if (!monitors_config) {
-@@ -786,19 +792,24 @@ void test_add_display_interface(Test* test)
-     spice_server_add_interface(test->server, &test->qxl_instance.base);
- }
- 
--static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-+static int vmc_write(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                     SPICE_GNUC_UNUSED const uint8_t *buf,
-+                     int len)
- {
-     printf("%s: %d\n", __func__, len);
-     return len;
- }
- 
--static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-+static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                    SPICE_GNUC_UNUSED uint8_t *buf,
-+                    int len)
- {
-     printf("%s: %d\n", __func__, len);
-     return 0;
- }
- 
--static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
-+static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                      int connected)
- {
-     printf("%s: %d\n", __func__, connected);
- }
-diff --git a/server/tests/test_display_base.h b/server/tests/test_display_base.h
-index d2823a7..0a58186 100644
---- a/server/tests/test_display_base.h
-+++ b/server/tests/test_display_base.h
-@@ -2,6 +2,7 @@
- #define __TEST_DISPLAY_BASE_H__
- 
- #include <spice.h>
-+#include <spice/macros.h>
- #include "basic_event_loop.h"
- 
- #define COUNT(x) ((sizeof(x)/sizeof(x[0])))
-diff --git a/server/tests/test_display_no_ssl.c b/server/tests/test_display_no_ssl.c
-index 83ab3dc..89b4796 100644
---- a/server/tests/test_display_no_ssl.c
-+++ b/server/tests/test_display_no_ssl.c
-@@ -17,7 +17,7 @@ void show_channels(SpiceServer *server);
- 
- int ping_ms = 100;
- 
--void pinger(void *opaque)
-+void pinger(SPICE_GNUC_UNUSED void *opaque)
- {
-     // show_channels is not thread safe - fails if disconnections / connections occur
-     //show_channels(server);
-diff --git a/server/tests/test_display_resolution_changes.c b/server/tests/test_display_resolution_changes.c
-index 4767ea9..c492653 100644
---- a/server/tests/test_display_resolution_changes.c
-+++ b/server/tests/test_display_resolution_changes.c
-@@ -22,7 +22,8 @@ void pinger(void *opaque)
-     test->core->timer_start(ping_timer, ping_ms);
- }
- 
--void set_primary_params(Test *test, Command *command)
-+void set_primary_params(SPICE_GNUC_UNUSED Test *test,
-+                        Command *command)
- {
- #if 0
-     static int toggle = 0;
-diff --git a/server/tests/test_display_width_stride.c b/server/tests/test_display_width_stride.c
-index f938373..a071e74 100644
---- a/server/tests/test_display_width_stride.c
-+++ b/server/tests/test_display_width_stride.c
-@@ -25,7 +25,8 @@ void pinger(void *opaque)
- static int g_surface_id = 1;
- static uint8_t *g_surface_data;
- 
--void set_draw_parameters(Test *test, Command *command)
-+void set_draw_parameters(SPICE_GNUC_UNUSED Test *test,
-+                         Command *command)
- {
-     static int count = 17;
-     CommandDrawSolid *solid = &command->solid;
-@@ -38,7 +39,8 @@ void set_draw_parameters(Test *test, Command *command)
-     count++;
- }
- 
--void set_surface_params(Test *test, Command *command)
-+void set_surface_params(SPICE_GNUC_UNUSED Test *test,
-+                        Command *command)
- {
-     CommandCreateSurface *create = &command->create_surface;
- 
-@@ -54,7 +56,8 @@ void set_surface_params(Test *test, Command *command)
-     create->data = g_surface_data;
- }
- 
--void set_destroy_parameters(Test *test, Command *command)
-+void set_destroy_parameters(SPICE_GNUC_UNUSED Test *test,
-+                            SPICE_GNUC_UNUSED Command *command)
- {
-     if (g_surface_data) {
-         free(g_surface_data);
-diff --git a/server/tests/test_empty_success.c b/server/tests/test_empty_success.c
-index 0176a52..6a3bb55 100644
---- a/server/tests/test_empty_success.c
-+++ b/server/tests/test_empty_success.c
-@@ -3,44 +3,52 @@
- #include <string.h>
- 
- #include <spice.h>
-+#include <spice/macros.h>
- 
- struct SpiceTimer {
-     int a,b;
- };
- 
--SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque)
-+SpiceTimer* timer_add(SPICE_GNUC_UNUSED SpiceTimerFunc func,
-+                      SPICE_GNUC_UNUSED void *opaque)
- {
-     static struct SpiceTimer t = {0,};
- 
-     return &t;
- }
- 
--void timer_start(SpiceTimer *timer, uint32_t ms)
-+void timer_start(SPICE_GNUC_UNUSED SpiceTimer *timer,
-+                 SPICE_GNUC_UNUSED uint32_t ms)
- {
- }
- 
--void timer_cancel(SpiceTimer *timer)
-+void timer_cancel(SPICE_GNUC_UNUSED SpiceTimer *timer)
- {
- }
- 
--void timer_remove(SpiceTimer *timer)
-+void timer_remove(SPICE_GNUC_UNUSED SpiceTimer *timer)
- {
- }
- 
--SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
-+SpiceWatch *watch_add(SPICE_GNUC_UNUSED int fd,
-+                      SPICE_GNUC_UNUSED int event_mask,
-+                      SPICE_GNUC_UNUSED SpiceWatchFunc func,
-+                      SPICE_GNUC_UNUSED void *opaque)
- {
-     return NULL;
- }
- 
--void watch_update_mask(SpiceWatch *watch, int event_mask)
-+void watch_update_mask(SPICE_GNUC_UNUSED SpiceWatch *watch,
-+                       SPICE_GNUC_UNUSED int event_mask)
- {
- }
- 
--void watch_remove(SpiceWatch *watch)
-+void watch_remove(SPICE_GNUC_UNUSED SpiceWatch *watch)
- {
- }
- 
--void channel_event(int event, SpiceChannelEventInfo *info)
-+void channel_event(SPICE_GNUC_UNUSED int event,
-+                   SPICE_GNUC_UNUSED SpiceChannelEventInfo *info)
- {
- }
- 
-diff --git a/server/tests/test_playback.c b/server/tests/test_playback.c
-index ed1b766..1e82c43 100644
---- a/server/tests/test_playback.c
-+++ b/server/tests/test_playback.c
-@@ -45,7 +45,7 @@ static void get_frame(void)
-                         : 100;
- }
- 
--void playback_timer_cb(void *opaque)
-+void playback_timer_cb(SPICE_GNUC_UNUSED void *opaque)
- {
-     static int t = 0;
-     static uint64_t last_sent_usec = 0;
-diff --git a/server/tests/test_vdagent.c b/server/tests/test_vdagent.c
-index af33145..7a56c2a 100644
---- a/server/tests/test_vdagent.c
-+++ b/server/tests/test_vdagent.c
-@@ -20,7 +20,7 @@ int ping_ms = 100;
- #define MIN(a, b) ((a) > (b) ? (b) : (a))
- #endif
- 
--void pinger(void *opaque)
-+void pinger(SPICE_GNUC_UNUSED void *opaque)
- {
-     // show_channels is not thread safe - fails if disconnections / connections occur
-     //show_channels(server);
-@@ -29,12 +29,16 @@ void pinger(void *opaque)
- }
- 
- 
--static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-+static int vmc_write(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                     SPICE_GNUC_UNUSED const uint8_t *buf,
-+                     int len)
- {
-     return len;
- }
- 
--static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-+static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                    uint8_t *buf,
-+                    int len)
- {
-     static uint8_t c = 0;
-     static uint8_t message[2048];
-@@ -70,7 +74,8 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-     return ret;
- }
- 
--static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
-+static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-+                      SPICE_GNUC_UNUSED int connected)
- {
- }
- 
diff --git a/SOURCES/0027-Fix-Wunused-value.patch b/SOURCES/0027-Fix-Wunused-value.patch
deleted file mode 100644
index 5298f6b..0000000
--- a/SOURCES/0027-Fix-Wunused-value.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:34:42 +0200
-Subject: [PATCH] Fix -Wunused-value
-
-(cherry picked from commit 79e5a52d0553b07c0e8ca5a894c5d371a07a8964)
----
- server/tests/test_display_streaming.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/tests/test_display_streaming.c b/server/tests/test_display_streaming.c
-index b66d870..b8bdf52 100644
---- a/server/tests/test_display_streaming.c
-+++ b/server/tests/test_display_streaming.c
-@@ -103,7 +103,7 @@ static void create_clipped_frame(Test *test, Command *command, int clipping_fact
-     cmd->bitmap = malloc(width*height*4);
-     memset(cmd->bitmap, 0xff, width*height*4);
-     dst = (uint32_t *)(cmd->bitmap + cur_line*width*4);
--    for (cur_line; cur_line < end_line; cur_line++) {
-+    for (; cur_line < end_line; cur_line++) {
-         int col;
-         for (col = 0; col < width; col++, dst++) {
-             *dst = 0x00FF00;
diff --git a/SOURCES/0028-Fix-Wsign.patch b/SOURCES/0028-Fix-Wsign.patch
deleted file mode 100644
index 0321ae5..0000000
--- a/SOURCES/0028-Fix-Wsign.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:42:48 +0200
-Subject: [PATCH] Fix -Wsign
-
-(cherry picked from commit 08b3e1d8f187fb371d9ade2f69670378e3e409f5)
----
- server/tests/test_display_base.c | 4 ++--
- server/tests/test_playback.c     | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index 602691b..6765a07 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -215,7 +215,7 @@ static SimpleSpiceUpdate *test_spice_create_update_solid(uint32_t surface_id, QX
-     uint32_t *dst;
-     uint32_t bw;
-     uint32_t bh;
--    int i;
-+    uint32_t i;
- 
-     bw = bbox.right - bbox.left;
-     bh = bbox.bottom - bbox.top;
-@@ -451,7 +451,7 @@ struct QXLCommandExt* commands[1024];
- 
- static void push_command(QXLCommandExt *ext)
- {
--    ASSERT(commands_end - commands_start < COMMANDS_SIZE);
-+    ASSERT(commands_end - commands_start < (int) COMMANDS_SIZE);
-     commands[commands_end % COMMANDS_SIZE] = ext;
-     commands_end++;
- }
-diff --git a/server/tests/test_playback.c b/server/tests/test_playback.c
-index 1e82c43..f712f7b 100644
---- a/server/tests/test_playback.c
-+++ b/server/tests/test_playback.c
-@@ -50,7 +50,7 @@ void playback_timer_cb(SPICE_GNUC_UNUSED void *opaque)
-     static int t = 0;
-     static uint64_t last_sent_usec = 0;
-     static uint64_t samples_to_send;
--    int i;
-+    uint32_t i;
-     struct timeval cur;
-     uint64_t cur_usec;
-     uint32_t *test_frame;
diff --git a/SOURCES/0029-Fix-Wswitch.patch b/SOURCES/0029-Fix-Wswitch.patch
deleted file mode 100644
index 1923558..0000000
--- a/SOURCES/0029-Fix-Wswitch.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:45:49 +0200
-Subject: [PATCH] Fix -Wswitch
-
-(cherry picked from commit 4bf5fd35c4ece8a9100e5cec18b4b75fbaf82d35)
----
- server/tests/test_display_base.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index 6765a07..1125b56 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -552,6 +552,8 @@ static void produce_command(Test *test)
-                 update = test_spice_create_update_solid(command->solid.surface_id,
-                         command->solid.bbox, command->solid.color);
-                 break;
-+            default: /* Just to shut up GCC warning (-Wswitch) */
-+                break;
-             }
-             push_command(&update->ext);
-             break;
diff --git a/SOURCES/0030-Fix-Wformat.patch b/SOURCES/0030-Fix-Wformat.patch
deleted file mode 100644
index fa19f08..0000000
--- a/SOURCES/0030-Fix-Wformat.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:52:16 +0200
-Subject: [PATCH] Fix -Wformat
-
-(cherry picked from commit 63180f6ce3266d3b9b6c7319a0aec1f0d4ee7fe3)
----
- server/tests/basic_event_loop.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/tests/basic_event_loop.c b/server/tests/basic_event_loop.c
-index c6f6698..79a4523 100644
---- a/server/tests/basic_event_loop.c
-+++ b/server/tests/basic_event_loop.c
-@@ -115,7 +115,7 @@ static void watch_remove(SpiceWatch *watch)
- 
- static void channel_event(int event, SpiceChannelEventInfo *info)
- {
--    DPRINTF(0, "channel event con, type, id, event: %ld, %d, %d, %d",
-+    DPRINTF(0, "channel event con, type, id, event: %d, %d, %d, %d",
-             info->connection_id, info->type, info->id, event);
- }
- 
diff --git a/SOURCES/0031-Fix-Wnonnull.patch b/SOURCES/0031-Fix-Wnonnull.patch
deleted file mode 100644
index 3ed5ae3..0000000
--- a/SOURCES/0031-Fix-Wnonnull.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 13:55:56 +0200
-Subject: [PATCH] Fix -Wnonnull
-
-(cherry picked from commit fb938c210ac507acb747c4c5126db7e6b12889fa)
----
- server/tests/test_display_base.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index 1125b56..01eaf9f 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -88,10 +88,11 @@ static void regression_test(void)
-     pid = fork();
-     if (pid == 0) {
-         char buf[PATH_MAX];
-+        char *argv[] = { NULL };
-         char *envp[] = {buf, NULL};
- 
-         snprintf(buf, sizeof(buf), "PATH=%s", getenv("PATH"));
--        execve("regression_test.py", NULL, envp);
-+        execve("regression_test.py", argv, envp);
-     } else if (pid > 0) {
-         return;
-     }
diff --git a/SOURCES/0032-Fix-Wmissing-field-initializers.patch b/SOURCES/0032-Fix-Wmissing-field-initializers.patch
deleted file mode 100644
index d96b117..0000000
--- a/SOURCES/0032-Fix-Wmissing-field-initializers.patch
+++ /dev/null
@@ -1,155 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 14:19:52 +0200
-Subject: [PATCH] Fix -Wmissing-field-initializers
-
-(cherry picked from commit b76e561d82796bd2bccc57be962fc5fba0141da6)
----
- server/tests/test_display_base.c               | 15 ++++++---------
- server/tests/test_display_resolution_changes.c |  4 ++--
- server/tests/test_display_width_stride.c       | 22 +++++++++++-----------
- server/tests/test_playback.c                   | 12 ++++++------
- server/tests/test_vdagent.c                    | 15 ++++++---------
- 5 files changed, 31 insertions(+), 37 deletions(-)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index 01eaf9f..bfe9991 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -817,19 +817,16 @@ static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
-     printf("%s: %d\n", __func__, connected);
- }
- 
--static SpiceCharDeviceInterface vdagent_sif = {
--    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
--    .base.description   = "test spice virtual channel char device",
--    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
--    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
--    .state              = vmc_state,
--    .write              = vmc_write,
--    .read               = vmc_read,
-+static SpiceBaseInterface base = {
-+    .type          = SPICE_INTERFACE_CHAR_DEVICE,
-+    .description   = "test spice virtual channel char device",
-+    .major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
-+    .minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
- };
- 
- SpiceCharDeviceInstance vdagent_sin = {
-     .base = {
--        .sif = &vdagent_sif.base,
-+        .sif = &base,
-     },
-     .subtype = "vdagent",
- };
-diff --git a/server/tests/test_display_resolution_changes.c b/server/tests/test_display_resolution_changes.c
-index c492653..e351e99 100644
---- a/server/tests/test_display_resolution_changes.c
-+++ b/server/tests/test_display_resolution_changes.c
-@@ -45,8 +45,8 @@ void set_primary_params(SPICE_GNUC_UNUSED Test *test,
- }
- 
- static Command commands[] = {
--    {DESTROY_PRIMARY, NULL},
--    {CREATE_PRIMARY, set_primary_params},
-+    {DESTROY_PRIMARY, NULL, .cb_opaque = NULL,},
-+    {CREATE_PRIMARY, set_primary_params, .cb_opaque = NULL},
- };
- 
- int main(void)
-diff --git a/server/tests/test_display_width_stride.c b/server/tests/test_display_width_stride.c
-index a071e74..77d3c12 100644
---- a/server/tests/test_display_width_stride.c
-+++ b/server/tests/test_display_width_stride.c
-@@ -66,17 +66,17 @@ void set_destroy_parameters(SPICE_GNUC_UNUSED Test *test,
- }
- 
- static Command commands[] = {
--    {SIMPLE_CREATE_SURFACE, set_surface_params},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DRAW_SOLID, set_draw_parameters},
--    {SIMPLE_DESTROY_SURFACE, set_destroy_parameters},
-+    {SIMPLE_CREATE_SURFACE, set_surface_params, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DRAW_SOLID, set_draw_parameters, .cb_opaque = NULL},
-+    {SIMPLE_DESTROY_SURFACE, set_destroy_parameters, .cb_opaque = NULL},
- };
- 
- void on_client_connected(Test *test)
-diff --git a/server/tests/test_playback.c b/server/tests/test_playback.c
-index f712f7b..a6c3d7e 100644
---- a/server/tests/test_playback.c
-+++ b/server/tests/test_playback.c
-@@ -21,11 +21,11 @@
- 
- SpicePlaybackInstance playback_instance;
- 
--static const SpicePlaybackInterface playback_sif = {
--    .base.type          = SPICE_INTERFACE_PLAYBACK,
--    .base.description   = "test playback",
--    .base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
--    .base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
-+static const SpiceBaseInterface base = {
-+    .type          = SPICE_INTERFACE_PLAYBACK,
-+    .description   = "test playback",
-+    .major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
-+    .minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
- };
- 
- uint32_t *frame;
-@@ -99,7 +99,7 @@ int main(void)
-     spice_server_set_noauth(server);
-     spice_server_init(server, core);
- 
--    playback_instance.base.sif = &playback_sif.base;
-+    playback_instance.base.sif = &base;
-     spice_server_add_interface(server, &playback_instance.base);
-     spice_server_playback_start(&playback_instance);
- 
-diff --git a/server/tests/test_vdagent.c b/server/tests/test_vdagent.c
-index 7a56c2a..191ad05 100644
---- a/server/tests/test_vdagent.c
-+++ b/server/tests/test_vdagent.c
-@@ -79,14 +79,11 @@ static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
- {
- }
- 
--static SpiceCharDeviceInterface vmc_interface = {
--    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
--    .base.description   = "test spice virtual channel char device",
--    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
--    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
--    .state              = vmc_state,
--    .write              = vmc_write,
--    .read               = vmc_read,
-+static SpiceBaseInterface base = {
-+    .type          = SPICE_INTERFACE_CHAR_DEVICE,
-+    .description   = "test spice virtual channel char device",
-+    .major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
-+    .minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
- };
- 
- SpiceCharDeviceInstance vmc_instance = {
-@@ -100,7 +97,7 @@ int main(void)
-     core = basic_event_loop_init();
-     test = test_new(core);
- 
--    vmc_instance.base.sif = &vmc_interface.base;
-+    vmc_instance.base.sif = &base;
-     spice_server_add_interface(test->server, &vmc_instance.base);
- 
-     ping_timer = core->timer_add(pinger, NULL);
diff --git a/SOURCES/0033-Fix-Wunused-function.patch b/SOURCES/0033-Fix-Wunused-function.patch
deleted file mode 100644
index 38d958f..0000000
--- a/SOURCES/0033-Fix-Wunused-function.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Mon, 1 Sep 2014 15:06:54 +0200
-Subject: [PATCH] Fix -Wunused-function
-
-(cherry picked from commit 93b4f4050c57bd851292e4cee884888cee56fc31)
----
- server/tests/test_display_base.c | 22 -----------------
- server/tests/test_vdagent.c      | 51 ----------------------------------------
- 2 files changed, 73 deletions(-)
-
-diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c
-index bfe9991..36b4fc1 100644
---- a/server/tests/test_display_base.c
-+++ b/server/tests/test_display_base.c
-@@ -795,28 +795,6 @@ void test_add_display_interface(Test* test)
-     spice_server_add_interface(test->server, &test->qxl_instance.base);
- }
- 
--static int vmc_write(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                     SPICE_GNUC_UNUSED const uint8_t *buf,
--                     int len)
--{
--    printf("%s: %d\n", __func__, len);
--    return len;
--}
--
--static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                    SPICE_GNUC_UNUSED uint8_t *buf,
--                    int len)
--{
--    printf("%s: %d\n", __func__, len);
--    return 0;
--}
--
--static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                      int connected)
--{
--    printf("%s: %d\n", __func__, connected);
--}
--
- static SpiceBaseInterface base = {
-     .type          = SPICE_INTERFACE_CHAR_DEVICE,
-     .description   = "test spice virtual channel char device",
-diff --git a/server/tests/test_vdagent.c b/server/tests/test_vdagent.c
-index 191ad05..22153b6 100644
---- a/server/tests/test_vdagent.c
-+++ b/server/tests/test_vdagent.c
-@@ -28,57 +28,6 @@ void pinger(SPICE_GNUC_UNUSED void *opaque)
-     core->timer_start(ping_timer, ping_ms);
- }
- 
--
--static int vmc_write(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                     SPICE_GNUC_UNUSED const uint8_t *buf,
--                     int len)
--{
--    return len;
--}
--
--static int vmc_read(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                    uint8_t *buf,
--                    int len)
--{
--    static uint8_t c = 0;
--    static uint8_t message[2048];
--    static unsigned pos = 0;
--    static unsigned message_size;
--    int ret;
--
--    if (pos == 0) {
--        VDIChunkHeader *hdr = (VDIChunkHeader *)message;
--        VDAgentMessage *msg = (VDAgentMessage *)&hdr[1];
--        uint8_t *p = message;
--        int size = sizeof(message);
--        message_size = size;
--        /* fill in message */
--        hdr->port = VDP_SERVER_PORT;
--        hdr->size = message_size - sizeof(VDIChunkHeader);
--        msg->protocol = VD_AGENT_PROTOCOL;
--        msg->type = VD_AGENT_END_MESSAGE;
--        msg->opaque = 0;
--        msg->size = message_size - sizeof(VDIChunkHeader) - sizeof(VDAgentMessage);
--        size -= sizeof(VDIChunkHeader) + sizeof(VDAgentMessage);
--        p += sizeof(VDIChunkHeader) + sizeof(VDAgentMessage);
--        for (; size; --size, ++p, ++c)
--            *p = c;
--    }
--    ret = MIN(message_size - pos, len);
--    memcpy(buf, &message[pos], ret);
--    pos += ret;
--    if (pos == message_size) {
--        pos = 0;
--    }
--    //printf("vmc_read %d (ret %d)\n", len, ret);
--    return ret;
--}
--
--static void vmc_state(SPICE_GNUC_UNUSED SpiceCharDeviceInstance *sin,
--                      SPICE_GNUC_UNUSED int connected)
--{
--}
--
- static SpiceBaseInterface base = {
-     .type          = SPICE_INTERFACE_CHAR_DEVICE,
-     .description   = "test spice virtual channel char device",
diff --git a/SOURCES/0034-Validate-surface-bounding-box-before-using-it.patch b/SOURCES/0034-Validate-surface-bounding-box-before-using-it.patch
deleted file mode 100644
index 701d618..0000000
--- a/SOURCES/0034-Validate-surface-bounding-box-before-using-it.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Tue, 9 Sep 2014 18:00:30 +0200
-Subject: [PATCH] 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
-
-(cherry picked from commit e270edcbfd958d764e84cdbca6d403ff24fef610)
----
- server/red_worker.c | 31 +++++++++++++++++++++++++++++++
- 1 file changed, 31 insertions(+)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 945f4f1..9e6a6ad 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -1272,6 +1272,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);
-@@ -4117,6 +4144,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);
- 
diff --git a/SOURCES/0035-migration-Don-t-assert-if-MIGRATE_DATA-comes-before-.patch b/SOURCES/0035-migration-Don-t-assert-if-MIGRATE_DATA-comes-before-.patch
deleted file mode 100644
index 80167ae..0000000
--- a/SOURCES/0035-migration-Don-t-assert-if-MIGRATE_DATA-comes-before-.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Uri Lublin <uril@redhat.com>
-Date: Wed, 16 Jul 2014 17:02:04 +0300
-Subject: [PATCH] migration: Don't assert() if MIGRATE_DATA comes before
- attaching the agent
-
-During seamless migration, after switching host, if a client was connected
-during the migration, it will have data to send back to the new
-qemu/spice-server instance. This is handled through MIGRATE_DATA messages.
-SPICE char devices use such MIGRATE_DATA messages to restore their state.
-
-However, the MIGRATE_DATA message can arrive any time after the new qemu
-instance has started, this can happen before or after the SPICE char
-devices have been created. In order to handle this, if the migrate data
-arrives early, it's stored in reds->agent_state.mig_data, and
-attach_to_red_agent() will restore the agent state as appropriate.
-
-Unfortunately this does not work as expected, for main
-channel (agent messages).
-If attach_to_red_agent() is called before the MIGRATE_DATA
-message reaches the server, all goes well,
-but if MIGRATE_DATA reaches the server before
-attach_to_red_agent() gets called, then some assert() gets
-triggered in spice_char_device_state_restore():
-
-((null):32507): Spice-ERROR **: char_device.c:937:spice_char_device_state_restore: assertion `dev->num_clients == 1 && dev->wait_for_migrate_data' failed
-Thread 3 (Thread 0x7f406b543700 (LWP 32543)):
-Thread 2 (Thread 0x7f40697ff700 (LWP 32586)):
-Thread 1 (Thread 0x7f4079b45a40 (LWP 32507)):
-
-When restoring state, a client must already be added to the
-spice-char-device.
-What happens is that a client is not being added to the char-device
-when when MIGRATE_DATA arrives first, which leaves both
-dev->num_clients and dev->wait_for_migrate_data value at 0.
-
-This commit changes the logic in spice_server_char_device_add_interface(),
-such that if there is migrate data pending in reds->agent_state.mig_data
-but no client was added to the spice-char-device yet,
-then first the client is added to the device by calling
-spice_char_device_client_add(), and only then the state is restored.
-
-=== How to Reproduce
-To reproduce, add delays to the migration connection between
-qmeu-kvm on the source host (SRC) and on the destination (DST).
-
-Specifically I added a man in the middle DLY host between
-migration ports from SRC to DST.
-
-+-----+    +-----+     +-----+
-| SRC |--> | DLY | --> | DST |
-+-----+    +-----+     +-----+
-
-DLY listens on port P1 (e.g. 4444) and DST listens on port
-PINCOMING (e.g. 4444, from qemu-kvm '-incoming' command line option)
-
-Precondition: make sure port P1 on DLY is accessible in iptables.
-Option 1: use ssh tcp port forwarding
-On DLY host run ssh:
-  ssh DLY:P1:DST:PINCOMING DST
-Then use the following migration command (on qemu-kvm monitor):
-  client_migrate_info spice DST PSPICE
-  migrate -d tcp:DLY:P1
-
-Option 2: Use a simple proxy program that forwards
-packets from SRC to DST while adding some delays.
-The program runs on DLY, listens to port D1, upon
-accept connects to DST:PINCOMING and forward all
-packets from DLY:D1 to DST:PINCOMING.
-Then use the same migrate command as in option 1:
-  client_migrate_info spice DST PSPICE
-  migrate -d tcp:DLY:P1
-
-=== How to Reproduce Ends
-
-This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1035184
-
-Based-on-a-patch-by: Christophe Fergeau <cfergeau@redhat.com>
-(cherry picked from commit 2d1c00a659cd1b3998f5d1f90fc5ee6abb7519bb)
----
- server/reds.c | 39 ++++++++++++++++++++++++++++-----------
- 1 file changed, 28 insertions(+), 11 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 464552a..06e9a3e 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1373,6 +1373,7 @@ int reds_handle_migrate_data(MainChannelClient *mcc, SpiceMigrateDataMain *mig_d
- {
-     VDIPortState *agent_state = &reds->agent_state;
- 
-+    spice_debug("main-channel: got migrate data");
-     /*
-      * Now that the client has switched to the target server, if main_channel
-      * controls the mm-time, we update the client's mm-time.
-@@ -1394,15 +1395,18 @@ int reds_handle_migrate_data(MainChannelClient *mcc, SpiceMigrateDataMain *mig_d
-                     main_channel_push_agent_disconnected(reds->main_channel);
-                     main_channel_push_agent_connected(reds->main_channel);
-                 } else {
-+                    spice_debug("restoring state from mig_data");
-                     return reds_agent_state_restore(mig_data);
-                 }
-             }
-         } else {
-             /* restore agent starte when the agent gets attached */
-+            spice_debug("saving mig_data");
-             spice_assert(agent_state->plug_generation == 0);
-             agent_state->mig_data = spice_memdup(mig_data, size);
-         }
-     } else {
-+        spice_debug("agent was not attached on the source host");
-         if (vdagent) {
-             /* spice_char_device_client_remove disables waiting for migration data */
-             spice_char_device_client_remove(agent_state->base,
-@@ -3589,17 +3593,15 @@ static SpiceCharDeviceState *attach_to_red_agent(SpiceCharDeviceInstance *sin)
-     state->read_filter.discard_all = FALSE;
-     reds->agent_state.plug_generation++;
- 
--    if (reds->agent_state.mig_data) {
--        spice_assert(reds->agent_state.plug_generation == 1);
--        reds_agent_state_restore(reds->agent_state.mig_data);
--        free(reds->agent_state.mig_data);
--        reds->agent_state.mig_data = NULL;
--    } else if (!red_channel_waits_for_migrate_data(&reds->main_channel->base)) {
--        /* we will assoicate the client with the char device, upon reds_on_main_agent_start,
--         * in response to MSGC_AGENT_START */
--        main_channel_push_agent_connected(reds->main_channel);
--    } else {
--       spice_debug("waiting for migration data");
-+    if (reds->agent_state.mig_data ||
-+        red_channel_waits_for_migrate_data(&reds->main_channel->base)) {
-+        /* Migration in progress (code is running on the destination host):
-+         * 1.  Add the client to spice char device, if it was not already added.
-+         * 2.a If this (qemu-kvm state load side of migration) happens first
-+         *     then wait for spice migration data to arrive. Otherwise
-+         * 2.b If this happens second ==> we already have spice migrate data
-+         *     then restore state
-+         */
-         if (!spice_char_device_client_exists(reds->agent_state.base, reds_get_client())) {
-             int client_added;
- 
-@@ -3615,9 +3617,24 @@ static SpiceCharDeviceState *attach_to_red_agent(SpiceCharDeviceInstance *sin)
-                 spice_warning("failed to add client to agent");
-                 reds_disconnect();
-             }
-+        }
- 
-+        if (reds->agent_state.mig_data) {
-+            spice_debug("restoring state from stored migration data");
-+            spice_assert(reds->agent_state.plug_generation == 1);
-+            reds_agent_state_restore(reds->agent_state.mig_data);
-+            free(reds->agent_state.mig_data);
-+            reds->agent_state.mig_data = NULL;
-+        }
-+        else {
-+            spice_debug("waiting for migration data");
-         }
-+    } else {
-+        /* we will associate the client with the char device, upon reds_on_main_agent_start,
-+         * in response to MSGC_AGENT_START */
-+        main_channel_push_agent_connected(reds->main_channel);
-     }
-+
-     return state->base;
- }
- 
diff --git a/SOURCES/0036-server-fix-crash-when-restarting-VM-with-old-client.patch b/SOURCES/0036-server-fix-crash-when-restarting-VM-with-old-client.patch
deleted file mode 100644
index 93a8405..0000000
--- a/SOURCES/0036-server-fix-crash-when-restarting-VM-with-old-client.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Thu, 9 Oct 2014 17:23:06 +0200
-Subject: [PATCH] server: fix crash when restarting VM with old client
-
-The server will reset the vdagent char device when the client does not
-implement SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS. This will nullify
-dev->sin and the following crash will be reached on restart:
-
- #0  0x00007fb05aa264a1 in spice_char_device_write_to_device (dev=dev@entry=0x7fb066ae5d30) at char_device.c:443
- #1  0x00007fb05aa27137 in spice_char_device_write_to_device (dev=0x7fb066ae5d30) at char_device.c:436
- #2  spice_char_device_start (dev=0x7fb066ae5d30) at char_device.c:798
- #3  0x00007fb05aa6a981 in spice_server_vm_start (s=<optimized out>) at reds.c:3795
- #4  0x00007fb0644b7f89 in qdev_reset_one (dev=<optimized out>, opaque=<optimized out>) at hw/core/qdev.c:241
- #5  0x00007fb0644b7918 in qbus_walk_children (bus=0x7fb06661e870, pre_devfn=0x0, pre_busfn=0x0,
-     post_devfn=0x7fb0644b7f80 <qdev_reset_one>, post_busfn=0x7fb0644b6350 <qbus_reset_one>, opaque=0x0)
-     at hw/core/qdev.c:422
- #6  0x00007fb0644b7848 in qdev_walk_children (dev=0x7fb0665f47a0, pre_devfn=0x0, pre_busfn=0x0,
-     post_devfn=0x7fb0644b7f80 <qdev_reset_one>, post_busfn=0x7fb0644b6350 <qbus_reset_one>, opaque=0x0)
-     at hw/core/qdev.c:456
- #7  0x00007fb0644b7918 in qbus_walk_children (bus=0x7fb06647cde0, pre_devfn=0x0, pre_busfn=0x0,
-     post_devfn=0x7fb0644b7f80 <qdev_reset_one>, post_busfn=0x7fb0644b6350 <qbus_reset_one>, opaque=0x0)
-     at hw/core/qdev.c:422
- #8  0x00007fb0644399fd in qemu_devices_reset () at vl.c:1830
-
-After restart, qemu will reset the device instance (sin) when virtio
-port is opened:
-
- #0  spice_char_device_state_reset_dev_instance (state=0x7fe4873876d0, sin=sin@entry=0x7fe486fb0c68)
-     at char_device.c:667
- #1  0x00007fe47b277516 in attach_to_red_agent (sin=0x7fe486fb0c68) at reds.c:2838
- #2  spice_server_char_device_add_interface (sin=0x7fe486fb0c68, s=0x7fe486fb2e60) at reds.c:2962
- #3  spice_server_add_interface (s=0x7fe486fb2e60, sin=0x7fe486fb0c68) at reds.c:3104
- #4  0x00007fe484c69e57 in vmc_register_interface (scd=0x7fe486fb0c60) at spice-qemu-char.c:123
- #5  0x00007fe484ce96b4 in set_guest_connected (port=<optimized out>, guest_connected=1)
-     at hw/char/virtio-console.c:89
- #6  0x00007fe484ba70ed in handle_control_message (len=8, buf=0x7fe486fbdf70, vser=0x7fe48739ae98)
-     at /usr/src/debug/qemu-2.1.0/hw/char/virtio-serial-bus.c:382
-
-Let's ignore the call to spice_char_device_{write,read}_to_device() when
-dev->sin is NULL, similary to other conditions, such as dev->running.
-
-Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1145919
-(cherry picked from commit 4639817f0eb26316894cc83b43a736bdd72f9018)
----
- server/char_device.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/char_device.c b/server/char_device.c
-index 660a788..6d2339e 100644
---- a/server/char_device.c
-+++ b/server/char_device.c
-@@ -283,7 +283,7 @@ static int spice_char_device_read_from_device(SpiceCharDeviceState *dev)
-     uint64_t max_send_tokens;
-     int did_read = FALSE;
- 
--    if (!dev->running || dev->wait_for_migrate_data) {
-+    if (!dev->running || dev->wait_for_migrate_data || !dev->sin) {
-         return FALSE;
-     }
- 
-@@ -433,7 +433,7 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-     int total = 0;
-     int n;
- 
--    if (!dev->running || dev->wait_for_migrate_data) {
-+    if (!dev->running || dev->wait_for_migrate_data || !dev->sin) {
-         return 0;
-     }
- 
diff --git a/SOURCES/0037-Use-TLS-version-1.0-or-better.patch b/SOURCES/0037-Use-TLS-version-1.0-or-better.patch
deleted file mode 100644
index 310feda..0000000
--- a/SOURCES/0037-Use-TLS-version-1.0-or-better.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?David=20Ja=C5=A1a?= <djasa@redhat.com>
-Date: Wed, 27 Nov 2013 17:45:49 +0100
-Subject: [PATCH] Use TLS version 1.0 or better
-
-When creating a TLS socket, both spice-server and spice-gtk currently
-call SSL_CTX_new(TLSv1_method()). The TLSv1_method() function set the
-protocol version to TLS 1.0 exclusively. The correct way to support
-multiple protocol versions is to call SSLv23_method() in spite of its
-scary name. This method will enable all SSL/TLS protocol versions. The
-protocol suite may be further narrowed down by setting respective
-SSL_OP_NO_<version_code> options of SSL context.  This possibility is
-used in this patch in order to block use of SSLv3 that is enabled by
-default in openssl for client sockets as of now but spice has never used
-it.
----
- server/reds.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 06e9a3e..ccba67c 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -3232,6 +3232,8 @@ static int reds_init_ssl(void)
-     SSL_METHOD *ssl_method;
- #endif
-     int return_code;
-+    /* When some other SSL/TLS version becomes obsolete, add it to this
-+     * variable. */
-     long ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
- 
-     /* Global system initialization*/
-@@ -3239,7 +3241,8 @@ static int reds_init_ssl(void)
-     SSL_load_error_strings();
- 
-     /* Create our context*/
--    ssl_method = TLSv1_method();
-+    /* SSLv23_method() handles TLSv1.x in addition to SSLv2/v3 */
-+    ssl_method = SSLv23_method();
-     reds->ctx = SSL_CTX_new(ssl_method);
-     if (!reds->ctx) {
-         spice_warning("Could not allocate new SSL context");
diff --git a/SOURCES/0038-Add-const-to-test_capability-first-argument.patch b/SOURCES/0038-Add-const-to-test_capability-first-argument.patch
deleted file mode 100644
index e7f2de9..0000000
--- a/SOURCES/0038-Add-const-to-test_capability-first-argument.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Wed, 19 Mar 2014 18:17:32 +0100
-Subject: [PATCH] Add const to test_capability first argument
-
-We don't modify the capabilities content, so it can be marked as const.
----
- server/red_channel.c | 2 +-
- server/red_channel.h | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 5df8f14..449e628 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -1159,7 +1159,7 @@ void red_channel_register_client_cbs(RedChannel *channel, ClientCbs *client_cbs)
-     }
- }
- 
--int test_capabilty(uint32_t *caps, int num_caps, uint32_t cap)
-+int test_capabilty(const uint32_t *caps, int num_caps, uint32_t cap)
- {
-     uint32_t index = cap / 32;
-     if (num_caps < index + 1) {
-diff --git a/server/red_channel.h b/server/red_channel.h
-index 9e54dce..58109d5 100644
---- a/server/red_channel.h
-+++ b/server/red_channel.h
-@@ -223,7 +223,7 @@ typedef struct RedChannelCapabilities {
-     uint32_t *caps;
- } RedChannelCapabilities;
- 
--int test_capabilty(uint32_t *caps, int num_caps, uint32_t cap);
-+int test_capabilty(const uint32_t *caps, int num_caps, uint32_t cap);
- 
- typedef struct RedChannelClientLatencyMonitor {
-     int state;
diff --git a/SOURCES/0039-Introduce-red_link_info_test_capability.patch b/SOURCES/0039-Introduce-red_link_info_test_capability.patch
deleted file mode 100644
index 434663d..0000000
--- a/SOURCES/0039-Introduce-red_link_info_test_capability.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Wed, 5 Mar 2014 11:59:37 +0100
-Subject: [PATCH] Introduce red_link_info_test_capability()
-
-This just hides a bit of pointer arithmetic away from reds_send_link_ack.
-This helper will be used in the next commits.
----
- server/reds.c | 21 ++++++++++++++++++---
- 1 file changed, 18 insertions(+), 3 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index ccba67c..9971b7a 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1446,6 +1446,22 @@ static void reds_channel_init_auth_caps(RedLinkInfo *link, RedChannel *channel)
-     red_channel_set_common_cap(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
- }
- 
-+
-+static const uint32_t *red_link_info_get_caps(const RedLinkInfo *link)
-+{
-+    const uint8_t *caps_start = (const uint8_t *)link->link_mess;
-+
-+    return (const uint32_t *)(caps_start + link->link_mess->caps_offset);
-+}
-+
-+static bool red_link_info_test_capability(const RedLinkInfo *link, uint32_t cap)
-+{
-+    const uint32_t *caps = red_link_info_get_caps(link);
-+
-+    return test_capabilty(caps, link->link_mess->num_common_caps, cap);
-+}
-+
-+
- static int reds_send_link_ack(RedLinkInfo *link)
- {
-     SpiceLinkHeader header;
-@@ -2701,7 +2717,6 @@ static void reds_handle_read_link_done(void *opaque)
-     SpiceLinkMess *link_mess = link->link_mess;
-     AsyncRead *obj = &link->asyc_read;
-     uint32_t num_caps = link_mess->num_common_caps + link_mess->num_channel_caps;
--    uint32_t *caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset);
-     int auth_selection;
- 
-     if (num_caps && (num_caps * sizeof(uint32_t) + link_mess->caps_offset >
-@@ -2712,8 +2727,8 @@ static void reds_handle_read_link_done(void *opaque)
-         return;
-     }
- 
--    auth_selection = test_capabilty(caps, link_mess->num_common_caps,
--                                    SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
-+    auth_selection = red_link_info_test_capability(link,
-+                                                   SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
- 
-     if (!reds_security_check(link)) {
-         if (link->stream->ssl) {
diff --git a/SOURCES/0040-Don-t-set-SpiceLinkReply-pub_key-if-client-advertise.patch b/SOURCES/0040-Don-t-set-SpiceLinkReply-pub_key-if-client-advertise.patch
deleted file mode 100644
index 9c2c90c..0000000
--- a/SOURCES/0040-Don-t-set-SpiceLinkReply-pub_key-if-client-advertise.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
-Date: Thu, 9 Jul 2015 01:04:31 +0200
-Subject: [PATCH] Don't set SpiceLinkReply::pub_key if client advertises SASL
- cap
-
-If the client advertises the SASL cap, it means it guarantees it will be
-able to use SASL if the server supports, and that it does not need a valid
-SpiceLinkReply::pub_key field when using SASL.
-
-When the client cap is set, we thus don't need to create a RSA public key
-if SASL is enabled server side.
-
-The reason for needing client guarantees about not looking at the pub_key
-field is that its presence and size is hardcoded in the protocol, but in
-some hardened setups (using fips mode), generating a RSA 1024 bit key as
-expected is forbidden and fails. With this new capability, the server
-knows the client will be able to handle SASL if needed, and can skip
-the generation of the key altogether. This means that on the setups
-described above, SASL authentication has to be used.
----
- server/reds.c | 56 +++++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 39 insertions(+), 17 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 9971b7a..f996c71 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1469,7 +1469,7 @@ static int reds_send_link_ack(RedLinkInfo *link)
-     RedChannel *channel;
-     RedChannelCapabilities *channel_caps;
-     BUF_MEM *bmBuf;
--    BIO *bio;
-+    BIO *bio = NULL;
-     int ret = FALSE;
- 
-     header.magic = SPICE_MAGIC;
-@@ -1494,24 +1494,45 @@ static int reds_send_link_ack(RedLinkInfo *link)
-     ack.num_channel_caps = channel_caps->num_caps;
-     header.size += (ack.num_common_caps + ack.num_channel_caps) * sizeof(uint32_t);
-     ack.caps_offset = sizeof(SpiceLinkReply);
-+    if (!sasl_enabled
-+        || !red_link_info_test_capability(link, SPICE_COMMON_CAP_AUTH_SASL)) {
-+        if (!(link->tiTicketing.rsa = RSA_new())) {
-+            spice_warning("RSA new failed");
-+            return FALSE;
-+        }
- 
--    if (!(link->tiTicketing.rsa = RSA_new())) {
--        spice_warning("RSA nes failed");
--        return FALSE;
--    }
--
--    if (!(bio = BIO_new(BIO_s_mem()))) {
--        spice_warning("BIO new failed");
--        return FALSE;
--    }
-+        if (!(bio = BIO_new(BIO_s_mem()))) {
-+            spice_warning("BIO new failed");
-+            return FALSE;
-+        }
- 
--    RSA_generate_key_ex(link->tiTicketing.rsa, SPICE_TICKET_KEY_PAIR_LENGTH, link->tiTicketing.bn,
--                        NULL);
--    link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
-+        if (RSA_generate_key_ex(link->tiTicketing.rsa,
-+                                SPICE_TICKET_KEY_PAIR_LENGTH,
-+                                link->tiTicketing.bn,
-+                                NULL) != 1) {
-+            spice_warning("Failed to generate %d bits RSA key: %s",
-+                          SPICE_TICKET_KEY_PAIR_LENGTH,
-+                          ERR_error_string(ERR_get_error(), NULL));
-+           goto end;
-+        }
-+        link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
- 
--    i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
--    BIO_get_mem_ptr(bio, &bmBuf);
--    memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
-+        i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
-+        BIO_get_mem_ptr(bio, &bmBuf);
-+        memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
-+    } else {
-+        /* if the client sets the AUTH_SASL cap, it indicates that it
-+         * supports SASL, and will use it if the server supports SASL as
-+         * well. Moreover, a client setting the AUTH_SASL cap also
-+         * indicates that it will not try using the RSA-related content
-+         * in the SpiceLinkReply message, so we don't need to initialize
-+         * it. Reason to avoid this is to fix auth in fips mode where
-+         * the generation of a 1024 bit RSA key as we are trying to do
-+         * will fail.
-+         */
-+         spice_warning("not initialising RSA key");
-+         memset(ack.pub_key, '\0', sizeof(ack.pub_key));
-+    }
- 
-     if (!sync_write(link->stream, &header, sizeof(header)))
-         goto end;
-@@ -1525,7 +1546,8 @@ static int reds_send_link_ack(RedLinkInfo *link)
-     ret = TRUE;
- 
- end:
--    BIO_free(bio);
-+    if (bio != NULL)
-+        BIO_free(bio);
-     return ret;
- }
- 
diff --git a/SOURCES/0041-server-don-t-assert-on-invalid-client-message.patch b/SOURCES/0041-server-don-t-assert-on-invalid-client-message.patch
deleted file mode 100644
index f920c78..0000000
--- a/SOURCES/0041-server-don-t-assert-on-invalid-client-message.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Wed, 25 Jun 2014 14:36:03 +0200
-Subject: [PATCH] server: don't assert on invalid client message
-
-Some users have been reaching this error:
-snd_receive: ASSERT n failed
-
-A misbehaving client could easily hit that condition by sending too big
-messages. Instead of assert(), replace with a warning. When a message
-too big to fit is received, it will simply disconnect the channel.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=962187
----
- server/snd_worker.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index ebddfcd..c451031 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -421,7 +421,7 @@ static void snd_receive(void* data)
-     for (;;) {
-         ssize_t n;
-         n = channel->recive_data.end - channel->recive_data.now;
--        spice_assert(n);
-+        spice_warn_if(n <= 0);
-         n = reds_stream_read(channel->stream, channel->recive_data.now, n);
-         if (n <= 0) {
-             if (n == 0) {
diff --git a/SOURCES/0042-Don-t-truncate-large-now-values-in-_spice_timer_set.patch b/SOURCES/0042-Don-t-truncate-large-now-values-in-_spice_timer_set.patch
deleted file mode 100644
index 1e34305..0000000
--- a/SOURCES/0042-Don-t-truncate-large-now-values-in-_spice_timer_set.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: David Gibson <dgibson@redhat.com>
-Date: Mon, 10 Mar 2014 11:55:47 +0100
-Subject: [PATCH] Don't truncate large 'now' values in _spice_timer_set
-
-static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
-
-The _spice_timer_set() function takes a 32-bit integer for the "now" value.
-The now value passed in however, can exceed 2^32 (it's in ms and derived
-from CLOCK_MONOTONIC, which will wrap around a 32-bit integer in around 46
-days).
-
-If the now value passed in exceeds 2^32, this will mean timers are inserted
-into the active list with expiry values before the current time, they will
-immediately trigger, and (if they don't make themselves inactive) be
-reinserted still before the current time.
-
-This leads to an infinite loop in spice_timer_queue_cb().
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1072700
----
- server/spice_timer_queue.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
-
-diff --git a/server/spice_timer_queue.c b/server/spice_timer_queue.c
-index 8f6e9c8..71de84a 100644
---- a/server/spice_timer_queue.c
-+++ b/server/spice_timer_queue.c
-@@ -147,7 +147,7 @@ SpiceTimer *spice_timer_queue_add(SpiceTimerFunc func, void *opaque)
-     return timer;
- }
- 
--static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint32_t now)
-+static void _spice_timer_set(SpiceTimer *timer, uint32_t ms, uint64_t now)
- {
-     RingItem *next_item;
-     SpiceTimerQueue *queue;
-@@ -183,7 +183,8 @@ void spice_timer_set(SpiceTimer *timer, uint32_t ms)
-     spice_assert(pthread_equal(timer->queue->thread, pthread_self()) != 0);
- 
-     clock_gettime(CLOCK_MONOTONIC, &now);
--    _spice_timer_set(timer, ms, now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
-+    _spice_timer_set(timer, ms,
-+                     (uint64_t)now.tv_sec * 1000 + (now.tv_nsec / 1000 / 1000));
- }
- 
- void spice_timer_cancel(SpiceTimer *timer)
-@@ -217,7 +218,7 @@ void spice_timer_remove(SpiceTimer *timer)
- unsigned int spice_timer_queue_get_timeout_ms(void)
- {
-     struct timespec now;
--    int now_ms;
-+    int64_t now_ms;
-     RingItem *head;
-     SpiceTimer *head_timer;
-     SpiceTimerQueue *queue = spice_timer_queue_find_with_lock();
-@@ -232,9 +233,9 @@ unsigned int spice_timer_queue_get_timeout_ms(void)
-     head_timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
- 
-     clock_gettime(CLOCK_MONOTONIC, &now);
--    now_ms = (now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
-+    now_ms = ((int64_t)now.tv_sec * 1000) - (now.tv_nsec / 1000 / 1000);
- 
--    return MAX(0, ((int)head_timer->expiry_time - now_ms));
-+    return MAX(0, ((int64_t)head_timer->expiry_time - now_ms));
- }
- 
- 
-@@ -252,7 +253,7 @@ void spice_timer_queue_cb(void)
-     }
- 
-     clock_gettime(CLOCK_MONOTONIC, &now);
--    now_ms = (now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
-+    now_ms = ((uint64_t)now.tv_sec * 1000) + (now.tv_nsec / 1000 / 1000);
- 
-     while ((head = ring_get_head(&queue->active_timers))) {
-         SpiceTimer *timer = SPICE_CONTAINEROF(head, SpiceTimer, active_link);
diff --git a/SOURCES/0043-Avoid-race-conditions-reading-monitor-configs-from-g.patch b/SOURCES/0043-Avoid-race-conditions-reading-monitor-configs-from-g.patch
deleted file mode 100644
index 14ed533..0000000
--- a/SOURCES/0043-Avoid-race-conditions-reading-monitor-configs-from-g.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 9 Jun 2015 08:50:46 +0100
-Subject: [PATCH] Avoid race conditions reading monitor configs from guest
-
-For security reasons do not assume guest do not change structures it
-pass to Qemu.
-Guest could change count field while Qemu is copying QXLMonitorsConfig
-structure leading to heap corruption.
-This patch avoid it reading count only once.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_worker.c | 46 ++++++++++++++++++++++++++++++++--------------
- 1 file changed, 32 insertions(+), 14 deletions(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 9e6a6ad..955cac2 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -11270,7 +11270,8 @@ static inline void red_monitors_config_item_add(DisplayChannelClient *dcc)
- }
- 
- static void worker_update_monitors_config(RedWorker *worker,
--                                          QXLMonitorsConfig *dev_monitors_config)
-+                                          QXLMonitorsConfig *dev_monitors_config,
-+                                          uint16_t count, uint16_t max_allowed)
- {
-     int heads_size;
-     MonitorsConfig *monitors_config;
-@@ -11279,22 +11280,22 @@ static void worker_update_monitors_config(RedWorker *worker,
-     monitors_config_decref(worker->monitors_config);
- 
-     spice_debug("monitors config %d(%d)",
--                dev_monitors_config->count,
--                dev_monitors_config->max_allowed);
--    for (i = 0; i < dev_monitors_config->count; i++) {
-+                count,
-+                max_allowed);
-+    for (i = 0; i < count; i++) {
-         spice_debug("+%d+%d %dx%d",
-                     dev_monitors_config->heads[i].x,
-                     dev_monitors_config->heads[i].y,
-                     dev_monitors_config->heads[i].width,
-                     dev_monitors_config->heads[i].height);
-     }
--    heads_size = dev_monitors_config->count * sizeof(QXLHead);
-+    heads_size = count * sizeof(QXLHead);
-     worker->monitors_config = monitors_config =
-         spice_malloc(sizeof(*monitors_config) + heads_size);
-     monitors_config->refs = 1;
-     monitors_config->worker = worker;
--    monitors_config->count = dev_monitors_config->count;
--    monitors_config->max_allowed = dev_monitors_config->max_allowed;
-+    monitors_config->count = count;
-+    monitors_config->max_allowed = max_allowed;
-     memcpy(monitors_config->heads, dev_monitors_config->heads, heads_size);
- }
- 
-@@ -11678,33 +11679,50 @@ void handle_dev_display_migrate(void *opaque, void *payload)
-     red_migrate_display(worker, rcc);
- }
- 
-+static inline uint32_t qxl_monitors_config_size(uint32_t heads)
-+{
-+    return sizeof(QXLMonitorsConfig) + sizeof(QXLHead) * heads;
-+}
-+
- static void handle_dev_monitors_config_async(void *opaque, void *payload)
- {
-     RedWorkerMessageMonitorsConfigAsync *msg = payload;
-     RedWorker *worker = opaque;
--    int min_size = sizeof(QXLMonitorsConfig) + sizeof(QXLHead);
-     int error;
-+    uint16_t count, max_allowed;
-     QXLMonitorsConfig *dev_monitors_config =
-         (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
--                                     min_size, msg->group_id, &error);
-+                                     qxl_monitors_config_size(1),
-+                                     msg->group_id, &error);
- 
-     if (error) {
-         /* TODO: raise guest bug (requires added QXL interface) */
-         return;
-     }
-     worker->driver_cap_monitors_config = 1;
--    if (dev_monitors_config->count == 0) {
-+    count = dev_monitors_config->count;
-+    max_allowed = dev_monitors_config->max_allowed;
-+    if (count == 0) {
-         spice_warning("ignoring an empty monitors config message from driver");
-         return;
-     }
--    if (dev_monitors_config->count > dev_monitors_config->max_allowed) {
-+    if (count > max_allowed) {
-         spice_warning("ignoring malformed monitors_config from driver, "
-                       "count > max_allowed %d > %d",
--                      dev_monitors_config->count,
--                      dev_monitors_config->max_allowed);
-+                      count,
-+                      max_allowed);
-+        return;
-+    }
-+    /* get pointer again to check virtual size */
-+    dev_monitors_config =
-+        (QXLMonitorsConfig*)get_virt(&worker->mem_slots, msg->monitors_config,
-+                                     qxl_monitors_config_size(count),
-+                                     msg->group_id, &error);
-+    if (error) {
-+        /* TODO: raise guest bug (requires added QXL interface) */
-         return;
-     }
--    worker_update_monitors_config(worker, dev_monitors_config);
-+    worker_update_monitors_config(worker, dev_monitors_config, count, max_allowed);
-     red_worker_push_monitors_config(worker);
- }
- 
diff --git a/SOURCES/0044-Lock-the-pixmap-image-cache-for-the-entire-fill_bits.patch b/SOURCES/0044-Lock-the-pixmap-image-cache-for-the-entire-fill_bits.patch
deleted file mode 100644
index 2b4c80e..0000000
--- a/SOURCES/0044-Lock-the-pixmap-image-cache-for-the-entire-fill_bits.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sandy Stutsman <sstutsma@redhat.com>
-Date: Fri, 26 Jun 2015 11:59:13 -0400
-Subject: [PATCH] Lock the pixmap image cache for the entire fill_bits call
-
-Locking the individual calls that access the pixmap cache in fill_bits is
-not adequately thread safe.  Often a windows guest with multiple monitors
-will be sending the same image via different threads.  Both threads can
-be in fill_bits at the same time making changes to the cache for the same
-image.  This can result in images being deleted before all the client
-channels are finished with them or with the same image being send multiple
-times.  Here's what can happen with out the lock in fill_bits
-
-On the server in red_worker.c:fill_bits
- Thread 1 calls pixmap_cache_hit for Image A and finds it isn't in cache
- Thread 2 calls pixmap_cache_hit for Image A and finds it isn't in cache
-
- Thread 1 adds Image 1 to pixmap_cache (1x)
- Thread 2 adds Image 1 to pixmap_cache (2x)
-
-On the client
- Channel 1 adds Image A to image_cache (1x)
- Channel 2 replaces Image A in image_cache (1x)
-
-On server
- Thread 1 sends Image A rendering commands
- Thread N removes Image A from pixmap_cache (image remains - 1x)
- Thread 2 sends Image A rendering commands
-
-On client
- Channe1 renders from Image A
- Channel N removes Image a from image_cache (image is completely removed)
- Channel2 render command hangs waiting for Image A
----
- server/red_client_shared_cache.h | 24 ++++++++++++------------
- server/red_worker.c              | 23 +++++++++++++++--------
- 2 files changed, 27 insertions(+), 20 deletions(-)
-
-diff --git a/server/red_client_shared_cache.h b/server/red_client_shared_cache.h
-index 821ee18..7feb28e 100644
---- a/server/red_client_shared_cache.h
-+++ b/server/red_client_shared_cache.h
-@@ -36,13 +36,12 @@
- 
- #define CHANNEL_FROM_RCC(rcc) SPICE_CONTAINEROF((rcc)->channel, CHANNEL, common.base);
- 
--static int FUNC_NAME(hit)(CACHE *cache, uint64_t id, int *lossy, DisplayChannelClient *dcc)
-+static int FUNC_NAME(unlocked_hit)(CACHE *cache, uint64_t id, int *lossy, DisplayChannelClient *dcc)
- {
-     NewCacheItem *item;
-     uint64_t serial;
- 
-     serial = red_channel_client_get_message_serial(&dcc->common.base);
--    pthread_mutex_lock(&cache->lock);
-     item = cache->hash_table[CACHE_HASH_KEY(id)];
- 
-     while (item) {
-@@ -57,15 +56,22 @@ static int FUNC_NAME(hit)(CACHE *cache, uint64_t id, int *lossy, DisplayChannelC
-         }
-         item = item->next;
-     }
--    pthread_mutex_unlock(&cache->lock);
- 
-     return !!item;
- }
- 
--static int FUNC_NAME(set_lossy)(CACHE *cache, uint64_t id, int lossy)
-+static int FUNC_NAME(hit)(CACHE *cache, uint64_t id, int *lossy, DisplayChannelClient *dcc)
- {
--    NewCacheItem *item;
-+    int hit;
-     pthread_mutex_lock(&cache->lock);
-+    hit = FUNC_NAME(unlocked_hit)(cache,id,lossy, dcc);
-+    pthread_mutex_unlock(&cache->lock);
-+    return hit;
-+}
-+
-+static int FUNC_NAME(unlocked_set_lossy)(CACHE *cache, uint64_t id, int lossy)
-+{
-+    NewCacheItem *item;
- 
-     item = cache->hash_table[CACHE_HASH_KEY(id)];
- 
-@@ -76,11 +82,10 @@ static int FUNC_NAME(set_lossy)(CACHE *cache, uint64_t id, int lossy)
-         }
-         item = item->next;
-     }
--    pthread_mutex_unlock(&cache->lock);
-     return !!item;
- }
- 
--static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, DisplayChannelClient *dcc)
-+static int FUNC_NAME(unlocked_add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, DisplayChannelClient *dcc)
- {
-     NewCacheItem *item;
-     uint64_t serial;
-@@ -91,15 +96,12 @@ static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, D
-     item = spice_new(NewCacheItem, 1);
-     serial = red_channel_client_get_message_serial(&dcc->common.base);
- 
--    pthread_mutex_lock(&cache->lock);
--
-     if (cache->generation != dcc->CACH_GENERATION) {
-         if (!dcc->pending_pixmaps_sync) {
-             red_channel_client_pipe_add_type(
-                 &dcc->common.base, PIPE_ITEM_TYPE_PIXMAP_SYNC);
-             dcc->pending_pixmaps_sync = TRUE;
-         }
--        pthread_mutex_unlock(&cache->lock);
-         free(item);
-         return FALSE;
-     }
-@@ -112,7 +114,6 @@ static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, D
-         if (!(tail = (NewCacheItem *)ring_get_tail(&cache->lru)) ||
-                                                    tail->sync[dcc->common.id] == serial) {
-             cache->available += size;
--            pthread_mutex_unlock(&cache->lock);
-             free(item);
-             return FALSE;
-         }
-@@ -144,7 +145,6 @@ static int FUNC_NAME(add)(CACHE *cache, uint64_t id, uint32_t size, int lossy, D
-     memset(item->sync, 0, sizeof(item->sync));
-     item->sync[dcc->common.id] = serial;
-     cache->sync[dcc->common.id] = serial;
--    pthread_mutex_unlock(&cache->lock);
-     return TRUE;
- }
- 
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 955cac2..93e3398 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -6750,9 +6750,9 @@ static inline void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
-     if ((image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) {
-         spice_assert(image->descriptor.width * image->descriptor.height > 0);
-         if (!(io_image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME)) {
--            if (pixmap_cache_add(dcc->pixmap_cache, image->descriptor.id,
--                                 image->descriptor.width * image->descriptor.height, is_lossy,
--                                 dcc)) {
-+            if (pixmap_cache_unlocked_add(dcc->pixmap_cache, image->descriptor.id,
-+                                          image->descriptor.width * image->descriptor.height, is_lossy,
-+                                          dcc)) {
-                 io_image->descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_ME;
-                 dcc->send_data.pixmap_cache_items[dcc->send_data.num_pixmap_cache_items++] =
-                                                                                image->descriptor.id;
-@@ -6797,11 +6797,12 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-     if (simage->descriptor.flags & SPICE_IMAGE_FLAGS_HIGH_BITS_SET) {
-         image.descriptor.flags = SPICE_IMAGE_FLAGS_HIGH_BITS_SET;
-     }
-+    pthread_mutex_lock(&dcc->pixmap_cache->lock);
- 
-     if ((simage->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME)) {
-         int lossy_cache_item;
--        if (pixmap_cache_hit(dcc->pixmap_cache, image.descriptor.id,
--                             &lossy_cache_item, dcc)) {
-+        if (pixmap_cache_unlocked_hit(dcc->pixmap_cache, image.descriptor.id,
-+                                      &lossy_cache_item, dcc)) {
-             dcc->send_data.pixmap_cache_items[dcc->send_data.num_pixmap_cache_items++] =
-                                                                                image.descriptor.id;
-             if (can_lossy || !lossy_cache_item) {
-@@ -6818,10 +6819,11 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-                 spice_assert(bitmap_palette_out == NULL);
-                 spice_assert(lzplt_palette_out == NULL);
-                 stat_inc_counter(display_channel->cache_hits_counter, 1);
-+                pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-                 return FILL_BITS_TYPE_CACHE;
-             } else {
--                pixmap_cache_set_lossy(dcc->pixmap_cache, simage->descriptor.id,
--                                       FALSE);
-+                pixmap_cache_unlocked_set_lossy(dcc->pixmap_cache, simage->descriptor.id,
-+                                                FALSE);
-                 image.descriptor.flags |= SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME;
-             }
-         }
-@@ -6835,6 +6837,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-         surface_id = simage->u.surface.surface_id;
-         if (!validate_surface(worker, surface_id)) {
-             rendering_incorrect("SPICE_IMAGE_TYPE_SURFACE");
-+            pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-             return FILL_BITS_TYPE_SURFACE;
-         }
- 
-@@ -6849,6 +6852,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-                              &bitmap_palette_out, &lzplt_palette_out);
-         spice_assert(bitmap_palette_out == NULL);
-         spice_assert(lzplt_palette_out == NULL);
-+        pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-         return FILL_BITS_TYPE_SURFACE;
-     }
-     case SPICE_IMAGE_TYPE_BITMAP: {
-@@ -6879,6 +6883,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-             }
- 
-             spice_marshaller_add_ref_chunks(m, bitmap->data);
-+            pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-             return FILL_BITS_TYPE_BITMAP;
-         } else {
-             red_display_add_image_to_pixmap_cache(rcc, simage, &image,
-@@ -6896,6 +6901,7 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-             }
- 
-             spice_assert(!comp_send_data.is_lossy || can_lossy);
-+            pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-             return (comp_send_data.is_lossy ? FILL_BITS_TYPE_COMPRESS_LOSSY :
-                                               FILL_BITS_TYPE_COMPRESS_LOSSLESS);
-         }
-@@ -6909,11 +6915,12 @@ static FillBitsType fill_bits(DisplayChannelClient *dcc, SpiceMarshaller *m,
-         spice_assert(bitmap_palette_out == NULL);
-         spice_assert(lzplt_palette_out == NULL);
-         spice_marshaller_add_ref_chunks(m, image.u.quic.data);
-+        pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-         return FILL_BITS_TYPE_COMPRESS_LOSSLESS;
-     default:
-         spice_error("invalid image type %u", image.descriptor.type);
-     }
--
-+    pthread_mutex_unlock(&dcc->pixmap_cache->lock);
-     return 0;
- }
- 
diff --git a/SOURCES/0045-reds-Assure-we-don-t-have-stale-statistic-files-befo.patch b/SOURCES/0045-reds-Assure-we-don-t-have-stale-statistic-files-befo.patch
deleted file mode 100644
index 35614e0..0000000
--- a/SOURCES/0045-reds-Assure-we-don-t-have-stale-statistic-files-befo.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Wed, 15 Jul 2015 14:15:52 +0100
-Subject: [PATCH] reds: Assure we don't have stale statistic files before
- trying to create a new one
-
-If a previous Qemu executable is not able to delete the statistic file
-on the next creation with same name (statitics file are based on pid
-numbers so if pid get reused for another Qemu process you get the same
-name) it fails as you can't open a file with 0444 permissions (these
-are the permission used to create these files).
-This patch assure there are no stale file trying to remove it before the
-creation of the new one. As file is based on pid and name used for spice
-you are not deleting another file.
-
-Fixes: rhbz#1177326
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/reds.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/server/reds.c b/server/reds.c
-index f996c71..e96f28d 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -4011,6 +4011,7 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
-     shm_name_len = strlen(SPICE_STAT_SHM_NAME) + 20;
-     reds->stat_shm_name = (char *)spice_malloc(shm_name_len);
-     snprintf(reds->stat_shm_name, shm_name_len, SPICE_STAT_SHM_NAME, getpid());
-+    shm_unlink(reds->stat_shm_name);
-     if ((fd = shm_open(reds->stat_shm_name, O_CREAT | O_RDWR, 0444)) == -1) {
-         spice_error("statistics shm_open failed, %s", strerror(errno));
-     }
diff --git a/SOURCES/0046-worker-validate-correctly-surfaces.patch b/SOURCES/0046-worker-validate-correctly-surfaces.patch
deleted file mode 100644
index 4c83112..0000000
--- a/SOURCES/0046-worker-validate-correctly-surfaces.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Wed, 9 Sep 2015 12:42:09 +0100
-Subject: [PATCH] worker: validate correctly surfaces
-
-Do not just give warning and continue to use an invalid index into
-an array.
-
-Resolves: CVE-2015-5260
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_worker.c | 33 ++++++++++++++++++---------------
- 1 file changed, 18 insertions(+), 15 deletions(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index 93e3398..c62dbcb 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -1054,6 +1054,7 @@ typedef struct BitmapData {
-     SpiceRect lossy_rect;
- } BitmapData;
- 
-+static inline int validate_surface(RedWorker *worker, uint32_t surface_id);
- static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable);
- static void red_current_flush(RedWorker *worker, int surface_id);
- #ifdef DRAW_ALL
-@@ -1267,11 +1268,6 @@ static inline int is_primary_surface(RedWorker *worker, uint32_t surface_id)
-     return FALSE;
- }
- 
--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;
-@@ -1280,7 +1276,7 @@ static int validate_drawable_bbox(RedWorker *worker, RedDrawable *drawable)
-         /* surface_id must be validated before calling into
-          * validate_drawable_bbox
-          */
--        __validate_surface(worker, surface_id);
-+        VALIDATE_SURFACE_RETVAL(worker, surface_id, FALSE);
-         context = &worker->surfaces[surface_id].context;
- 
-         if (drawable->bbox.top < 0)
-@@ -1301,7 +1297,10 @@ static int validate_drawable_bbox(RedWorker *worker, RedDrawable *drawable)
- 
- static inline int validate_surface(RedWorker *worker, uint32_t surface_id)
- {
--    spice_warn_if(surface_id >= worker->n_surfaces);
-+    if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) {
-+        spice_warning("invalid surface_id %u", surface_id);
-+        return 0;
-+    }
-     if (!worker->surfaces[surface_id].context.canvas) {
-         spice_warning("canvas address is %p for %d (and is NULL)\n",
-                    &(worker->surfaces[surface_id].context.canvas), surface_id);
-@@ -4304,12 +4303,14 @@ static inline void red_create_surface(RedWorker *worker, uint32_t surface_id,uin
- static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface,
-                                        uint32_t group_id, int loadvm)
- {
--    int surface_id;
-+    uint32_t surface_id;
-     RedSurface *red_surface;
-     uint8_t *data;
- 
-     surface_id = surface->surface_id;
--    __validate_surface(worker, surface_id);
-+    if SPICE_UNLIKELY(surface_id >= worker->n_surfaces) {
-+        goto exit;
-+    }
- 
-     red_surface = &worker->surfaces[surface_id];
- 
-@@ -4345,6 +4346,7 @@ static inline void red_process_surface(RedWorker *worker, RedSurfaceCmd *surface
-     default:
-             spice_error("unknown surface command");
-     };
-+exit:
-     red_put_surface_cmd(surface);
-     free(surface);
- }
-@@ -11091,7 +11093,7 @@ void handle_dev_update(void *opaque, void *payload)
- {
-     RedWorker *worker = opaque;
-     RedWorkerMessageUpdate *msg = payload;
--    SpiceRect *rect = spice_new0(SpiceRect, 1);
-+    SpiceRect *rect;
-     RedSurface *surface;
-     uint32_t surface_id = msg->surface_id;
-     const QXLRect *qxl_area = msg->qxl_area;
-@@ -11099,17 +11101,16 @@ void handle_dev_update(void *opaque, void *payload)
-     QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects;
-     uint32_t clear_dirty_region = msg->clear_dirty_region;
- 
-+    VALIDATE_SURFACE_RET(worker, surface_id);
-+
-+    rect = spice_new0(SpiceRect, 1);
-     surface = &worker->surfaces[surface_id];
-     red_get_rect_ptr(rect, qxl_area);
-     flush_display_commands(worker);
- 
-     spice_assert(worker->running);
- 
--    if (validate_surface(worker, surface_id)) {
--        red_update_area(worker, rect, surface_id);
--    } else {
--        rendering_incorrect(__func__);
--    }
-+    red_update_area(worker, rect, surface_id);
-     free(rect);
- 
-     surface_dirty_region_to_rects(surface, qxl_dirty_rects, num_dirty_rects,
-@@ -11148,6 +11149,7 @@ void handle_dev_del_memslot(void *opaque, void *payload)
-  * surface_id == 0, maybe move the assert upward and merge the two functions? */
- static inline void destroy_surface_wait(RedWorker *worker, int surface_id)
- {
-+    VALIDATE_SURFACE_RET(worker, surface_id);
-     if (!worker->surfaces[surface_id].context.canvas) {
-         return;
-     }
-@@ -11412,6 +11414,7 @@ void handle_dev_create_primary_surface(void *opaque, void *payload)
- 
- static void dev_destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
- {
-+    VALIDATE_SURFACE_RET(worker, surface_id);
-     spice_warn_if(surface_id != 0);
- 
-     spice_debug(NULL);
diff --git a/SOURCES/0047-worker-avoid-double-free-or-double-create-of-surface.patch b/SOURCES/0047-worker-avoid-double-free-or-double-create-of-surface.patch
deleted file mode 100644
index 5565ad2..0000000
--- a/SOURCES/0047-worker-avoid-double-free-or-double-create-of-surface.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Wed, 9 Sep 2015 12:45:06 +0100
-Subject: [PATCH] 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>
----
- server/red_worker.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index c62dbcb..a7eaab9 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -4320,6 +4320,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));
-@@ -4333,7 +4337,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(worker, surface_id, 0, 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.
diff --git a/SOURCES/0048-Define-a-constant-to-limit-data-from-guest.patch b/SOURCES/0048-Define-a-constant-to-limit-data-from-guest.patch
deleted file mode 100644
index 7ab58f5..0000000
--- a/SOURCES/0048-Define-a-constant-to-limit-data-from-guest.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 11:58:11 +0100
-Subject: [PATCH] Define a constant to limit data from guest.
-
-This limit will prevent guest trying to do nasty things and DoS to host.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 6c0b065..4449f2c 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -21,11 +21,22 @@
- 
- #include <stdbool.h>
- #include <inttypes.h>
-+#include <glib.h>
- #include "common/lz_common.h"
- #include "red_common.h"
- #include "red_memslots.h"
- #include "red_parse_qxl.h"
- 
-+/* Max size in bytes for any data field used in a QXL command.
-+ * This will for example be useful to prevent the guest from saturating the
-+ * host memory if it tries to send overlapping chunks.
-+ * This value should be big enough for all requests but limited
-+ * to 32 bits. Even better if it fits on 31 bits to detect integer overflows.
-+ */
-+#define MAX_DATA_CHUNK 0x7ffffffflu
-+
-+G_STATIC_ASSERT(MAX_DATA_CHUNK <= G_MAXINT32);
-+
- #if 0
- static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
-                         QXLPHYSICAL addr, uint8_t bytes)
diff --git a/SOURCES/0049-Fix-some-integer-overflow-causing-large-memory-alloc.patch b/SOURCES/0049-Fix-some-integer-overflow-causing-large-memory-alloc.patch
deleted file mode 100644
index e03bba2..0000000
--- a/SOURCES/0049-Fix-some-integer-overflow-causing-large-memory-alloc.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Thu, 17 Sep 2015 15:00:22 +0100
-Subject: [PATCH] Fix some integer overflow causing large memory allocations
-
-Prevent integer overflow when computing image sizes.
-Image index computations are done using 32 bit so this can cause easily
-security issues. MAX_DATA_CHUNK is larger than the virtual
-card limit, so this is not going to cause change in behaviours.
-Comparing size calculation results with MAX_DATA_CHUNK will allow us to
-catch overflows.
-Prevent guest from allocating large amount of memory.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 4449f2c..ceb2759 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -384,7 +384,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-     QXLImage *qxl;
-     SpiceImage *red = NULL;
-     SpicePalette *rp = NULL;
--    size_t bitmap_size, size;
-+    uint64_t bitmap_size, size;
-     uint8_t qxl_flags;
-     int error;
- 
-@@ -460,7 +460,10 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-             red->u.bitmap.palette = rp;
-             red->u.bitmap.palette_id = rp->unique;
-         }
--        bitmap_size = red->u.bitmap.y * abs(red->u.bitmap.stride);
-+        bitmap_size = (uint64_t) red->u.bitmap.y * red->u.bitmap.stride;
-+        if (bitmap_size > MAX_DATA_CHUNK) {
-+            goto error;
-+        }
-         if (qxl_flags & QXL_BITMAP_DIRECT) {
-             red->u.bitmap.data = red_get_image_data_flat(slots, group_id,
-                                                          qxl->bitmap.data,
-@@ -1220,7 +1223,7 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-                         RedSurfaceCmd *red, QXLPHYSICAL addr)
- {
-     QXLSurfaceCmd *qxl;
--    size_t size;
-+    uint64_t size;
-     int error;
- 
-     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-@@ -1240,7 +1243,11 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-         red->u.surface_create.width  = qxl->u.surface_create.width;
-         red->u.surface_create.height = qxl->u.surface_create.height;
-         red->u.surface_create.stride = qxl->u.surface_create.stride;
--        size = red->u.surface_create.height * abs(red->u.surface_create.stride);
-+        /* the multiplication can overflow, also abs(-2^31) may return a negative value */
-+        size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
-+        if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) {
-+            return 1;
-+        }
-         red->u.surface_create.data =
-             (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
-         if (error) {
diff --git a/SOURCES/0050-Check-properly-surface-to-be-created.patch b/SOURCES/0050-Check-properly-surface-to-be-created.patch
deleted file mode 100644
index 4e5297b..0000000
--- a/SOURCES/0050-Check-properly-surface-to-be-created.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 16:02:59 +0100
-Subject: [PATCH] Check properly surface to be created
-
-Check format is valid.
-Check stride is at least the size of required bytes for a row.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 35 ++++++++++++++++++++++++++++++++++-
- 1 file changed, 34 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index ceb2759..a7ca71d 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -1219,12 +1219,30 @@ void red_put_message(RedMessage *red)
-     /* nothing yet */
- }
- 
-+static unsigned int surface_format_to_bpp(uint32_t format)
-+{
-+    switch (format) {
-+    case SPICE_SURFACE_FMT_1_A:
-+        return 1;
-+    case SPICE_SURFACE_FMT_8_A:
-+        return 8;
-+    case SPICE_SURFACE_FMT_16_555:
-+    case SPICE_SURFACE_FMT_16_565:
-+        return 16;
-+    case SPICE_SURFACE_FMT_32_xRGB:
-+    case SPICE_SURFACE_FMT_32_ARGB:
-+        return 32;
-+    }
-+    return 0;
-+}
-+
- int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-                         RedSurfaceCmd *red, QXLPHYSICAL addr)
- {
-     QXLSurfaceCmd *qxl;
-     uint64_t size;
-     int error;
-+    unsigned int bpp;
- 
-     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                     &error);
-@@ -1243,9 +1261,24 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-         red->u.surface_create.width  = qxl->u.surface_create.width;
-         red->u.surface_create.height = qxl->u.surface_create.height;
-         red->u.surface_create.stride = qxl->u.surface_create.stride;
-+        bpp = surface_format_to_bpp(red->u.surface_create.format);
-+
-+        /* check if format is valid */
-+        if (!bpp) {
-+            return 1;
-+        }
-+
-+        /* check stride is larger than required bytes */
-+        size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u;
-+        /* the uint32_t conversion is here to avoid problems with -2^31 value */
-+        if (red->u.surface_create.stride == G_MININT32
-+            || size > (uint32_t) abs(red->u.surface_create.stride)) {
-+            return 1;
-+        }
-+
-         /* the multiplication can overflow, also abs(-2^31) may return a negative value */
-         size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
--        if (size > MAX_DATA_CHUNK || red->u.surface_create.stride == G_MININT32) {
-+        if (size > MAX_DATA_CHUNK) {
-             return 1;
-         }
-         red->u.surface_create.data =
diff --git a/SOURCES/0051-Fix-buffer-reading-overflow.patch b/SOURCES/0051-Fix-buffer-reading-overflow.patch
deleted file mode 100644
index 4a7a9cc..0000000
--- a/SOURCES/0051-Fix-buffer-reading-overflow.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 10:00:37 +0100
-Subject: [PATCH] Fix buffer reading overflow
-
-Not security risk as just for read.
-However, this could be used to attempt integer overflows in the
-following lines.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index a7ca71d..01cba0f 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -361,7 +361,14 @@ static const int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] = {0, 1, 1, 4, 4, 8, 16, 24,
- 
- static int bitmap_consistent(SpiceBitmap *bitmap)
- {
--    int bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format];
-+    int bpp;
-+
-+    if (bitmap->format >= SPICE_N_ELEMENTS(MAP_BITMAP_FMT_TO_BITS_PER_PIXEL)) {
-+        spice_warning("wrong format specified for image\n");
-+        return FALSE;
-+    }
-+
-+    bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format];
- 
-     if (bitmap->stride < ((bitmap->x * bpp + 7) / 8)) {
-         spice_error("image stride too small for width: %d < ((%d * %d + 7) / 8) (%s=%d)\n",
diff --git a/SOURCES/0052-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch b/SOURCES/0052-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch
deleted file mode 100644
index 5a990ad..0000000
--- a/SOURCES/0052-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 13:09:35 +0100
-Subject: [PATCH] Prevent 32 bit integer overflow in bitmap_consistent
-
-The overflow may lead to buffer overflow as the row size computed from
-width (bitmap->x) can be bigger than the size in bytes (bitmap->stride).
-This can make spice-server accept the invalid sizes.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 9 +++++----
- 1 file changed, 5 insertions(+), 4 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 01cba0f..3385f52 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -357,11 +357,12 @@ static const char *bitmap_format_to_string(int format)
-     return "unknown";
- }
- 
--static const int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] = {0, 1, 1, 4, 4, 8, 16, 24, 32, 32, 8};
-+static const unsigned int MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[] =
-+    {0, 1, 1, 4, 4, 8, 16, 24, 32, 32, 8};
- 
- static int bitmap_consistent(SpiceBitmap *bitmap)
- {
--    int bpp;
-+    unsigned int bpp;
- 
-     if (bitmap->format >= SPICE_N_ELEMENTS(MAP_BITMAP_FMT_TO_BITS_PER_PIXEL)) {
-         spice_warning("wrong format specified for image\n");
-@@ -370,8 +371,8 @@ static int bitmap_consistent(SpiceBitmap *bitmap)
- 
-     bpp = MAP_BITMAP_FMT_TO_BITS_PER_PIXEL[bitmap->format];
- 
--    if (bitmap->stride < ((bitmap->x * bpp + 7) / 8)) {
--        spice_error("image stride too small for width: %d < ((%d * %d + 7) / 8) (%s=%d)\n",
-+    if (bitmap->stride < (((uint64_t) bitmap->x * bpp + 7u) / 8u)) {
-+        spice_warning("image stride too small for width: %d < ((%d * %d + 7) / 8) (%s=%d)\n",
-                     bitmap->stride, bitmap->x, bpp,
-                     bitmap_format_to_string(bitmap->format),
-                     bitmap->format);
diff --git a/SOURCES/0053-Fix-race-condition-on-red_get_clip_rects.patch b/SOURCES/0053-Fix-race-condition-on-red_get_clip_rects.patch
deleted file mode 100644
index 83ebfe1..0000000
--- a/SOURCES/0053-Fix-race-condition-on-red_get_clip_rects.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 10:01:51 +0100
-Subject: [PATCH] Fix race condition on red_get_clip_rects
-
-Do not read multiple time an array size that can be changed.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 3385f52..affd3a2 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -273,6 +273,7 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id,
-     size_t size;
-     int i;
-     int error;
-+    uint32_t num_rects;
- 
-     qxl = (QXLClipRects *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
-     if (error) {
-@@ -284,9 +285,10 @@ static SpiceClipRects *red_get_clip_rects(RedMemSlotInfo *slots, int group_id,
-     data = red_linearize_chunk(&chunks, size, &free_data);
-     red_put_data_chunks(&chunks);
- 
--    spice_assert(qxl->num_rects * sizeof(QXLRect) == size);
--    red = spice_malloc(sizeof(*red) + qxl->num_rects * sizeof(SpiceRect));
--    red->num_rects = qxl->num_rects;
-+    num_rects = qxl->num_rects;
-+    spice_assert(num_rects * sizeof(QXLRect) == size);
-+    red = spice_malloc(sizeof(*red) + num_rects * sizeof(SpiceRect));
-+    red->num_rects = num_rects;
- 
-     start = (QXLRect*)data;
-     for (i = 0; i < red->num_rects; i++) {
diff --git a/SOURCES/0054-Fix-race-in-red_get_image.patch b/SOURCES/0054-Fix-race-in-red_get_image.patch
deleted file mode 100644
index fa53795..0000000
--- a/SOURCES/0054-Fix-race-in-red_get_image.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 10:04:10 +0100
-Subject: [PATCH] Fix race in red_get_image
-
-Do not read multiple times data from guest as this could be changed
-by other vcpu threads.
-This causes races and security problems if these data are used for
-buffer allocation or checks.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index affd3a2..84ea526 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -397,6 +397,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-     uint64_t bitmap_size, size;
-     uint8_t qxl_flags;
-     int error;
-+    QXLPHYSICAL palette;
- 
-     if (addr == 0) {
-         return NULL;
-@@ -422,12 +423,16 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-     switch (red->descriptor.type) {
-     case SPICE_IMAGE_TYPE_BITMAP:
-         red->u.bitmap.format = qxl->bitmap.format;
--        if (!bitmap_fmt_is_rgb(qxl->bitmap.format) && !qxl->bitmap.palette && !is_mask) {
-+        red->u.bitmap.x      = qxl->bitmap.x;
-+        red->u.bitmap.y      = qxl->bitmap.y;
-+        red->u.bitmap.stride = qxl->bitmap.stride;
-+        palette = qxl->bitmap.palette;
-+        if (!bitmap_fmt_is_rgb(red->u.bitmap.format) && !palette && !is_mask) {
-             spice_warning("guest error: missing palette on bitmap format=%d\n",
-                           red->u.bitmap.format);
-             goto error;
-         }
--        if (qxl->bitmap.x == 0 || qxl->bitmap.y == 0) {
-+        if (red->u.bitmap.x == 0 || red->u.bitmap.y == 0) {
-             spice_warning("guest error: zero area bitmap\n");
-             goto error;
-         }
-@@ -435,23 +440,20 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-         if (qxl_flags & QXL_BITMAP_TOP_DOWN) {
-             red->u.bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN;
-         }
--        red->u.bitmap.x      = qxl->bitmap.x;
--        red->u.bitmap.y      = qxl->bitmap.y;
--        red->u.bitmap.stride = qxl->bitmap.stride;
-         if (!bitmap_consistent(&red->u.bitmap)) {
-             goto error;
-         }
--        if (qxl->bitmap.palette) {
-+        if (palette) {
-             QXLPalette *qp;
-             int i, num_ents;
--            qp = (QXLPalette *)get_virt(slots, qxl->bitmap.palette,
-+            qp = (QXLPalette *)get_virt(slots, palette,
-                                         sizeof(*qp), group_id, &error);
-             if (error) {
-                 goto error;
-             }
-             num_ents = qp->num_ents;
-             if (!validate_virt(slots, (intptr_t)qp->ents,
--                               get_memslot_id(slots, qxl->bitmap.palette),
-+                               get_memslot_id(slots, palette),
-                                num_ents * sizeof(qp->ents[0]), group_id)) {
-                 goto error;
-             }
diff --git a/SOURCES/0055-Fix-race-condition-in-red_get_string.patch b/SOURCES/0055-Fix-race-condition-in-red_get_string.patch
deleted file mode 100644
index 5e7a716..0000000
--- a/SOURCES/0055-Fix-race-condition-in-red_get_string.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 10:05:20 +0100
-Subject: [PATCH] Fix race condition in red_get_string
-
-Do not read multiple time an array size that can be changed.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 84ea526..2d4636e 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -809,6 +809,7 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-     size_t chunk_size, qxl_size, red_size, glyph_size;
-     int glyphs, bpp = 0, i;
-     int error;
-+    uint16_t qxl_flags, qxl_length;
- 
-     qxl = (QXLString *)get_virt(slots, addr, sizeof(*qxl), group_id, &error);
-     if (error) {
-@@ -825,13 +826,15 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-     red_put_data_chunks(&chunks);
- 
-     qxl_size = qxl->data_size;
-+    qxl_flags = qxl->flags;
-+    qxl_length = qxl->length;
-     spice_assert(chunk_size == qxl_size);
- 
--    if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A1) {
-+    if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A1) {
-         bpp = 1;
--    } else if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A4) {
-+    } else if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A4) {
-         bpp = 4;
--    } else if (qxl->flags & SPICE_STRING_FLAGS_RASTER_A8) {
-+    } else if (qxl_flags & SPICE_STRING_FLAGS_RASTER_A8) {
-         bpp = 8;
-     }
-     spice_assert(bpp != 0);
-@@ -848,11 +851,11 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
-     }
-     spice_assert(start <= end);
--    spice_assert(glyphs == qxl->length);
-+    spice_assert(glyphs == qxl_length);
- 
-     red = spice_malloc(red_size);
--    red->length = qxl->length;
--    red->flags = qxl->flags;
-+    red->length = qxl_length;
-+    red->flags = qxl_flags;
- 
-     start = (QXLRasterGlyph*)data;
-     end = (QXLRasterGlyph*)(data + chunk_size);
diff --git a/SOURCES/0056-Fix-integer-overflow-computing-glyph_size-in-red_get.patch b/SOURCES/0056-Fix-integer-overflow-computing-glyph_size-in-red_get.patch
deleted file mode 100644
index 34a462f..0000000
--- a/SOURCES/0056-Fix-integer-overflow-computing-glyph_size-in-red_get.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 10:13:24 +0100
-Subject: [PATCH] Fix integer overflow computing glyph_size in red_get_string
-
-If bpp is int the formula can lead to weird overflows. width and height
-are uint16_t so the formula is:
-
-  size_t = u16 * (u16 * int + const_int) / const_int;
-
-so it became
-
-  size_t = (int) u16 * ((int) u16 * int + const_int) / const_int;
-
-However the (int) u16 * (int) u16 can then became negative to overflow.
-Under 64 bit architectures size_t is 64 and int usually 32 so converting
-this negative 32 bit number to a unsigned 64 bit lead to a very big
-number as the signed is extended and then converted to unsigned.
-Using unsigned arithmetic prevent extending the sign.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 2d4636e..c4b82be 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -807,7 +807,9 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-     uint8_t *data;
-     bool free_data;
-     size_t chunk_size, qxl_size, red_size, glyph_size;
--    int glyphs, bpp = 0, i;
-+    int glyphs, i;
-+    /* use unsigned to prevent integer overflow in multiplication below */
-+    unsigned int bpp = 0;
-     int error;
-     uint16_t qxl_flags, qxl_length;
- 
-@@ -846,7 +848,7 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-     while (start < end) {
-         spice_assert((QXLRasterGlyph*)(&start->data[0]) <= end);
-         glyphs++;
--        glyph_size = start->height * ((start->width * bpp + 7) / 8);
-+        glyph_size = start->height * ((start->width * bpp + 7u) / 8u);
-         red_size += sizeof(SpiceRasterGlyph *) + SPICE_ALIGN(sizeof(SpiceRasterGlyph) + glyph_size, 4);
-         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
-     }
-@@ -867,7 +869,7 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-         glyph->height = start->height;
-         red_get_point_ptr(&glyph->render_pos, &start->render_pos);
-         red_get_point_ptr(&glyph->glyph_origin, &start->glyph_origin);
--        glyph_size = glyph->height * ((glyph->width * bpp + 7) / 8);
-+        glyph_size = glyph->height * ((glyph->width * bpp + 7u) / 8u);
-         spice_assert((QXLRasterGlyph*)(&start->data[glyph_size]) <= end);
-         memcpy(glyph->data, start->data, glyph_size);
-         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
diff --git a/SOURCES/0057-Fix-race-condition-in-red_get_data_chunks_ptr.patch b/SOURCES/0057-Fix-race-condition-in-red_get_data_chunks_ptr.patch
deleted file mode 100644
index e17c267..0000000
--- a/SOURCES/0057-Fix-race-condition-in-red_get_data_chunks_ptr.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 12:12:19 +0100
-Subject: [PATCH] Fix race condition in red_get_data_chunks_ptr
-
-Do not read multiple times data from guest as this can be changed by
-other guest vcpus. This causes races and security problems if these
-data are used for buffer allocation or checks.
-
-Actually, the 'data' member can't change during read as it is just a
-pointer to a fixed array contained in qxl. However, this change will
-make it clear that there can be no race condition.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 17 ++++++++++-------
- 1 file changed, 10 insertions(+), 7 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index c4b82be..7cc20e6 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -102,30 +102,33 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
-     RedDataChunk *red_prev;
-     size_t data_size = 0;
-     int error;
-+    QXLPHYSICAL next_chunk;
- 
-     red->data_size = qxl->data_size;
-     data_size += red->data_size;
--    if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) {
-+    red->data = qxl->data;
-+    if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
-+        red->data = NULL;
-         return 0;
-     }
--    red->data = qxl->data;
-     red->prev_chunk = NULL;
- 
--    while (qxl->next_chunk) {
-+    while ((next_chunk = qxl->next_chunk) != 0) {
-         red_prev = red;
-         red = spice_new(RedDataChunk, 1);
--        memslot_id = get_memslot_id(slots, qxl->next_chunk);
--        qxl = (QXLDataChunk *)get_virt(slots, qxl->next_chunk, sizeof(*qxl), group_id,
-+        memslot_id = get_memslot_id(slots, next_chunk);
-+        qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id,
-                                       &error);
-         if (error) {
-             return 0;
-         }
-         red->data_size = qxl->data_size;
-         data_size += red->data_size;
--        if (!validate_virt(slots, (intptr_t)qxl->data, memslot_id, red->data_size, group_id)) {
-+        red->data = qxl->data;
-+        if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
-+            red->data = NULL;
-             return 0;
-         }
--        red->data = qxl->data;
-         red->prev_chunk = red_prev;
-         red_prev->next_chunk = red;
-     }
diff --git a/SOURCES/0058-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch b/SOURCES/0058-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch
deleted file mode 100644
index 34a3f83..0000000
--- a/SOURCES/0058-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 12:14:55 +0100
-Subject: [PATCH] Prevent memory leak if red_get_data_chunks_ptr fails
-
-Free linked list if client tries to do nasty things
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 31 ++++++++++++++++++++-----------
- 1 file changed, 20 insertions(+), 11 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 7cc20e6..fe3ae78 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -107,34 +107,43 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
-     red->data_size = qxl->data_size;
-     data_size += red->data_size;
-     red->data = qxl->data;
-+    red->prev_chunk = red->next_chunk = NULL;
-     if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
-         red->data = NULL;
-         return 0;
-     }
--    red->prev_chunk = NULL;
- 
-     while ((next_chunk = qxl->next_chunk) != 0) {
-         red_prev = red;
--        red = spice_new(RedDataChunk, 1);
-+        red = spice_new0(RedDataChunk, 1);
-+        red->prev_chunk = red_prev;
-+        red_prev->next_chunk = red;
-+
-         memslot_id = get_memslot_id(slots, next_chunk);
-         qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id,
-                                       &error);
--        if (error) {
--            return 0;
--        }
-+        if (error)
-+            goto error;
-         red->data_size = qxl->data_size;
-         data_size += red->data_size;
-         red->data = qxl->data;
--        if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id)) {
--            red->data = NULL;
--            return 0;
--        }
--        red->prev_chunk = red_prev;
--        red_prev->next_chunk = red;
-+        if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id))
-+            goto error;
-     }
- 
-     red->next_chunk = NULL;
-     return data_size;
-+
-+error:
-+    while (red->prev_chunk) {
-+        red_prev = red->prev_chunk;
-+        free(red);
-+        red = red_prev;
-+    }
-+    red->data_size = 0;
-+    red->next_chunk = NULL;
-+    red->data = NULL;
-+    return 0;
- }
- 
- static size_t red_get_data_chunks(RedMemSlotInfo *slots, int group_id,
diff --git a/SOURCES/0059-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch b/SOURCES/0059-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch
deleted file mode 100644
index 88d955a..0000000
--- a/SOURCES/0059-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 12:28:54 +0100
-Subject: [PATCH] Prevent DoS from guest trying to allocate too much data on
- host for chunks
-
-Limit number of chunks to a given amount to avoid guest trying to
-allocate too much memory. Using circular or nested chunks lists
-guest could try to allocate huge amounts of memory.
-Considering the list can be infinite and guest can change data this
-also prevents strange security attacks from guest.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 41 insertions(+), 8 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index fe3ae78..f183248 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -37,6 +37,13 @@
- 
- G_STATIC_ASSERT(MAX_DATA_CHUNK <= G_MAXINT32);
- 
-+/* Limit number of chunks.
-+ * The guest can attempt to make host allocate too much memory
-+ * just with a large number of small chunks.
-+ * Prevent that the chunk list take more memory than the data itself.
-+ */
-+#define MAX_CHUNKS (MAX_DATA_CHUNK/1024u)
-+
- #if 0
- static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
-                         QXLPHYSICAL addr, uint8_t bytes)
-@@ -100,9 +107,11 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
-                                       RedDataChunk *red, QXLDataChunk *qxl)
- {
-     RedDataChunk *red_prev;
--    size_t data_size = 0;
-+    uint64_t data_size = 0;
-+    uint32_t chunk_data_size;
-     int error;
-     QXLPHYSICAL next_chunk;
-+    unsigned num_chunks = 0;
- 
-     red->data_size = qxl->data_size;
-     data_size += red->data_size;
-@@ -114,19 +123,43 @@ static size_t red_get_data_chunks_ptr(RedMemSlotInfo *slots, int group_id,
-     }
- 
-     while ((next_chunk = qxl->next_chunk) != 0) {
-+        /* somebody is trying to use too much memory using a lot of chunks.
-+         * Or made a circular list of chunks
-+         */
-+        if (++num_chunks >= MAX_CHUNKS) {
-+            spice_warning("data split in too many chunks, avoiding DoS\n");
-+            goto error;
-+        }
-+
-+        memslot_id = get_memslot_id(slots, next_chunk);
-+        qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl),
-+                                       group_id, &error);
-+        if (error)
-+            goto error;
-+
-+        /* do not waste space for empty chunks.
-+         * This could be just a driver issue or an attempt
-+         * to allocate too much memory or a circular list.
-+         * All above cases are handled by the check for number
-+         * of chunks.
-+         */
-+        chunk_data_size = qxl->data_size;
-+        if (chunk_data_size == 0)
-+            continue;
-+
-         red_prev = red;
-         red = spice_new0(RedDataChunk, 1);
-+        red->data_size = chunk_data_size;
-         red->prev_chunk = red_prev;
-+        red->data = qxl->data;
-         red_prev->next_chunk = red;
- 
--        memslot_id = get_memslot_id(slots, next_chunk);
--        qxl = (QXLDataChunk *)get_virt(slots, next_chunk, sizeof(*qxl), group_id,
--                                      &error);
--        if (error)
-+        data_size += chunk_data_size;
-+        /* this can happen if client is sending nested chunks */
-+        if (data_size > MAX_DATA_CHUNK) {
-+            spice_warning("too much data inside chunks, avoiding DoS\n");
-             goto error;
--        red->data_size = qxl->data_size;
--        data_size += red->data_size;
--        red->data = qxl->data;
-+        }
-         if (!validate_virt(slots, (intptr_t)red->data, memslot_id, red->data_size, group_id))
-             goto error;
-     }
diff --git a/SOURCES/0060-Fix-some-possible-overflows-in-red_get_string-for-32.patch b/SOURCES/0060-Fix-some-possible-overflows-in-red_get_string-for-32.patch
deleted file mode 100644
index ca0dff1..0000000
--- a/SOURCES/0060-Fix-some-possible-overflows-in-red_get_string-for-32.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 8 Sep 2015 13:06:03 +0100
-Subject: [PATCH] Fix some possible overflows in red_get_string for 32 bit
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index f183248..668ce10 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -895,6 +895,11 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-         glyphs++;
-         glyph_size = start->height * ((start->width * bpp + 7u) / 8u);
-         red_size += sizeof(SpiceRasterGlyph *) + SPICE_ALIGN(sizeof(SpiceRasterGlyph) + glyph_size, 4);
-+        /* do the test correctly, we know end - start->data[0] cannot
-+         * overflow, don't use start->data[glyph_size] to test for
-+         * buffer overflow as this on 32 bit can cause overflow
-+         * on the pointer arithmetic */
-+        spice_assert(glyph_size <= (char*) end - (char*) &start->data[0]);
-         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
-     }
-     spice_assert(start <= end);
-@@ -915,7 +920,8 @@ static SpiceString *red_get_string(RedMemSlotInfo *slots, int group_id,
-         red_get_point_ptr(&glyph->render_pos, &start->render_pos);
-         red_get_point_ptr(&glyph->glyph_origin, &start->glyph_origin);
-         glyph_size = glyph->height * ((glyph->width * bpp + 7u) / 8u);
--        spice_assert((QXLRasterGlyph*)(&start->data[glyph_size]) <= end);
-+        /* see above for similar test */
-+        spice_assert(glyph_size <= (char*) end - (char*) &start->data[0]);
-         memcpy(glyph->data, start->data, glyph_size);
-         start = (QXLRasterGlyph*)(&start->data[glyph_size]);
-         glyph = (SpiceRasterGlyph*)
diff --git a/SOURCES/0061-Make-sure-we-can-read-QXLPathSeg-structures.patch b/SOURCES/0061-Make-sure-we-can-read-QXLPathSeg-structures.patch
deleted file mode 100644
index dd68ace..0000000
--- a/SOURCES/0061-Make-sure-we-can-read-QXLPathSeg-structures.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 15 Sep 2015 16:25:17 +0100
-Subject: [PATCH] Make sure we can read QXLPathSeg structures
-
-start pointer points to a QXLPathSeg structure.
-Before reading from the structure, make sure the structure is contained
-in the memory range checked.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 668ce10..4663bfd 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -256,7 +256,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
- 
-     start = (QXLPathSeg*)data;
-     end = (QXLPathSeg*)(data + size);
--    while (start < end) {
-+    while (start+1 < end) {
-         n_segments++;
-         count = start->count;
-         segment_size = sizeof(SpicePathSeg) + count * sizeof(SpicePointFix);
-@@ -272,7 +272,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
-     seg = (SpicePathSeg*)&red->segments[n_segments];
-     n_segments = 0;
-     mem_size2 = sizeof(*red);
--    while (start < end) {
-+    while (start+1 < end) {
-         red->segments[n_segments++] = seg;
-         count = start->count;
- 
diff --git a/SOURCES/0062-Avoid-race-condition-copying-segments-in-red_get_pat.patch b/SOURCES/0062-Avoid-race-condition-copying-segments-in-red_get_pat.patch
deleted file mode 100644
index c6f4253..0000000
--- a/SOURCES/0062-Avoid-race-condition-copying-segments-in-red_get_pat.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 15 Sep 2015 16:38:23 +0100
-Subject: [PATCH] Avoid race condition copying segments in red_get_path
-
-The guest can attempt to increase the number of segments while
-spice-server is reading them.
-Make sure we don't copy more then the allocated segments.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
----
- server/red_parse_qxl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 4663bfd..c1df8e8 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -272,7 +272,7 @@ static SpicePath *red_get_path(RedMemSlotInfo *slots, int group_id,
-     seg = (SpicePathSeg*)&red->segments[n_segments];
-     n_segments = 0;
-     mem_size2 = sizeof(*red);
--    while (start+1 < end) {
-+    while (start+1 < end && n_segments < red->num_segments) {
-         red->segments[n_segments++] = seg;
-         count = start->count;
- 
diff --git a/SOURCES/0063-Prevent-data_size-to-be-set-independently-from-data.patch b/SOURCES/0063-Prevent-data_size-to-be-set-independently-from-data.patch
deleted file mode 100644
index 4cbe23b..0000000
--- a/SOURCES/0063-Prevent-data_size-to-be-set-independently-from-data.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Thu, 17 Sep 2015 14:28:36 +0100
-Subject: [PATCH] Prevent data_size to be set independently from data
-
-There was not check for data_size field so one could set data to
-a small set of data and data_size much bigger than size of data
-leading to buffer overflow.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index c1df8e8..8e3dd55 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -1391,6 +1391,7 @@ static int red_get_cursor(RedMemSlotInfo *slots, int group_id,
-     size = red_get_data_chunks_ptr(slots, group_id,
-                                    get_memslot_id(slots, addr),
-                                    &chunks, &qxl->chunk);
-+    red->data_size = MIN(red->data_size, size);
-     data = red_linearize_chunk(&chunks, size, &free_data);
-     red_put_data_chunks(&chunks);
-     if (free_data) {
diff --git a/SOURCES/0064-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch b/SOURCES/0064-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch
deleted file mode 100644
index a0bbb61..0000000
--- a/SOURCES/0064-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Thu, 17 Sep 2015 15:01:05 +0100
-Subject: [PATCH] Prevent leak if size from red_get_data_chunks don't match in
- red_get_image
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index 8e3dd55..bd0c408 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -530,6 +530,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-                                        &chunks, qxl->bitmap.data);
-             spice_assert(size == bitmap_size);
-             if (size != bitmap_size) {
-+                red_put_data_chunks(&chunks);
-                 goto error;
-             }
-             red->u.bitmap.data = red_get_image_data_chunked(slots, group_id,
-@@ -550,6 +551,7 @@ static SpiceImage *red_get_image(RedMemSlotInfo *slots, int group_id,
-                                        &chunks, (QXLDataChunk *)qxl->quic.data);
-         spice_assert(size == red->u.quic.data_size);
-         if (size != red->u.quic.data_size) {
-+            red_put_data_chunks(&chunks);
-             goto error;
-         }
-         red->u.quic.data = red_get_image_data_chunked(slots, group_id,
diff --git a/SOURCES/0065-smartcard-add-a-ref-to-item-before-adding-to-pipe.patch b/SOURCES/0065-smartcard-add-a-ref-to-item-before-adding-to-pipe.patch
deleted file mode 100644
index 2d79fbb..0000000
--- a/SOURCES/0065-smartcard-add-a-ref-to-item-before-adding-to-pipe.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Marc-Andre Lureau <marcandre.lureau@redhat.com>
-Date: Thu, 17 Dec 2015 18:13:47 +0100
-Subject: [PATCH] smartcard: add a ref to item before adding to pipe
-
-There is an unref when the message is sent.
-
-==17204== ERROR: AddressSanitizer: heap-use-after-free on address 0x6008000144a8 at pc 0x7fffee0ce245 bp 0x7fffffffc630 sp 0x7fffffffc620
-READ of size 4 at 0x6008000144a8 thread T0
-    #0 0x7fffee0ce244 in smartcard_unref_vsc_msg_item /home/elmarco/src/spice/spice/server/smartcard.c:608
-    #1 0x7fffee0cb451 in smartcard_unref_msg_to_client /home/elmarco/src/spice/spice/server/smartcard.c:178
-    #2 0x7fffedfcdf14 in spice_char_device_read_from_device /home/elmarco/src/spice/spice/server/char-device.c:330
-    #3 0x7fffedfd1763 in spice_char_device_wakeup /home/elmarco/src/spice/spice/server/char-device.c:901
-    #4 0x7fffee05da98 in spice_server_char_device_wakeup /home/elmarco/src/spice/spice/server/reds.c:2990
-    #5 0x55555593fa34 in spice_chr_write /home/elmarco/src/qemu/spice-qemu-char.c:189
-    #6 0x5555559375f1 in qemu_chr_fe_write /home/elmarco/src/qemu/qemu-char.c:220
-    #7 0x555555b3b682 in ccid_card_vscard_send_msg.isra.2 /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:76
-    #8 0x555555b3c466 in ccid_card_vscard_send_error /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:91
-    #9 0x555555b3c466 in ccid_card_vscard_handle_message /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:242
-    #10 0x555555b3c466 in ccid_card_vscard_read /home/elmarco/src/qemu/hw/usb/ccid-card-passthru.c:289
-    #11 0x55555593f169 in vmc_write /home/elmarco/src/qemu/spice-qemu-char.c:41
-    #12 0x7fffedfcee6d in spice_char_device_write_to_device /home/elmarco/src/spice/spice/server/char-device.c:477
-    #13 0x7fffedfcfd31 in spice_char_device_write_buffer_add /home/elmarco/src/spice/spice/server/char-device.c:629
-    #14 0x7fffee0ce9df in smartcard_channel_write_to_reader /home/elmarco/src/spice/spice/server/smartcard.c:675
-    #15 0x7fffee0cc7db in smartcard_char_device_notify_reader_add /home/elmarco/src/spice/spice/server/smartcard.c:341
-    #16 0x7fffee0ce4f3 in smartcard_add_reader /home/elmarco/src/spice/spice/server/smartcard.c:648
-    #17 0x7fffee0cf2e2 in smartcard_channel_handle_message /home/elmarco/src/spice/spice/server/smartcard.c:763
-    #18 0x7fffedffe21f in red_peer_handle_incoming /home/elmarco/src/spice/spice/server/red-channel.c:307
-    #19 0x7fffedffe4f6 in red_channel_client_receive /home/elmarco/src/spice/spice/server/red-channel.c:325
-    #20 0x7fffee00726c in red_channel_client_event /home/elmarco/src/spice/spice/server/red-channel.c:1566
-    #21 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
-    #22 0x555555c3b800 in main_loop_wait /home/elmarco/src/qemu/main-loop.c:504
-    #23 0x5555556f160c in main_loop /home/elmarco/src/qemu/vl.c:1818
-    #24 0x5555556f160c in main /home/elmarco/src/qemu/vl.c:4394
-    #25 0x7fffed7d0b14 in __libc_start_main /usr/src/debug/glibc-2.17-c758a686/csu/libc-start.c:274
-    #26 0x5555556f9c20 in _start (/home/elmarco/src/qemu/x86_64-softmmu/qemu-system-x86_64+0x1a5c20)
-0x6008000144a8 is located 24 bytes inside of 40-byte region [0x600800014490,0x6008000144b8)
-freed by thread T0 here:
-    #0 0x7ffff4e61009 in __interceptor_free /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libsanitizer/asan/../../../../libsanitizer/asan/asan_malloc_linux.cc:61
-    #1 0x7fffee0ce2a1 in smartcard_unref_vsc_msg_item /home/elmarco/src/spice/spice/server/smartcard.c:610
-    #2 0x7fffee0cdd58 in smartcard_channel_release_pipe_item /home/elmarco/src/spice/spice/server/smartcard.c:548
-    #3 0x7fffee000668 in red_channel_client_release_item /home/elmarco/src/spice/spice/server/red-channel.c:602
-    #4 0x7fffee0006ef in red_channel_client_release_sent_item /home/elmarco/src/spice/spice/server/red-channel.c:609
-    #5 0x7fffee0007b5 in red_channel_peer_on_out_msg_done /home/elmarco/src/spice/spice/server/red-channel.c:620
-    #6 0x7fffedffed7e in red_peer_handle_outgoing /home/elmarco/src/spice/spice/server/red-channel.c:385
-    #7 0x7fffee0057bb in red_channel_client_send /home/elmarco/src/spice/spice/server/red-channel.c:1294
-    #8 0x7fffee0076e6 in red_channel_client_begin_send_message /home/elmarco/src/spice/spice/server/red-channel.c:1605
-    #9 0x7fffee0cdccd in smartcard_channel_send_item /home/elmarco/src/spice/spice/server/smartcard.c:541
-    #10 0x7fffee000570 in red_channel_client_send_item /home/elmarco/src/spice/spice/server/red-channel.c:588
-    #11 0x7fffee005bfb in red_channel_client_push /home/elmarco/src/spice/spice/server/red-channel.c:1347
-    #12 0x7fffee007ef7 in red_channel_client_pipe_add_push /home/elmarco/src/spice/spice/server/red-channel.c:1673
-    #13 0x7fffee0cde4d in smartcard_channel_client_pipe_add_push /home/elmarco/src/spice/spice/server/smartcard.c:571
-    #14 0x7fffee0cb567 in smartcard_send_msg_to_client /home/elmarco/src/spice/spice/server/smartcard.c:187
-    #15 0x7fffedfcdba2 in spice_char_device_send_msg_to_clients /home/elmarco/src/spice/spice/server/char-device.c:282
-    #16 0x7fffedfcdea4 in spice_char_device_read_from_device /home/elmarco/src/spice/spice/server/char-device.c:329
-    #17 0x7fffedfd1763 in spice_char_device_wakeup /home/elmarco/src/spice/spice/server/char-device.c:901
-    #18 0x7fffee05da98 in spice_server_char_device_wakeup /home/elmarco/src/spice/spice/server/reds.c:2990
-    #19 0x55555593fa34 in spice_chr_write /home/elmarco/src/qemu/spice-qemu-char.c:189
-
-Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
----
- server/smartcard.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/server/smartcard.c b/server/smartcard.c
-index aad22aa..8d529fe 100644
---- a/server/smartcard.c
-+++ b/server/smartcard.c
-@@ -172,14 +172,17 @@ static void smartcard_unref_msg_to_client(SpiceCharDeviceMsgToClient *msg,
-     smartcard_unref_vsc_msg_item((MsgItem *)msg);
- }
- 
--static void smartcard_send_msg_to_client(SpiceCharDeviceMsgToClient *msg,
-+static void smartcard_send_msg_to_client(SpiceCharDeviceMsgToClient *message,
-                                          RedClient *client,
-                                          void *opaque)
- {
-     SmartCardDeviceState *dev = opaque;
--    spice_assert(dev->scc && dev->scc->base.client == client);
--    smartcard_channel_client_pipe_add_push(&dev->scc->base, &((MsgItem *)msg)->base);
-+    MsgItem *msg = (MsgItem *)message;
-+    PipeItem *item = &msg->base;
- 
-+    spice_assert(dev->scc && dev->scc->base.client == client);
-+    smartcard_ref_vsc_msg_item(msg);
-+    smartcard_channel_client_pipe_add_push(&dev->scc->base, item);
- }
- 
- static void smartcard_send_tokens_to_client(RedClient *client, uint32_t tokens, void *opaque)
diff --git a/SOURCES/0066-smartcard-allocate-msg-with-the-expected-size.patch b/SOURCES/0066-smartcard-allocate-msg-with-the-expected-size.patch
deleted file mode 100644
index 671fc43..0000000
--- a/SOURCES/0066-smartcard-allocate-msg-with-the-expected-size.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Marc-Andre Lureau <marcandre.lureau@redhat.com>
-Date: Thu, 17 Dec 2015 18:16:22 +0100
-Subject: [PATCH] smartcard: allocate msg with the expected size
-
-==529== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60040009c098 at pc 0x7fffee0eda6d bp 0x7fffffffcd00 sp 0x7fffffffccf0
-WRITE of size 4 at 0x60040009c098 thread T0
-    #0 0x7fffee0eda6c in smartcard_char_device_notify_reader_add /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:334
-    #1 0x7fffee0ef783 in smartcard_add_reader /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:642
-    #2 0x7fffee0f0568 in smartcard_channel_handle_message /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:757
-    #3 0x7fffee032f3f in red_peer_handle_incoming /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:304
-    #4 0x7fffee033216 in red_channel_client_receive /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:322
-    #5 0x7fffee03bf1f in red_channel_client_event /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:1561
-    #6 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
-    #7 0x555555c3b800 in main_loop_wait /home/elmarco/src/qemu/main-loop.c:504
-    #8 0x5555556f160c in main_loop /home/elmarco/src/qemu/vl.c:1818
-    #9 0x5555556f160c in main /home/elmarco/src/qemu/vl.c:4394
-    #10 0x7fffed80eb14 in __libc_start_main /usr/src/debug/glibc-2.17-c758a686/csu/libc-start.c:274
-    #11 0x5555556f9c20 in _start (/home/elmarco/src/qemu/x86_64-softmmu/qemu-system-x86_64+0x1a5c20)
-0x60040009c098 is located 0 bytes to the right of 8-byte region [0x60040009c090,0x60040009c098)
-allocated by thread T0 here:
-    #0 0x7ffff4e612be in __interceptor_realloc /usr/src/debug/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/x86_64-redhat-linux/libsanitizer/asan/../../../../libsanitizer/asan/asan_malloc_linux.cc:92
-    #1 0x7fffee121308 in spice_realloc /home/elmarco/pkg/spice/spice-0.12.4/spice-common/common/mem.c:123
-    #2 0x7fffee004a48 in __spice_char_device_write_buffer_get /home/elmarco/pkg/spice/spice-0.12.4/server/char_device.c:516
-    #3 0x7fffee004e87 in spice_char_device_write_buffer_get /home/elmarco/pkg/spice/spice-0.12.4/server/char_device.c:557
-    #4 0x7fffee0ed8b9 in smartcard_char_device_notify_reader_add /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:325
-    #5 0x7fffee0ef783 in smartcard_add_reader /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:642
-    #6 0x7fffee0f0568 in smartcard_channel_handle_message /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:757
-    #7 0x7fffee032f3f in red_peer_handle_incoming /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:304
-    #8 0x7fffee033216 in red_channel_client_receive /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:322
-    #9 0x7fffee03bf1f in red_channel_client_event /home/elmarco/pkg/spice/spice-0.12.4/server/red_channel.c:1561
-    #10 0x555555c3c53d in qemu_iohandler_poll /home/elmarco/src/qemu/iohandler.c:143
-SUMMARY: AddressSanitizer: heap-buffer-overflow /home/elmarco/pkg/spice/spice-0.12.4/server/smartcard.c:334 smartcard_char_device_notify_reader_add
-
-Signed-off-by: Marc-Andre Lureau <marcandre.lureau@redhat.com>
----
- server/smartcard.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/smartcard.c b/server/smartcard.c
-index 8d529fe..3043ad1 100644
---- a/server/smartcard.c
-+++ b/server/smartcard.c
-@@ -325,7 +325,7 @@ static void smartcard_char_device_notify_reader_add(SmartCardDeviceState *st)
-     SpiceCharDeviceWriteBuffer *write_buf;
-     VSCMsgHeader *vheader;
- 
--    write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader));
-+    write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(*vheader));
-     if (!write_buf) {
-         spice_error("failed to allocate write buffer");
-         return;
-@@ -372,7 +372,7 @@ static void smartcard_char_device_notify_reader_remove(SmartCardDeviceState *st)
-         spice_debug("reader add was never sent to the device");
-         return;
-     }
--    write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(vheader));
-+    write_buf = spice_char_device_write_buffer_get(st->chardev_st, NULL, sizeof(*vheader));
-     if (!write_buf) {
-         spice_error("failed to allocate write buffer");
-         return;
diff --git a/SOURCES/0067-create-a-function-to-validate-surface-parameters.patch b/SOURCES/0067-create-a-function-to-validate-surface-parameters.patch
deleted file mode 100644
index a1f0c64..0000000
--- a/SOURCES/0067-create-a-function-to-validate-surface-parameters.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Mon, 29 Feb 2016 14:24:03 +0000
-Subject: [PATCH] create a function to validate surface parameters
-
-Make possible to reuse it outside red-parse-qxl.c
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_parse_qxl.c | 50 ++++++++++++++++++++++++++++++++------------------
- server/red_parse_qxl.h |  5 +++++
- 2 files changed, 37 insertions(+), 18 deletions(-)
-
-diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c
-index bd0c408..7dc6a4d 100644
---- a/server/red_parse_qxl.c
-+++ b/server/red_parse_qxl.c
-@@ -19,7 +19,6 @@
- #include <config.h>
- #endif
- 
--#include <stdbool.h>
- #include <inttypes.h>
- #include <glib.h>
- #include "common/lz_common.h"
-@@ -1306,13 +1305,41 @@ static unsigned int surface_format_to_bpp(uint32_t format)
-     return 0;
- }
- 
-+bool red_validate_surface(uint32_t width, uint32_t height,
-+                          int32_t stride, uint32_t format)
-+{
-+    unsigned int bpp;
-+    uint64_t size;
-+
-+    bpp = surface_format_to_bpp(format);
-+
-+    /* check if format is valid */
-+    if (!bpp) {
-+        return false;
-+    }
-+
-+    /* check stride is larger than required bytes */
-+    size = ((uint64_t) width * bpp + 7u) / 8u;
-+    /* the uint32_t conversion is here to avoid problems with -2^31 value */
-+    if (stride == G_MININT32 || size > (uint32_t) abs(stride)) {
-+        return false;
-+    }
-+
-+    /* the multiplication can overflow, also abs(-2^31) may return a negative value */
-+    size = (uint64_t) height * abs(stride);
-+    if (size > MAX_DATA_CHUNK) {
-+        return false;
-+    }
-+
-+    return true;
-+}
-+
- int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-                         RedSurfaceCmd *red, QXLPHYSICAL addr)
- {
-     QXLSurfaceCmd *qxl;
-     uint64_t size;
-     int error;
--    unsigned int bpp;
- 
-     qxl = (QXLSurfaceCmd *)get_virt(slots, addr, sizeof(*qxl), group_id,
-                                     &error);
-@@ -1331,26 +1358,13 @@ int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-         red->u.surface_create.width  = qxl->u.surface_create.width;
-         red->u.surface_create.height = qxl->u.surface_create.height;
-         red->u.surface_create.stride = qxl->u.surface_create.stride;
--        bpp = surface_format_to_bpp(red->u.surface_create.format);
- 
--        /* check if format is valid */
--        if (!bpp) {
-+        if (!red_validate_surface(red->u.surface_create.width, red->u.surface_create.height,
-+                                  red->u.surface_create.stride, red->u.surface_create.format)) {
-             return 1;
-         }
- 
--        /* check stride is larger than required bytes */
--        size = ((uint64_t) red->u.surface_create.width * bpp + 7u) / 8u;
--        /* the uint32_t conversion is here to avoid problems with -2^31 value */
--        if (red->u.surface_create.stride == G_MININT32
--            || size > (uint32_t) abs(red->u.surface_create.stride)) {
--            return 1;
--        }
--
--        /* the multiplication can overflow, also abs(-2^31) may return a negative value */
--        size = (uint64_t) red->u.surface_create.height * abs(red->u.surface_create.stride);
--        if (size > MAX_DATA_CHUNK) {
--            return 1;
--        }
-+        size = red->u.surface_create.height * abs(red->u.surface_create.stride);
-         red->u.surface_create.data =
-             (uint8_t*)get_virt(slots, qxl->u.surface_create.data, size, group_id, &error);
-         if (error) {
-diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h
-index 3adc9fa..e18d8d0 100644
---- a/server/red_parse_qxl.h
-+++ b/server/red_parse_qxl.h
-@@ -19,6 +19,8 @@
- #ifndef RED_ABI_TRANSLATE_H
- #define RED_ABI_TRANSLATE_H
- 
-+#include <stdbool.h>
-+
- #include <spice/qxl_dev.h>
- #include "red_common.h"
- #include "red_memslots.h"
-@@ -128,6 +130,9 @@ int red_get_message(RedMemSlotInfo *slots, int group_id,
-                     RedMessage *red, QXLPHYSICAL addr);
- void red_put_message(RedMessage *red);
- 
-+bool red_validate_surface(uint32_t width, uint32_t height,
-+                          int32_t stride, uint32_t format);
-+
- int red_get_surface_cmd(RedMemSlotInfo *slots, int group_id,
-                         RedSurfaceCmd *red, QXLPHYSICAL addr);
- void red_put_surface_cmd(RedSurfaceCmd *red);
diff --git a/SOURCES/0068-improve-primary-surface-parameter-checks.patch b/SOURCES/0068-improve-primary-surface-parameter-checks.patch
deleted file mode 100644
index 8005e06..0000000
--- a/SOURCES/0068-improve-primary-surface-parameter-checks.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Mon, 29 Feb 2016 14:34:49 +0000
-Subject: [PATCH] improve primary surface parameter checks
-
-Primary surface, as additional surfaces, can be used to access
-host memory from the guest using invalid parameters.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_worker.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/server/red_worker.c b/server/red_worker.c
-index a7eaab9..f9179a6 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -11380,6 +11380,15 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
-     spice_warn_if(((uint64_t)abs(surface.stride) * (uint64_t)surface.height) !=
-              abs(surface.stride) * surface.height);
- 
-+     /* surface can arrive from guest unchecked so make sure
-+      * guest is not a malicious one and drop invalid requests
-+      */
-+     if (!red_validate_surface(surface.width, surface.height,
-+                               surface.stride, surface.format)) {
-+         spice_warning("wrong primary surface creation request");
-+         return;
-+     }
-+
-     line_0 = (uint8_t*)get_virt(&worker->mem_slots, surface.mem,
-                                 surface.height * abs(surface.stride),
-                                 surface.group_id, &error);
diff --git a/SOURCES/0069-reds-Do-not-abort-due-to-wrong-header.patch b/SOURCES/0069-reds-Do-not-abort-due-to-wrong-header.patch
deleted file mode 100644
index a420d2f..0000000
--- a/SOURCES/0069-reds-Do-not-abort-due-to-wrong-header.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Pavel Grunt <pgrunt@redhat.com>
-Date: Fri, 13 Nov 2015 09:14:29 +0100
-Subject: [PATCH] reds: Do not abort due to wrong header
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Just prevent the buggy client from connecting.
-
- #0  0x00007fffe83b2a98 in raise () at /lib64/libc.so.6
- #1  0x00007fffe83b469a in abort () at /lib64/libc.so.6
- #2  0x00007ffff7b1533d in spice_logv (log_domain=0x7ffff7b87226 "Spice", log_level=SPICE_LOG_LEVEL_ERROR, strloc=0x7ffff7b92aba "reds.c:1373", function=0x7ffff7b94f40 <__FUNCTION__.31775> "reds_send_link_ack", format=0x7ffff7b871fe "assertion `%s' failed", args=args@entry=0x7fffffffcb68) at log.c:109
- #3  0x00007ffff7b15468 in spice_log (log_domain=log_domain@entry=0x7ffff7b87226 "Spice", log_level=log_level@entry=SPICE_LOG_LEVEL_ERROR, strloc=strloc@entry=0x7ffff7b92aba "reds.c:1373", function=function@entry=0x7ffff7b94f40 <__FUNCTION__.31775> "reds_send_link_ack", format=format@entry=0x7ffff7b871fe "assertion `%s' failed") at log.c:123
- #4  0x00007ffff7aee335 in reds_handle_read_link_done (link=0x555556b27c70)
-     at reds.c:1373
- #5  0x00007ffff7aee335 in reds_handle_read_link_done (opaque=0x555556b27c70)
-     at reds.c:2139
- #6  0x000055555588acc6 in qemu_iohandler_poll ()
- #7  0x000055555588a8e1 in main_loop_wait ()
- #8  0x0000555555614064 in main ()
-
-Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1281442
-
-Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
-Acked-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/reds.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index e96f28d..b45c44f 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -1482,7 +1482,10 @@ static int reds_send_link_ack(RedLinkInfo *link)
-     channel = reds_find_channel(link->link_mess->channel_type,
-                                 link->link_mess->channel_id);
-     if (!channel) {
--        spice_assert(link->link_mess->channel_type == SPICE_CHANNEL_MAIN);
-+        if (link->link_mess->channel_type != SPICE_CHANNEL_MAIN) {
-+            spice_warning("Received wrong header: channel_type != SPICE_CHANNEL_MAIN");
-+            return FALSE;
-+        }
-         spice_assert(reds->main_channel);
-         channel = &reds->main_channel->base;
-     }
diff --git a/SOURCES/0070-memslot-do-not-crash-if-guest-provide-a-wrong-addres.patch b/SOURCES/0070-memslot-do-not-crash-if-guest-provide-a-wrong-addres.patch
deleted file mode 100644
index 29787ce..0000000
--- a/SOURCES/0070-memslot-do-not-crash-if-guest-provide-a-wrong-addres.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Wed, 17 Feb 2016 21:22:22 +0000
-Subject: [PATCH] memslot: do not crash if guest provide a wrong address
-
-This could happen with buggy driver.
-
-This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1264356
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Pavel Grunt <pgrunt@redhat.com>
----
- server/red_memslots.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/server/red_memslots.c b/server/red_memslots.c
-index d9153d3..3b8443e 100644
---- a/server/red_memslots.c
-+++ b/server/red_memslots.c
-@@ -87,7 +87,7 @@ int validate_virt(RedMemSlotInfo *info, unsigned long virt, int slot_id,
- 
-     if (virt < slot->virt_start_addr || (virt + add_size) > slot->virt_end_addr) {
-         print_memslots(info);
--        spice_critical("virtual address out of range\n"
-+        spice_warning("virtual address out of range\n"
-               "    virt=0x%lx+0x%x slot_id=%d group_id=%d\n"
-               "    slot=0x%lx-0x%lx delta=0x%lx",
-               virt, add_size, slot_id, group_id,
diff --git a/SOURCES/0071-red-channel-make-red_client_-ref-unref-thread-safe.patch b/SOURCES/0071-red-channel-make-red_client_-ref-unref-thread-safe.patch
deleted file mode 100644
index a429d17..0000000
--- a/SOURCES/0071-red-channel-make-red_client_-ref-unref-thread-safe.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 12 Apr 2016 16:28:07 +0100
-Subject: [PATCH] red-channel: make red_client_{ref,unref} thread safe
-
-These function are called on both sides of dispatcher so the
-increment/decrement of the counter is done in multiple threads.
-This caused the counter to not get incremented correctly and
-freed the structure too early, leaving a dangling pointer in
-the other thread.
-
-This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1253375.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-Acked-by: Christophe Fergeau <cfergeau@redhat.com>
-Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
----
- server/red_channel.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/server/red_channel.c b/server/red_channel.c
-index 449e628..82e7137 100644
---- a/server/red_channel.c
-+++ b/server/red_channel.c
-@@ -2060,13 +2060,13 @@ RedClient *red_client_new(int migrated)
- RedClient *red_client_ref(RedClient *client)
- {
-     spice_assert(client);
--    client->refs++;
-+    g_atomic_int_inc(&client->refs);
-     return client;
- }
- 
- RedClient *red_client_unref(RedClient *client)
- {
--    if (!--client->refs) {
-+    if (g_atomic_int_dec_and_test(&client->refs)) {
-         spice_debug("release client=%p", client);
-         pthread_mutex_destroy(&client->lock);
-         free(client);
diff --git a/SOURCES/0072-chardev-remove-write-polling.patch b/SOURCES/0072-chardev-remove-write-polling.patch
deleted file mode 100644
index 4ad544b..0000000
--- a/SOURCES/0072-chardev-remove-write-polling.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Fri, 24 Oct 2014 10:51:05 +0200
-Subject: [PATCH] chardev: remove write polling
-
-In an effort to reduce the wakeups per second, get rid of the
-"write_to_dev" timer when the implementation supports
-SPICE_CHAR_DEVICE_NOTIFY_WRITABLE.
-
-When this flag is set, the frontend instance is responsible for calling
-spice_char_device_wakeup() when the device is ready to perform IO.
-
-Related to:
-https://bugzilla.redhat.com/show_bug.cgi?id=912763
----
- server/char_device.c | 36 +++++++++++++++++++++++++++---------
- server/spice.h       |  7 ++++++-
- 2 files changed, 33 insertions(+), 10 deletions(-)
-
-diff --git a/server/char_device.c b/server/char_device.c
-index 6d2339e..c6dc45b 100644
---- a/server/char_device.c
-+++ b/server/char_device.c
-@@ -438,7 +438,10 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-     }
- 
-     spice_char_device_state_ref(dev);
--    core->timer_cancel(dev->write_to_dev_timer);
-+
-+    if (dev->write_to_dev_timer) {
-+        core->timer_cancel(dev->write_to_dev_timer);
-+    }
- 
-     sif = SPICE_CONTAINEROF(dev->sin->base.sif, SpiceCharDeviceInterface, base);
-     while (dev->running) {
-@@ -473,8 +476,10 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-     /* retry writing as long as the write queue is not empty */
-     if (dev->running) {
-         if (dev->cur_write_buf) {
--            core->timer_start(dev->write_to_dev_timer,
--                              CHAR_DEVICE_WRITE_TO_TIMEOUT);
-+            if (dev->write_to_dev_timer) {
-+                core->timer_start(dev->write_to_dev_timer,
-+                                  CHAR_DEVICE_WRITE_TO_TIMEOUT);
-+            }
-         } else {
-             spice_assert(ring_is_empty(&dev->write_queue));
-         }
-@@ -488,7 +493,9 @@ static void spice_char_dev_write_retry(void *opaque)
- {
-     SpiceCharDeviceState *dev = opaque;
- 
--    core->timer_cancel(dev->write_to_dev_timer);
-+    if (dev->write_to_dev_timer) {
-+        core->timer_cancel(dev->write_to_dev_timer);
-+    }
-     spice_char_device_write_to_device(dev);
- }
- 
-@@ -635,6 +642,7 @@ SpiceCharDeviceState *spice_char_device_state_create(SpiceCharDeviceInstance *si
-                                                      void *opaque)
- {
-     SpiceCharDeviceState *char_dev;
-+    SpiceCharDeviceInterface *sif;
- 
-     spice_assert(sin);
-     spice_assert(cbs->read_one_msg_from_device && cbs->ref_msg_to_client &&
-@@ -652,10 +660,15 @@ SpiceCharDeviceState *spice_char_device_state_create(SpiceCharDeviceInstance *si
-     ring_init(&char_dev->write_bufs_pool);
-     ring_init(&char_dev->clients);
- 
--    char_dev->write_to_dev_timer = core->timer_add(spice_char_dev_write_retry, char_dev);
--    if (!char_dev->write_to_dev_timer) {
--        spice_error("failed creating char dev write timer");
-+    sif = SPICE_CONTAINEROF(char_dev->sin->base.sif, SpiceCharDeviceInterface, base);
-+    if (sif->base.minor_version <= 2 ||
-+        !(sif->flags & SPICE_CHAR_DEVICE_NOTIFY_WRITABLE)) {
-+        char_dev->write_to_dev_timer = core->timer_add(spice_char_dev_write_retry, char_dev);
-+        if (!char_dev->write_to_dev_timer) {
-+            spice_error("failed creating char dev write timer");
-+        }
-     }
-+
-     char_dev->refs = 1;
-     sin->st = char_dev;
-     spice_debug("sin %p dev_state %p", sin, char_dev);
-@@ -697,7 +710,9 @@ static void spice_char_device_state_unref(SpiceCharDeviceState *char_dev)
- void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
- {
-     reds_on_char_device_state_destroy(char_dev);
--    core->timer_remove(char_dev->write_to_dev_timer);
-+    if (char_dev->write_to_dev_timer) {
-+        core->timer_remove(char_dev->write_to_dev_timer);
-+    }
-     write_buffers_queue_free(&char_dev->write_queue);
-     write_buffers_queue_free(&char_dev->write_bufs_pool);
-     if (char_dev->cur_write_buf) {
-@@ -805,7 +820,9 @@ void spice_char_device_stop(SpiceCharDeviceState *dev)
-     spice_debug("dev_state %p", dev);
-     dev->running = FALSE;
-     dev->active = FALSE;
--    core->timer_cancel(dev->write_to_dev_timer);
-+    if (dev->write_to_dev_timer) {
-+        core->timer_cancel(dev->write_to_dev_timer);
-+    }
- }
- 
- void spice_char_device_reset(SpiceCharDeviceState *dev)
-@@ -842,6 +859,7 @@ void spice_char_device_reset(SpiceCharDeviceState *dev)
- 
- void spice_char_device_wakeup(SpiceCharDeviceState *dev)
- {
-+    spice_char_device_write_to_device(dev);
-     spice_char_device_read_from_device(dev);
- }
- 
-diff --git a/server/spice.h b/server/spice.h
-index 6fbb7b2..7b5e04e 100644
---- a/server/spice.h
-+++ b/server/spice.h
-@@ -390,11 +390,15 @@ void spice_server_record_set_mute(SpiceRecordInstance *sin, uint8_t mute);
- 
- #define SPICE_INTERFACE_CHAR_DEVICE "char_device"
- #define SPICE_INTERFACE_CHAR_DEVICE_MAJOR 1
--#define SPICE_INTERFACE_CHAR_DEVICE_MINOR 2
-+#define SPICE_INTERFACE_CHAR_DEVICE_MINOR 3
- typedef struct SpiceCharDeviceInterface SpiceCharDeviceInterface;
- typedef struct SpiceCharDeviceInstance SpiceCharDeviceInstance;
- typedef struct SpiceCharDeviceState SpiceCharDeviceState;
- 
-+typedef enum {
-+    SPICE_CHAR_DEVICE_NOTIFY_WRITABLE = 1 << 0,
-+} spice_char_device_flags;
-+
- struct SpiceCharDeviceInterface {
-     SpiceBaseInterface base;
- 
-@@ -402,6 +406,7 @@ struct SpiceCharDeviceInterface {
-     int (*write)(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len);
-     int (*read)(SpiceCharDeviceInstance *sin, uint8_t *buf, int len);
-     void (*event)(SpiceCharDeviceInstance *sin, uint8_t event);
-+    spice_char_device_flags flags;
- };
- 
- struct SpiceCharDeviceInstance {
diff --git a/SOURCES/0073-clean-up-remove-unused-function.patch b/SOURCES/0073-clean-up-remove-unused-function.patch
deleted file mode 100644
index 8b7b2fb..0000000
--- a/SOURCES/0073-clean-up-remove-unused-function.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
-Date: Mon, 18 Nov 2013 11:28:27 +0100
-Subject: [PATCH] clean-up: remove unused function
-
----
- server/reds.c | 5 -----
- server/reds.h | 1 -
- 2 files changed, 6 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index b45c44f..53f21bd 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -3572,11 +3572,6 @@ uint32_t reds_get_mm_time(void)
-     return time_space.tv_sec * 1000 + time_space.tv_nsec / 1000 / 1000;
- }
- 
--void reds_update_mm_timer(uint32_t mm_time)
--{
--    red_dispatcher_set_mm_time(mm_time);
--}
--
- void reds_enable_mm_timer(void)
- {
-     core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
-diff --git a/server/reds.h b/server/reds.h
-index 1c5ae84..24b4d95 100644
---- a/server/reds.h
-+++ b/server/reds.h
-@@ -122,7 +122,6 @@ void reds_handle_channel_event(int event, SpiceChannelEventInfo *info);
- 
- void reds_disable_mm_timer(void);
- void reds_enable_mm_timer(void);
--void reds_update_mm_timer(uint32_t mm_time);
- uint32_t reds_get_mm_time(void);
- void reds_set_client_mouse_allowed(int is_client_mouse_allowed,
-                                    int x_res, int y_res);
diff --git a/SOURCES/0074-Remove-guest-side-video-time-stamping.patch b/SOURCES/0074-Remove-guest-side-video-time-stamping.patch
deleted file mode 100644
index 28f0440..0000000
--- a/SOURCES/0074-Remove-guest-side-video-time-stamping.patch
+++ /dev/null
@@ -1,154 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Sun, 2 Nov 2014 22:11:58 +0100
-Subject: [PATCH] Remove guest side video time-stamping
-
-The multimedia time is defined by the server side monotonic time [1],
-but the drawing time-stamp is done in guest side, so it requires
-synchronization between host and guest. This is expensive, when no audio
-is playing, there is a ~30x/sec wakeup to update the qxl device mmtime,
-and it requires marking dirty the rom region.
-
-Instead, the video timestamping can be done more efficiently on server
-side, without visible drawbacks.
-
-[1] a better timestamp could be the audio time, since audio players are
-    usually sync with audio time)
-
-Related to:
-https://bugzilla.redhat.com/show_bug.cgi?id=912763
----
- server/red_dispatcher.c |  9 ---------
- server/red_worker.c     |  1 +
- server/reds-private.h   |  2 --
- server/reds.c           | 13 -------------
- server/snd_worker.c     |  1 -
- server/spice.h          |  3 ++-
- 6 files changed, 3 insertions(+), 26 deletions(-)
-
-diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
-index 2ebde63..6ecd3d4 100644
---- a/server/red_dispatcher.c
-+++ b/server/red_dispatcher.c
-@@ -749,15 +749,6 @@ static void qxl_worker_loadvm_commands(QXLWorker *qxl_worker,
-     red_dispatcher_loadvm_commands((RedDispatcher*)qxl_worker, ext, count);
- }
- 
--void red_dispatcher_set_mm_time(uint32_t mm_time)
--{
--    RedDispatcher *now = dispatchers;
--    while (now) {
--        now->qxl->st->qif->set_mm_time(now->qxl, mm_time);
--        now = now->next;
--    }
--}
--
- static inline int calc_compression_level(void)
- {
-     spice_assert(streaming_video != STREAM_VIDEO_INVALID);
-diff --git a/server/red_worker.c b/server/red_worker.c
-index f9179a6..dfa5274 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -4237,6 +4237,7 @@ static inline void red_process_drawable(RedWorker *worker, RedDrawable *drawable
-         return;
-     }
- 
-+    drawable->mm_time = reds_get_mm_time();
-     surface_id = item->surface_id;
- 
-     worker->surfaces[surface_id].refs++;
-diff --git a/server/reds-private.h b/server/reds-private.h
-index 9358d27..46899f6 100644
---- a/server/reds-private.h
-+++ b/server/reds-private.h
-@@ -6,7 +6,6 @@
- #include <spice/protocol.h>
- 
- #define MIGRATE_TIMEOUT (1000 * 10) /* 10sec */
--#define MM_TIMER_GRANULARITY_MS (1000 / 30)
- #define MM_TIME_DELTA 400 /*ms*/
- 
- typedef struct TicketAuthentication {
-@@ -159,7 +158,6 @@ typedef struct RedsState {
-     int dispatcher_allows_client_mouse;
-     MonitorMode monitor_mode;
-     SpiceTimer *mig_timer;
--    SpiceTimer *mm_timer;
- 
-     int vm_running;
-     Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
-diff --git a/server/reds.c b/server/reds.c
-index 53f21bd..f4c6d1d 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -3574,7 +3574,6 @@ uint32_t reds_get_mm_time(void)
- 
- void reds_enable_mm_timer(void)
- {
--    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
-     reds->mm_timer_enabled = TRUE;
-     reds->mm_time_latency = MM_TIME_DELTA;
-     reds_send_mm_time();
-@@ -3582,16 +3581,9 @@ void reds_enable_mm_timer(void)
- 
- void reds_disable_mm_timer(void)
- {
--    core->timer_cancel(reds->mm_timer);
-     reds->mm_timer_enabled = FALSE;
- }
- 
--static void mm_timer_proc(void *opaque)
--{
--    red_dispatcher_set_mm_time(reds_get_mm_time());
--    core->timer_start(reds->mm_timer, MM_TIMER_GRANULARITY_MS);
--}
--
- static SpiceCharDeviceState *attach_to_red_agent(SpiceCharDeviceInstance *sin)
- {
-     VDIPortState *state = &reds->agent_state;
-@@ -4029,11 +4021,6 @@ static int do_spice_init(SpiceCoreInterface *core_interface)
-     }
- #endif
- 
--    if (!(reds->mm_timer = core->timer_add(mm_timer_proc, NULL))) {
--        spice_error("mm timer create failed");
--    }
--    reds_enable_mm_timer();
--
-     if (reds_init_net() < 0) {
-         goto err;
-     }
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index c451031..b6cb62b 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -1113,7 +1113,6 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
-         snd_playback_free_frame(playback_channel, playback_channel->pending_frame);
-     }
-     frame->time = reds_get_mm_time();
--    red_dispatcher_set_mm_time(frame->time);
-     playback_channel->pending_frame = frame;
-     snd_set_command(&playback_channel->base, SND_PLAYBACK_PCM_MASK);
-     snd_playback_send(&playback_channel->base);
-diff --git a/server/spice.h b/server/spice.h
-index 7b5e04e..9c8e18a 100644
---- a/server/spice.h
-+++ b/server/spice.h
-@@ -20,6 +20,7 @@
- 
- #include <stdint.h>
- #include <sys/socket.h>
-+#include <spice/macros.h>
- #include <spice/qxl_dev.h>
- #include <spice/vd_agent.h>
- 
-@@ -228,7 +229,7 @@ struct QXLInterface {
- 
-     void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
-     void (*set_compression_level)(QXLInstance *qin, int level);
--    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
-+    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time) SPICE_GNUC_DEPRECATED;
- 
-     void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
-     int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
diff --git a/SOURCES/0075-char-device-fix-usage-of-free-unref-on-WriteBuffer.patch b/SOURCES/0075-char-device-fix-usage-of-free-unref-on-WriteBuffer.patch
deleted file mode 100644
index 80704a0..0000000
--- a/SOURCES/0075-char-device-fix-usage-of-free-unref-on-WriteBuffer.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Victor Toso <victortoso@redhat.com>
-Date: Wed, 19 Aug 2015 10:53:22 +0200
-Subject: [PATCH] char-device: fix usage of free/unref on WriteBuffer
-
-There are places were the could should definetly free the
-SpiceCharDeviceWriteBuffer and places that it should only unref it. The
-current use of spice_char_device_write_buffer_free was missleading.
-
-This patch creates the spice_char_device_write_buffer_unref and properly
-call these two functions.
-
-Related: https://bugs.freedesktop.org/show_bug.cgi?id=91350
----
- server/char_device.c | 34 ++++++++++++++++++++++------------
- 1 file changed, 22 insertions(+), 12 deletions(-)
-
-diff --git a/server/char_device.c b/server/char_device.c
-index c6dc45b..dd367ab 100644
---- a/server/char_device.c
-+++ b/server/char_device.c
-@@ -80,6 +80,7 @@ enum {
-  * destroyed during a callback */
- static void spice_char_device_state_ref(SpiceCharDeviceState *char_dev);
- static void spice_char_device_state_unref(SpiceCharDeviceState *char_dev);
-+static void spice_char_device_write_buffer_unref(SpiceCharDeviceWriteBuffer *write_buf);
- 
- static void spice_char_dev_write_retry(void *opaque);
- 
-@@ -90,10 +91,11 @@ typedef struct SpiceCharDeviceMsgToClientItem {
- 
- static void spice_char_device_write_buffer_free(SpiceCharDeviceWriteBuffer *buf)
- {
--    if (--buf->refs == 0) {
--        free(buf->buf);
--        free(buf);
--    }
-+    if (buf == NULL)
-+        return;
-+
-+    free(buf->buf);
-+    free(buf);
- }
- 
- static void write_buffers_queue_free(Ring *write_queue)
-@@ -116,9 +118,11 @@ static void spice_char_device_write_buffer_pool_add(SpiceCharDeviceState *dev,
-         buf->origin = WRITE_BUFFER_ORIGIN_NONE;
-         buf->client = NULL;
-         ring_add(&dev->write_bufs_pool, &buf->link);
--    } else {
--        --buf->refs;
-+        return;
-     }
-+
-+    /* Buffer still being used - just unref for the caller */
-+    spice_char_device_write_buffer_unref(buf);
- }
- 
- static void spice_char_device_client_send_queue_free(SpiceCharDeviceState *dev,
-@@ -581,6 +585,15 @@ static SpiceCharDeviceWriteBuffer *spice_char_device_write_buffer_ref(SpiceCharD
-     return write_buf;
- }
- 
-+static void spice_char_device_write_buffer_unref(SpiceCharDeviceWriteBuffer *write_buf)
-+{
-+    spice_assert(write_buf);
-+
-+    write_buf->refs--;
-+    if (write_buf->refs == 0)
-+        spice_char_device_write_buffer_free(write_buf);
-+}
-+
- void spice_char_device_write_buffer_add(SpiceCharDeviceState *dev,
-                                         SpiceCharDeviceWriteBuffer *write_buf)
- {
-@@ -607,8 +620,7 @@ void spice_char_device_write_buffer_release(SpiceCharDeviceState *dev,
-     spice_assert(!ring_item_is_linked(&write_buf->link));
-     if (!dev) {
-         spice_printerr("no device. write buffer is freed");
--        free(write_buf->buf);
--        free(write_buf);
-+        spice_char_device_write_buffer_free(write_buf);
-         return;
-     }
- 
-@@ -715,9 +727,7 @@ void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
-     }
-     write_buffers_queue_free(&char_dev->write_queue);
-     write_buffers_queue_free(&char_dev->write_bufs_pool);
--    if (char_dev->cur_write_buf) {
--        spice_char_device_write_buffer_free(char_dev->cur_write_buf);
--    }
-+    spice_char_device_write_buffer_free(char_dev->cur_write_buf);
- 
-     while (!ring_is_empty(&char_dev->clients)) {
-         RingItem *item = ring_get_tail(&char_dev->clients);
-@@ -883,7 +893,7 @@ static void migrate_data_marshaller_write_buffer_free(uint8_t *data, void *opaqu
- {
-     SpiceCharDeviceWriteBuffer *write_buf = (SpiceCharDeviceWriteBuffer *)opaque;
- 
--    spice_char_device_write_buffer_free(write_buf);
-+    spice_char_device_write_buffer_unref(write_buf);
- }
- 
- void spice_char_device_state_migrate_data_marshall(SpiceCharDeviceState *dev,
diff --git a/SOURCES/0076-spicevmc-set-state-of-DeviceInstance-to-NULL.patch b/SOURCES/0076-spicevmc-set-state-of-DeviceInstance-to-NULL.patch
deleted file mode 100644
index f5afa21..0000000
--- a/SOURCES/0076-spicevmc-set-state-of-DeviceInstance-to-NULL.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Victor Toso <victortoso@redhat.com>
-Date: Fri, 13 Nov 2015 10:46:43 +0100
-Subject: [PATCH] spicevmc: set state of DeviceInstance to NULL
-
-After spice_char_device_state_destroy is called spicevmc should not keep
-reference to that memory. state->chardev_st and sin->st point to the
-same SpiceCharDeviceState and both should be set to NULL when it is
-destroyed.
----
- server/spicevmc.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/server/spicevmc.c b/server/spicevmc.c
-index e10f183..94cb8a7 100644
---- a/server/spicevmc.c
-+++ b/server/spicevmc.c
-@@ -559,6 +559,7 @@ void spicevmc_device_disconnect(SpiceCharDeviceInstance *sin)
-     }
-     spice_char_device_state_destroy(sin->st);
-     state->chardev_st = NULL;
-+    sin->st = NULL;
- 
-     reds_unregister_channel(&state->channel);
-     free(state->pipe_item);
diff --git a/SOURCES/0077-char-device-set-to-NULL-freed-pointers-on-destroy.patch b/SOURCES/0077-char-device-set-to-NULL-freed-pointers-on-destroy.patch
deleted file mode 100644
index ef4660b..0000000
--- a/SOURCES/0077-char-device-set-to-NULL-freed-pointers-on-destroy.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Victor Toso <victortoso@redhat.com>
-Date: Fri, 13 Nov 2015 10:44:55 +0100
-Subject: [PATCH] char-device: set to NULL freed pointers on destroy
-
-As SpiceCharDeviceState is only unref'ed on
-spice_char_device_state_destroy the same device could be destroyed more
-then once so the pointers that are freed should be set to NULL.
-
-Related: https://bugzilla.redhat.com/show_bug.cgi?id=1281455
----
- server/char_device.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/server/char_device.c b/server/char_device.c
-index dd367ab..285299c 100644
---- a/server/char_device.c
-+++ b/server/char_device.c
-@@ -724,10 +724,12 @@ void spice_char_device_state_destroy(SpiceCharDeviceState *char_dev)
-     reds_on_char_device_state_destroy(char_dev);
-     if (char_dev->write_to_dev_timer) {
-         core->timer_remove(char_dev->write_to_dev_timer);
-+        char_dev->write_to_dev_timer = NULL;
-     }
-     write_buffers_queue_free(&char_dev->write_queue);
-     write_buffers_queue_free(&char_dev->write_bufs_pool);
-     spice_char_device_write_buffer_free(char_dev->cur_write_buf);
-+    char_dev->cur_write_buf = NULL;
- 
-     while (!ring_is_empty(&char_dev->clients)) {
-         RingItem *item = ring_get_tail(&char_dev->clients);
diff --git a/SOURCES/0078-channel-add-option-tcp-keepalive-timeout-to-channels.patch b/SOURCES/0078-channel-add-option-tcp-keepalive-timeout-to-channels.patch
deleted file mode 100644
index 8b81a8d..0000000
--- a/SOURCES/0078-channel-add-option-tcp-keepalive-timeout-to-channels.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sunny Shin <sunny4s.git@gmail.com>
-Date: Tue, 1 Dec 2015 13:46:30 +0900
-Subject: [PATCH] channel: add option tcp keepalive timeout to channels
-
----
- server/reds-private.h    |  1 +
- server/reds.c            | 22 ++++++++++++++++++++++
- server/spice-server.syms |  5 +++++
- server/spice.h           |  1 +
- 4 files changed, 29 insertions(+)
-
-diff --git a/server/reds-private.h b/server/reds-private.h
-index 46899f6..0f7ab65 100644
---- a/server/reds-private.h
-+++ b/server/reds-private.h
-@@ -162,6 +162,7 @@ typedef struct RedsState {
-     int vm_running;
-     Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
-     int seamless_migration_enabled; /* command line arg */
-+    int keepalive_timeout;
- 
-     SSL_CTX *ctx;
- 
-diff --git a/server/reds.c b/server/reds.c
-index f4c6d1d..a28027e 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -2899,6 +2899,21 @@ static RedLinkInfo *reds_init_client_connection(int socket)
-         }
-     }
- 
-+    if (reds->keepalive_timeout > 0) {
-+        int keepalive = 1;
-+        if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) == -1) {
-+            if (errno != ENOTSUP) {
-+                spice_printerr("setsockopt for keepalive failed, %s", strerror(errno));
-+            }
-+        }
-+        if (setsockopt(socket, SOL_TCP, TCP_KEEPIDLE,
-+                       &reds->keepalive_timeout, sizeof(reds->keepalive_timeout)) == -1) {
-+            if (errno != ENOTSUP) {
-+                spice_printerr("setsockopt for keepalive timeout failed, %s", strerror(errno));
-+            }
-+        }
-+    }
-+
-     link = spice_new0(RedLinkInfo, 1);
-     stream = spice_new0(RedsStream, 1);
-     stream->info = spice_new0(SpiceChannelEventInfo, 1);
-@@ -4690,3 +4705,10 @@ void reds_stream_free(RedsStream *s)
- 
-     free(s);
- }
-+
-+SPICE_GNUC_VISIBLE void spice_server_set_keepalive_timeout(SpiceServer *s, int timeout)
-+{
-+    spice_assert(s == reds);
-+    reds->keepalive_timeout = timeout;
-+    spice_debug("keepalive timeout=%d", timeout);
-+}
-diff --git a/server/spice-server.syms b/server/spice-server.syms
-index 4f2dc37..9af3354 100644
---- a/server/spice-server.syms
-+++ b/server/spice-server.syms
-@@ -145,3 +145,8 @@ SPICE_SERVER_0.12.4 {
- global:
-     spice_server_set_agent_file_xfer;
- } SPICE_SERVER_0.12.3;
-+
-+SPICE_SERVER_0.12.7 {
-+global:
-+    spice_server_set_keepalive_timeout;
-+} SPICE_SERVER_0.12.4;
-diff --git a/server/spice.h b/server/spice.h
-index 9c8e18a..c31839d 100644
---- a/server/spice.h
-+++ b/server/spice.h
-@@ -508,6 +508,7 @@ int spice_server_set_playback_compression(SpiceServer *s, int enable);
- int spice_server_set_agent_mouse(SpiceServer *s, int enable);
- int spice_server_set_agent_copypaste(SpiceServer *s, int enable);
- int spice_server_set_agent_file_xfer(SpiceServer *s, int enable);
-+void spice_server_set_keepalive_timeout(SpiceServer *s, int timeout);
- 
- int spice_server_get_sock_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
- int spice_server_get_peer_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
diff --git a/SOURCES/0079-Always-enable-TCP-keepalive.patch b/SOURCES/0079-Always-enable-TCP-keepalive.patch
deleted file mode 100644
index be6db5c..0000000
--- a/SOURCES/0079-Always-enable-TCP-keepalive.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Wed, 2 Mar 2016 12:24:11 +0100
-Subject: [PATCH] Always enable TCP keepalive
-
-Always enabled, hardcoded interval
-as per https://bugzilla.redhat.com/show_bug.cgi?id=1298590
----
- server/reds.c | 40 ++++++++++++++++++++++++++--------------
- 1 file changed, 26 insertions(+), 14 deletions(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index a28027e..a848828 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -2876,6 +2876,31 @@ static void reds_handle_ssl_accept(int fd, int event, void *data)
-     reds_handle_new_link(link);
- }
- 
-+#define KEEPALIVE_TIMEOUT (10*60)
-+
-+static bool reds_init_keepalive(int socket)
-+{
-+    int keepalive = 1;
-+    int keepalive_timeout = KEEPALIVE_TIMEOUT;
-+
-+    if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) == -1) {
-+        if (errno != ENOTSUP) {
-+            spice_printerr("setsockopt for keepalive failed, %s", strerror(errno));
-+            return false;
-+        }
-+    }
-+
-+    if (setsockopt(socket, SOL_TCP, TCP_KEEPIDLE,
-+                   &keepalive_timeout, sizeof(keepalive_timeout)) == -1) {
-+        if (errno != ENOTSUP) {
-+            spice_printerr("setsockopt for keepalive timeout failed, %s", strerror(errno));
-+            return false;
-+        }
-+    }
-+
-+    return true;
-+}
-+
- static RedLinkInfo *reds_init_client_connection(int socket)
- {
-     RedLinkInfo *link;
-@@ -2899,20 +2924,7 @@ static RedLinkInfo *reds_init_client_connection(int socket)
-         }
-     }
- 
--    if (reds->keepalive_timeout > 0) {
--        int keepalive = 1;
--        if (setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) == -1) {
--            if (errno != ENOTSUP) {
--                spice_printerr("setsockopt for keepalive failed, %s", strerror(errno));
--            }
--        }
--        if (setsockopt(socket, SOL_TCP, TCP_KEEPIDLE,
--                       &reds->keepalive_timeout, sizeof(reds->keepalive_timeout)) == -1) {
--            if (errno != ENOTSUP) {
--                spice_printerr("setsockopt for keepalive timeout failed, %s", strerror(errno));
--            }
--        }
--    }
-+    reds_init_keepalive(socket);
- 
-     link = spice_new0(RedLinkInfo, 1);
-     stream = spice_new0(RedsStream, 1);
diff --git a/SOURCES/0080-Remove-spice_server_set_keepalive_timeout.patch b/SOURCES/0080-Remove-spice_server_set_keepalive_timeout.patch
deleted file mode 100644
index 31f1f5b..0000000
--- a/SOURCES/0080-Remove-spice_server_set_keepalive_timeout.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Christophe Fergeau <cfergeau@redhat.com>
-Date: Wed, 2 Mar 2016 12:25:23 +0100
-Subject: [PATCH] Remove spice_server_set_keepalive_timeout
-
-This public API is no longer needed as the keepalive interval does not
-need to be configurable. This API was never in a stable 0.12 release, so
-it's OK to remove it now.
----
- server/reds-private.h    | 1 -
- server/reds.c            | 7 -------
- server/spice-server.syms | 5 -----
- server/spice.h           | 1 -
- 4 files changed, 14 deletions(-)
-
-diff --git a/server/reds-private.h b/server/reds-private.h
-index 0f7ab65..46899f6 100644
---- a/server/reds-private.h
-+++ b/server/reds-private.h
-@@ -162,7 +162,6 @@ typedef struct RedsState {
-     int vm_running;
-     Ring char_devs_states; /* list of SpiceCharDeviceStateItem */
-     int seamless_migration_enabled; /* command line arg */
--    int keepalive_timeout;
- 
-     SSL_CTX *ctx;
- 
-diff --git a/server/reds.c b/server/reds.c
-index a848828..e7e4090 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -4717,10 +4717,3 @@ void reds_stream_free(RedsStream *s)
- 
-     free(s);
- }
--
--SPICE_GNUC_VISIBLE void spice_server_set_keepalive_timeout(SpiceServer *s, int timeout)
--{
--    spice_assert(s == reds);
--    reds->keepalive_timeout = timeout;
--    spice_debug("keepalive timeout=%d", timeout);
--}
-diff --git a/server/spice-server.syms b/server/spice-server.syms
-index 9af3354..4f2dc37 100644
---- a/server/spice-server.syms
-+++ b/server/spice-server.syms
-@@ -145,8 +145,3 @@ SPICE_SERVER_0.12.4 {
- global:
-     spice_server_set_agent_file_xfer;
- } SPICE_SERVER_0.12.3;
--
--SPICE_SERVER_0.12.7 {
--global:
--    spice_server_set_keepalive_timeout;
--} SPICE_SERVER_0.12.4;
-diff --git a/server/spice.h b/server/spice.h
-index c31839d..9c8e18a 100644
---- a/server/spice.h
-+++ b/server/spice.h
-@@ -508,7 +508,6 @@ int spice_server_set_playback_compression(SpiceServer *s, int enable);
- int spice_server_set_agent_mouse(SpiceServer *s, int enable);
- int spice_server_set_agent_copypaste(SpiceServer *s, int enable);
- int spice_server_set_agent_file_xfer(SpiceServer *s, int enable);
--void spice_server_set_keepalive_timeout(SpiceServer *s, int timeout);
- 
- int spice_server_get_sock_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
- int spice_server_get_peer_info(SpiceServer *s, struct sockaddr *sa, socklen_t *salen);
diff --git a/SOURCES/0081-sound-do-not-modify-client-state-on-migration.patch b/SOURCES/0081-sound-do-not-modify-client-state-on-migration.patch
deleted file mode 100644
index 1893ec9..0000000
--- a/SOURCES/0081-sound-do-not-modify-client-state-on-migration.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@gmail.com>
-Date: Fri, 24 Apr 2015 14:05:00 +0200
-Subject: [PATCH] sound: do not modify client state on migration
-
-During migration, a volume jump is observed by the client. This is due
-to qemu setting up destination server with default sound state, and the
-server sending it after the client is connected. The volume is later
-restored after migration is finished so there is no need to send this
-default state values on connection.
-
-Tested with both AC97 & HDA devices.
-
-Fixes:
-https://bugzilla.redhat.com/show_bug.cgi?id=1012868
----
- server/snd_worker.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/server/snd_worker.c b/server/snd_worker.c
-index b6cb62b..d1bfcae 100644
---- a/server/snd_worker.c
-+++ b/server/snd_worker.c
-@@ -1223,7 +1223,10 @@ static void snd_set_playback_peer(RedChannel *channel, RedClient *client, RedsSt
-                                                                 SPICE_PLAYBACK_CAP_CELT_0_5_1) ?
-         playback_compression : SPICE_AUDIO_DATA_MODE_RAW;
- 
--    on_new_playback_channel(worker);
-+    if (!red_client_during_migrate_at_target(client)) {
-+        on_new_playback_channel(worker);
-+    }
-+
-     if (worker->active) {
-         spice_server_playback_start(st->sin);
-     }
diff --git a/SOURCES/0082-char-device-spice_char_device_write_to_device-protec.patch b/SOURCES/0082-char-device-spice_char_device_write_to_device-protec.patch
deleted file mode 100644
index 44b250b..0000000
--- a/SOURCES/0082-char-device-spice_char_device_write_to_device-protec.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Uri Lublin <uril@redhat.com>
-Date: Mon, 2 Feb 2015 12:35:59 +0200
-Subject: [PATCH] char-device: spice_char_device_write_to_device: protect
- against recursion
-
-This fixes Spice's smart card support and is related to
-commit 697f3214fd16adcd524456003619f7f44ddd031b.
-
-Reported-by: Swapna Krishnan <skrishna@redhat.com>
-
-Recursion is now possible starting with spice_char_device_write_to_device
-going through spice_char_device_wakeup (after going through qemu),
-calling again to spice_char_device_write_to_device.
-
-The protecting code is the same as the one protecting the read path.
-
-This function call loop makes the program to abort with the following messages:
-
-  usb-ccid: chardev: unexpected message of type 3000000
-  qemu: qemu_mutex_lock: Resource deadlock avoided
-
-Backtrace:
-
-(gdb) bt
-* #0  0x00007ffff3fc78c7 in raise () from /lib64/libc.so.6
-* #1  0x00007ffff3fc952a in abort () from /lib64/libc.so.6
-* #2  0x0000555555969a95 in error_exit (err=35,
-*     msg=0x5555559f8c90 <__func__.5119> "qemu_mutex_lock")
-*     at util/qemu-thread-posix.c:48
-* #3  0x0000555555969b82 in qemu_mutex_lock (mutex=0x5555562c4d60)
-*     at util/qemu-thread-posix.c:79
-* #4  0x0000555555714771 in qemu_chr_fe_write (s=0x5555562c4d60,
-*     buf=0x7fffffffd2a0 "", len=12) at qemu-char.c:219
-* #5  0x000055555586be49 in ccid_card_vscard_send_msg (s=0x5555565c5f80,
-*     type=VSC_Error, reader_id=0, payload=0x7fffffffd2e0 "", length=4)
-*     at hw/usb/ccid-card-passthru.c:75
-* #6  0x000055555586bf00 in ccid_card_vscard_send_error (s=0x5555565c5f80,
-*     reader_id=0, code=VSC_GENERAL_ERROR) at
-*     hw/usb/ccid-card-passthru.c:91
-* #7  0x000055555586c559 in ccid_card_vscard_handle_message (
-*     card=0x5555565c5f80, scr_msg_header=0x5555565c6008)
-*     at hw/usb/ccid-card-passthru.c:254
-* #8  0x000055555586c72f in ccid_card_vscard_read (opaque=0x5555565c5f80,
-*     buf=0x5555565034b0 "", size=12) at hw/usb/ccid-card-passthru.c:289
-* #9  0x00005555557149db in qemu_chr_be_write (s=0x5555562c4d60,
-*     buf=0x5555565034b0 "", len=12) at qemu-char.c:305
-* #10 0x000055555571cde5 in vmc_write (sin=0x5555562c4e78,
-*     buf=0x5555565034b0 "", len=12) at spice-qemu-char.c:41
-* #11 0x00007ffff4fa86aa in spice_char_device_write_to_device (
-*     dev=0x55555657f210) at char_device.c:462
-* #12 0x00007ffff4fa9b48 in spice_char_device_wakeup (dev=0x55555657f210)
-*     at char_device.c:862
-* #13 0x00007ffff4ff7658 in spice_server_char_device_wakeup
-*     (sin=0x5555562c4e78) at reds.c:2955
-* #14 0x000055555571d1d2 in spice_chr_write (chr=0x5555562c4d60,
-*     buf=0x7fffffffd560 "", len=12) at spice-qemu-char.c:189
-* #15 0x0000555555714789 in qemu_chr_fe_write (s=0x5555562c4d60,
-*     buf=0x7fffffffd560 "", len=12) at qemu-char.c:220
-* #16 0x000055555586be49 in ccid_card_vscard_send_msg (s=0x5555565c5f80,
-*     type=VSC_Error, reader_id=0, payload=0x7fffffffd5a0 "", length=4)
-*     at hw/usb/ccid-card-passthru.c:75
-* #17 0x000055555586bf00 in ccid_card_vscard_send_error
-* (s=0x5555565c5f80,
-*     reader_id=0, code=VSC_SUCCESS) at hw/usb/ccid-card-passthru.c:91
-* #18 0x000055555586c4fc in ccid_card_vscard_handle_message (
-*     card=0x5555565c5f80, scr_msg_header=0x5555565c6008)
-*     at hw/usb/ccid-card-passthru.c:242
-* #19 0x000055555586c72f in ccid_card_vscard_read (opaque=0x5555565c5f80,
-*     buf=0x5555565034b0 "", size=12) at hw/usb/ccid-card-passthru.c:289
-* #20 0x00005555557149db in qemu_chr_be_write (s=0x5555562c4d60,
-*     buf=0x5555565034b0 "", len=12) at qemu-char.c:305
-* #21 0x000055555571cde5 in vmc_write (sin=0x5555562c4e78,
-*     buf=0x5555565034b0 "", len=12) at spice-qemu-char.c:41
-* #22 0x00007ffff4fa86aa in spice_char_device_write_to_device (
-*     dev=0x55555657f210) at char_device.c:462
-* #23 0x00007ffff4fa8d37 in spice_char_device_write_buffer_add (
-*     dev=0x55555657f210, write_buf=0x555556501f70) at char_device.c:597
-* #24 0x00007ffff501142d in smartcard_channel_write_to_reader (
-*     write_buf=0x555556501f70) at smartcard.c:669
-* #25 0x00007ffff501034c in smartcard_char_device_notify_reader_add (
-*     st=0x55555657ef00) at smartcard.c:335
-* #26 0x00007ffff50112b3 in smartcard_add_reader (scc=0x555556493ee0,
-*     name=0x5555565023cc "E-Gate 0 0") at smartcard.c:642
-* #27 0x00007ffff50118d2 in smartcard_channel_handle_message (
-*     rcc=0x555556493ee0, type=101, size=22, msg=0x5555565023c0 "\003")
-*     at smartcard.c:757
-* #28 0x00007ffff4fbc168 in red_peer_handle_incoming
-*     (stream=0x555556588250, handler=0x555556497ff0) at red_channel.c:308
-* #29 0x00007ffff4fbc231 in red_channel_client_receive
-*     (rcc=0x555556493ee0) at red_channel.c:326
-* #30 0x00007ffff4fc0019 in red_channel_client_event (fd=59, event=1,
-*     data=0x555556493ee0) at red_channel.c:1574
-* #31 0x00005555558b6076 in watch_read (opaque=0x5555565002f0)
-*     at ui/spice-core.c:101
-* #32 0x00005555558e8d48 in qemu_iohandler_poll (pollfds=0x5555562b7630,
-*     ret=2) at iohandler.c:143
-* #33 0x00005555558e89a4 in main_loop_wait (nonblocking=0) at
-* main-loop.c:495
-* #34 0x00005555557219b0 in main_loop () at vl.c:1794
-* #35 0x0000555555729257 in main (argc=40, argv=0x7fffffffddc8,
-*     envp=0x7fffffffdf10) at vl.c:4350
-
-(cherry picked from commit 0c1f5b00e7907aefee13f86a234558f00cd6c7ef)
----
- server/char_device.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/server/char_device.c b/server/char_device.c
-index 285299c..e5d7c69 100644
---- a/server/char_device.c
-+++ b/server/char_device.c
-@@ -64,6 +64,7 @@ struct SpiceCharDeviceState {
-     SpiceCharDeviceInstance *sin;
- 
-     int during_read_from_device;
-+    int during_write_to_device;
- 
-     SpiceCharDeviceCallbacks cbs;
-     void *opaque;
-@@ -441,6 +442,11 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-         return 0;
-     }
- 
-+    /* protect against recursion with spice_char_device_wakeup */
-+    if (dev->during_write_to_device++ > 0) {
-+        return 0;
-+    }
-+
-     spice_char_device_state_ref(dev);
- 
-     if (dev->write_to_dev_timer) {
-@@ -465,6 +471,11 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-                     dev->cur_write_buf_pos;
-         n = sif->write(dev->sin, dev->cur_write_buf_pos, write_len);
-         if (n <= 0) {
-+            if (dev->during_write_to_device > 1) {
-+                dev->during_write_to_device = 1;
-+                continue; /* a wakeup might have been called during the write -
-+                             make sure it doesn't get lost */
-+            }
-             break;
-         }
-         total += n;
-@@ -489,6 +500,7 @@ static int spice_char_device_write_to_device(SpiceCharDeviceState *dev)
-         }
-         dev->active = dev->active || total;
-     }
-+    dev->during_write_to_device = 0;
-     spice_char_device_state_unref(dev);
-     return total;
- }
diff --git a/SOURCES/0083-server-allows-to-set-maximum-monitors.patch b/SOURCES/0083-server-allows-to-set-maximum-monitors.patch
deleted file mode 100644
index fa60289..0000000
--- a/SOURCES/0083-server-allows-to-set-maximum-monitors.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Fri, 19 Jun 2015 11:56:05 +0100
-Subject: [PATCH] server: allows to set maximum monitors
-
-spice-server will attempt to limit number of monitors.
-Guest machine can send monitor list it accepts. Limiting the number sent
-by guest will limit the number of monitors client will try to enable.
-The guest usually see client monitors enabled and start using it so
-not seeing client monitor won't try to enable more monitor.
-In this case the additional monitor guest can support will always be
-seen as heads with no attached monitors.
-This allows limiting monitors number without changing guest drivers.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/red_dispatcher.c  | 10 ++++++++++
- server/red_dispatcher.h  |  1 +
- server/red_worker.c      |  4 +++-
- server/spice-server.syms |  5 +++++
- server/spice.h           |  3 +++
- 5 files changed, 22 insertions(+), 1 deletion(-)
-
-diff --git a/server/red_dispatcher.c b/server/red_dispatcher.c
-index 6ecd3d4..6b395f4 100644
---- a/server/red_dispatcher.c
-+++ b/server/red_dispatcher.c
-@@ -64,6 +64,7 @@ struct RedDispatcher {
-     Ring async_commands;
-     pthread_mutex_t  async_lock;
-     QXLDevSurfaceCreate surface_create;
-+    unsigned int max_monitors;
- };
- 
- typedef struct RedWorkeState {
-@@ -701,6 +702,7 @@ static void red_dispatcher_monitors_config_async(RedDispatcher *dispatcher,
-     payload.base.cmd = async_command_alloc(dispatcher, message, cookie);
-     payload.monitors_config = monitors_config;
-     payload.group_id = group_id;
-+    payload.max_monitors = dispatcher->max_monitors;
- 
-     dispatcher_send_message(&dispatcher->dispatcher, message, &payload);
- }
-@@ -995,6 +997,12 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
- }
- 
- SPICE_GNUC_VISIBLE
-+void spice_qxl_set_max_monitors(QXLInstance *instance, unsigned int max_monitors)
-+{
-+    instance->st->dispatcher->max_monitors = MAX(1u, max_monitors);
-+}
-+
-+SPICE_GNUC_VISIBLE
- void spice_qxl_driver_unload(QXLInstance *instance)
- {
-     red_dispatcher_driver_unload(instance->st->dispatcher);
-@@ -1116,6 +1124,8 @@ RedDispatcher *red_dispatcher_init(QXLInstance *qxl)
-     red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;
-     red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands;
- 
-+    red_dispatcher->max_monitors = UINT_MAX;
-+
-     qxl->st->qif->get_init_info(qxl, &init_info);
- 
-     init_data.memslot_id_bits = init_info.memslot_id_bits;
-diff --git a/server/red_dispatcher.h b/server/red_dispatcher.h
-index 7d23b11..bc4d620 100644
---- a/server/red_dispatcher.h
-+++ b/server/red_dispatcher.h
-@@ -199,6 +199,7 @@ typedef struct RedWorkerMessageMonitorsConfigAsync {
-     RedWorkerMessageAsync base;
-     QXLPHYSICAL monitors_config;
-     int group_id;
-+    unsigned int max_monitors;
- } RedWorkerMessageMonitorsConfigAsync;
- 
- typedef struct RedWorkerMessageDriverUnload {
-diff --git a/server/red_worker.c b/server/red_worker.c
-index dfa5274..64a7758 100644
---- a/server/red_worker.c
-+++ b/server/red_worker.c
-@@ -11749,7 +11749,9 @@ static void handle_dev_monitors_config_async(void *opaque, void *payload)
-         /* TODO: raise guest bug (requires added QXL interface) */
-         return;
-     }
--    worker_update_monitors_config(worker, dev_monitors_config, count, max_allowed);
-+    worker_update_monitors_config(worker, dev_monitors_config,
-+                                  MIN(count, msg->max_monitors),
-+                                  MIN(max_allowed, msg->max_monitors));
-     red_worker_push_monitors_config(worker);
- }
- 
-diff --git a/server/spice-server.syms b/server/spice-server.syms
-index 4f2dc37..59da512 100644
---- a/server/spice-server.syms
-+++ b/server/spice-server.syms
-@@ -145,3 +145,8 @@ SPICE_SERVER_0.12.4 {
- global:
-     spice_server_set_agent_file_xfer;
- } SPICE_SERVER_0.12.3;
-+
-+SPICE_SERVER_0.12.6 {
-+global:
-+    spice_qxl_set_max_monitors;
-+} SPICE_SERVER_0.12.4;
-diff --git a/server/spice.h b/server/spice.h
-index 9c8e18a..3645775 100644
---- a/server/spice.h
-+++ b/server/spice.h
-@@ -170,6 +170,9 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
-                                      int group_id, uint64_t cookie);
- /* since spice 0.12.3 */
- void spice_qxl_driver_unload(QXLInstance *instance);
-+/* since spice 0.12.6 */
-+void spice_qxl_set_max_monitors(QXLInstance *instance,
-+                                unsigned int max_monitors);
- 
- typedef struct QXLDrawArea {
-     uint8_t *buf;
diff --git a/SOURCES/0084-Call-migrate_end_complete-after-falling-back-to-swit.patch b/SOURCES/0084-Call-migrate_end_complete-after-falling-back-to-swit.patch
deleted file mode 100644
index b33d17a..0000000
--- a/SOURCES/0084-Call-migrate_end_complete-after-falling-back-to-swit.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
-Date: Wed, 20 Jul 2016 17:16:31 +0400
-Subject: [PATCH] Call migrate_end_complete() after falling back to switch-host
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Eventually, during a seamless migration, qemu may finish to migrate
-before the spice client even finished to connect all channels to
-destination and informed the server. In this case,
-main_channel_client_migrate_src_complete() will fall back to
-switch-host method, and reds_mig_fill_wait_disconnect() is called to
-complete the migration (disconnecting all channels).
-
-reds_mig_cleanup() is called when all channels are disconnected, but
-reds->mig_wait_connect is still TRUE, and it will call
-migrate_connect_complete() instead of the expected
-migrate_end_complete(). Setting reds->mig_wait_connect to FALSE when
-reds_mig_fill_wait_disconnect() solves the issue.
-
-Fixes:
-https://bugzilla.redhat.com/show_bug.cgi?id=1352836
-
-Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
----
- server/reds.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/server/reds.c b/server/reds.c
-index e7e4090..9e1d5e7 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -3500,6 +3500,7 @@ static void reds_mig_fill_wait_disconnect(void)
-         wait_client->client = client;
-         ring_add(&reds->mig_wait_disconnect_clients, &wait_client->link);
-     }
-+    reds->mig_wait_connect = FALSE;
-     reds->mig_wait_disconnect = TRUE;
-     core->timer_start(reds->mig_timer, MIGRATE_TIMEOUT);
- }
diff --git a/SOURCES/0085-Prevent-possible-DoS-attempts-during-protocol-handsh.patch b/SOURCES/0085-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
deleted file mode 100644
index 38c9db7..0000000
--- a/SOURCES/0085-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 198ad1ea078c1b74c9e24617c509c6a408eb822e Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Mon, 28 Nov 2016 13:15:58 +0000
-Subject: [PATCH] Prevent possible DoS attempts during protocol handshake
-
-The limit for link message is specified using a 32 bit unsigned integer.
-This could cause possible DoS due to excessive memory allocations and
-some possible crashes.
-For instance a value >= 2^31 causes a spice_assert to be triggered in
-async_read_handler (reds-stream.c) due to an integer overflow at this
-line:
-
-   int n = async->end - async->now;
-
-This could be easily triggered with a program like
-
-  #!/usr/bin/env python
-
-  import socket
-  import time
-  from struct import pack
-
-  server = '127.0.0.1'
-  port = 5900
-
-  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-  s.connect((server, port))
-  data = pack('<4sIII', 'REDQ', 2, 2, 0xaaaaaaaa)
-  s.send(data)
-
-  time.sleep(1)
-
-without requiring any authentication (the same can be done
-with TLS).
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/reds.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 9e1d5e7..1c215ed 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -2826,7 +2826,8 @@ static void reds_handle_read_header_done(void *opaque)
- 
-     reds->peer_minor_version = header->minor_version;
- 
--    if (header->size < sizeof(SpiceLinkMess)) {
-+    /* the check for 4096 is to avoid clients to cause arbitrary big memory allocations */
-+    if (header->size < sizeof(SpiceLinkMess) || header->size > 4096) {
-         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
-         spice_warning("bad size %u", header->size);
-         reds_link_free(link);
--- 
-2.9.3
-
diff --git a/SOURCES/0086-Prevent-integer-overflows-in-capability-checks.patch b/SOURCES/0086-Prevent-integer-overflows-in-capability-checks.patch
deleted file mode 100644
index 83c914d..0000000
--- a/SOURCES/0086-Prevent-integer-overflows-in-capability-checks.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 665f7dddd2d534500d3b3e3e1f8135c49479ad25 Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Mon, 28 Nov 2016 13:15:58 +0000
-Subject: [PATCH] Prevent integer overflows in capability checks
-
-The limits for capabilities are specified using 32 bit unsigned integers.
-This could cause possible integer overflows causing buffer overflows.
-For instance the sum of num_common_caps and num_caps can be 0 avoiding
-additional checks.
-As the link message is now capped to 4096 and the capabilities are
-contained in the link message, this commit limits the capabilities
-to 1024 (capabilities are expressed in number of uint32_t items).
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/reds.c | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/server/reds.c b/server/reds.c
-index 64f07cc..f5542f6 100644
---- a/server/reds.c
-+++ b/server/reds.c
-@@ -2744,6 +2744,14 @@ static void reds_handle_read_link_done(void *opaque)
-     uint32_t num_caps = link_mess->num_common_caps + link_mess->num_channel_caps;
-     int auth_selection;
- 
-+    /* Prevent integer overflows. Currently we defined only 13 capabilities,
-+     * I expect 1024 to be valid for quite a lot time */
-+    if (link_mess->num_channel_caps > 1024 || link_mess->num_common_caps > 1024) {
-+        reds_send_link_error(link, SPICE_LINK_ERR_INVALID_DATA);
-+        reds_link_free(link);
-+        return;
-+    }
-+
-     if (num_caps && (num_caps * sizeof(uint32_t) + link_mess->caps_offset >
-                      link->link_header.size ||
-                      link_mess->caps_offset < sizeof(*link_mess))) {
--- 
-2.9.3
-
diff --git a/SOURCES/0087-main-channel-Prevent-overflow-reading-messages-from-.patch b/SOURCES/0087-main-channel-Prevent-overflow-reading-messages-from-.patch
deleted file mode 100644
index a61dd04..0000000
--- a/SOURCES/0087-main-channel-Prevent-overflow-reading-messages-from-.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From c4e3113a8df53ba60c36829c8b2d583c2d5e529d Mon Sep 17 00:00:00 2001
-From: Frediano Ziglio <fziglio@redhat.com>
-Date: Tue, 29 Nov 2016 16:46:56 +0000
-Subject: [PATCH] main-channel: Prevent overflow reading messages from client
-
-Caller is supposed the function return a buffer able to store
-size bytes.
-
-Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
----
- server/main_channel.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/server/main_channel.c b/server/main_channel.c
-index 54718ba..bedff46 100644
---- a/server/main_channel.c
-+++ b/server/main_channel.c
-@@ -1030,6 +1030,9 @@ static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc,
- 
-     if (type == SPICE_MSGC_MAIN_AGENT_DATA) {
-         return reds_get_agent_data_buffer(mcc, size);
-+    } else if (size > sizeof(main_chan->recv_buf)) {
-+        /* message too large, caller will log a message and close the connection */
-+        return NULL;
-     } else {
-         return main_chan->recv_buf;
-     }
--- 
-2.9.3
-
diff --git a/SPECS/spice.spec b/SPECS/spice.spec
index 86854af..40a708a 100644
--- a/SPECS/spice.spec
+++ b/SPECS/spice.spec
@@ -1,99 +1,16 @@
 Name:           spice
-Version:        0.12.4
-Release:        20%{?dist}
+Version:        0.12.8
+Release:        2%{?dist}
 Summary:        Implements the SPICE protocol
 Group:          User Interface/Desktops
 License:        LGPLv2+
 URL:            http://www.spice-space.org/
 Source0:        http://www.spice-space.org/download/releases/%{name}-%{version}.tar.bz2
-Patch1: 0001-red_channel-prevent-adding-and-pushing-pipe-items-af.patch
-Patch2: 0002-red_channel-add-ref-count-to-RedClient.patch
-Patch3: 0003-main_dispatcher-add-ref-count-protection-to-RedClien.patch
-Patch4: 0004-decouple-disconnection-of-the-main-channel-from-clie.patch
-Patch5: 0005-reds-s-red_client_disconnect-red_channel_client_shut.patch
-Patch6: 0006-snd_worker-fix-memory-leak-of-PlaybackChannel.patch
-Patch7: 0007-snd_worker-snd_disconnect_channel-don-t-call-snd_cha.patch
-Patch8: 0008-log-improve-debug-information-related-to-client-disc.patch
-Patch9: 0009-red_worker-decrease-the-timeout-when-flushing-comman.patch
-Patch10: 0010-Fix-buffer-overflow-when-decrypting-client-SPICE-tic.patch
-Patch11: 0011-server-move-three-functions-to-red_channel.patch
-Patch12: 0012-server-s-red_wait_all_sent-red_channel_wait_all_sent.patch
-Patch13: 0013-red_worker-cleanup-red_clear_surface_drawables_from_.patch
-Patch14: 0014-red_channel-cleanup-of-red_channel_client-blocking-m.patch
-Patch15: 0015-red_worker-disconnect-the-channel-instead-of-shutdow.patch
-Patch16: 0016-spice_timer_queue-don-t-call-timers-repeatedly.patch
-Patch17: 0017-red_channel-add-on_input-callback-for-tracing-incomi.patch
-Patch18: 0018-red_channel-add-option-to-monitor-whether-a-channel-.patch
-Patch19: 0019-main_channel-monitoring-client-connection-status.patch
-Patch20: 0020-Fix-crash-when-clearing-surface-memory.patch
-Patch21: 0021-Fix-assert-in-mjpeg_encoder_adjust_params_to_bit_rat.patch
-Patch22: 0022-reds-lookup-corresponding-channel-id.patch
-Patch23: 0023-dispatcher-lower-a-monitor-config-warning-to-a-debug.patch
-Patch24: 0024-mjpeg-Don-t-warn-on-unsupported-image-formats.patch
-Patch25: 0025-server-Don-t-dump-the-bitmap-when-the-format-is-inva.patch
-Patch26: 0026-Fix-Wunused-parameter.patch
-Patch27: 0027-Fix-Wunused-value.patch
-Patch28: 0028-Fix-Wsign.patch
-Patch29: 0029-Fix-Wswitch.patch
-Patch30: 0030-Fix-Wformat.patch
-Patch31: 0031-Fix-Wnonnull.patch
-Patch32: 0032-Fix-Wmissing-field-initializers.patch
-Patch33: 0033-Fix-Wunused-function.patch
-Patch34: 0034-Validate-surface-bounding-box-before-using-it.patch
-Patch35: 0035-migration-Don-t-assert-if-MIGRATE_DATA-comes-before-.patch
-Patch36: 0036-server-fix-crash-when-restarting-VM-with-old-client.patch
-Patch37: 0037-Use-TLS-version-1.0-or-better.patch
-Patch38: 0038-Add-const-to-test_capability-first-argument.patch
-Patch39: 0039-Introduce-red_link_info_test_capability.patch
-Patch40: 0040-Don-t-set-SpiceLinkReply-pub_key-if-client-advertise.patch
-Patch41: 0041-server-don-t-assert-on-invalid-client-message.patch
-Patch42: 0042-Don-t-truncate-large-now-values-in-_spice_timer_set.patch
-Patch43: 0043-Avoid-race-conditions-reading-monitor-configs-from-g.patch
-Patch44: 0044-Lock-the-pixmap-image-cache-for-the-entire-fill_bits.patch
-Patch45: 0045-reds-Assure-we-don-t-have-stale-statistic-files-befo.patch
-Patch46: 0046-worker-validate-correctly-surfaces.patch
-Patch47: 0047-worker-avoid-double-free-or-double-create-of-surface.patch
-Patch48: 0048-Define-a-constant-to-limit-data-from-guest.patch
-Patch49: 0049-Fix-some-integer-overflow-causing-large-memory-alloc.patch
-Patch50: 0050-Check-properly-surface-to-be-created.patch
-Patch51: 0051-Fix-buffer-reading-overflow.patch
-Patch52: 0052-Prevent-32-bit-integer-overflow-in-bitmap_consistent.patch
-Patch53: 0053-Fix-race-condition-on-red_get_clip_rects.patch
-Patch54: 0054-Fix-race-in-red_get_image.patch
-Patch55: 0055-Fix-race-condition-in-red_get_string.patch
-Patch56: 0056-Fix-integer-overflow-computing-glyph_size-in-red_get.patch
-Patch57: 0057-Fix-race-condition-in-red_get_data_chunks_ptr.patch
-Patch58: 0058-Prevent-memory-leak-if-red_get_data_chunks_ptr-fails.patch
-Patch59: 0059-Prevent-DoS-from-guest-trying-to-allocate-too-much-d.patch
-Patch60: 0060-Fix-some-possible-overflows-in-red_get_string-for-32.patch
-Patch61: 0061-Make-sure-we-can-read-QXLPathSeg-structures.patch
-Patch62: 0062-Avoid-race-condition-copying-segments-in-red_get_pat.patch
-Patch63: 0063-Prevent-data_size-to-be-set-independently-from-data.patch
-Patch64: 0064-Prevent-leak-if-size-from-red_get_data_chunks-don-t-.patch
-Patch65: 0065-smartcard-add-a-ref-to-item-before-adding-to-pipe.patch
-Patch66: 0066-smartcard-allocate-msg-with-the-expected-size.patch
-Patch67: 0067-create-a-function-to-validate-surface-parameters.patch
-Patch68: 0068-improve-primary-surface-parameter-checks.patch
-Patch69: 0069-reds-Do-not-abort-due-to-wrong-header.patch
-Patch70: 0070-memslot-do-not-crash-if-guest-provide-a-wrong-addres.patch
-Patch71: 0071-red-channel-make-red_client_-ref-unref-thread-safe.patch
-Patch72: 0072-chardev-remove-write-polling.patch
-Patch73: 0073-clean-up-remove-unused-function.patch
-Patch74: 0074-Remove-guest-side-video-time-stamping.patch
-Patch75: 0075-char-device-fix-usage-of-free-unref-on-WriteBuffer.patch
-Patch76: 0076-spicevmc-set-state-of-DeviceInstance-to-NULL.patch
-Patch77: 0077-char-device-set-to-NULL-freed-pointers-on-destroy.patch
-Patch78: 0078-channel-add-option-tcp-keepalive-timeout-to-channels.patch
-Patch79: 0079-Always-enable-TCP-keepalive.patch
-Patch80: 0080-Remove-spice_server_set_keepalive_timeout.patch
-Patch81: 0081-sound-do-not-modify-client-state-on-migration.patch
-Patch82: 0082-char-device-spice_char_device_write_to_device-protec.patch
-Patch83: 0083-server-allows-to-set-maximum-monitors.patch
-Patch84: 0084-Call-migrate_end_complete-after-falling-back-to-swit.patch
-Patch85: 0085-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
-Patch86: 0086-Prevent-integer-overflows-in-capability-checks.patch
-Patch87: 0087-main-channel-Prevent-overflow-reading-messages-from-.patch
-
+Patch01: 0001-Call-migrate_end_complete-after-falling-back-to-swit.patch
+Patch02: 0002-Prevent-possible-DoS-attempts-during-protocol-handsh.patch
+Patch03: 0003-Prevent-integer-overflows-in-capability-checks.patch
+Patch04: 0004-main-channel-Prevent-overflow-reading-messages-from-.patch
+Patch05: 0005-reds-Check-link-header-magic-without-waiting-for-the.patch
 
 # https://bugzilla.redhat.com/show_bug.cgi?id=613529
 %if 0%{?rhel}
@@ -104,7 +21,7 @@ ExclusiveArch:  i686 x86_64 armv6l armv7l armv7hl
 
 BuildRequires:  pkgconfig
 BuildRequires:  glib2-devel >= 2.22
-# BuildRequires:  spice-protocol >= 0.12.3 -- not needed since spice-0.11.3
+BuildRequires:  spice-protocol >= 0.12.10
 BuildRequires:  celt051-devel
 BuildRequires:  pixman-devel alsa-lib-devel openssl-devel libjpeg-turbo-devel
 BuildRequires:  libcacard-devel cyrus-sasl-devel
@@ -180,6 +97,15 @@ mkdir -p %{buildroot}%{_libexecdir}
 
 
 %changelog
+* Tue Apr 25 2017 Christophe Fergeau <cfergeau@redhat.com> 0.12.8-2
+- Drop clients immediatly if the magic they send is wrong
+  Resolves: rhbz#1416692
+
+* Mon Jan 16 2017 Christophe Fergeau <cfergeau@redhat.com> 0.12.8-1
+- Rebase to spice-server 0.12.8
+  Resolves: rhbz#1388947
+  Resolves: rhbz#1377551
+  Resolves: rhbz#1283202
 * Fri Dec 09 2016 Frediano Ziglio <fziglio@redhat.com> - 0.12.4-20
 - Fix buffer overflow in main_channel_alloc_msg_rcv_buf when reading large
   messages.