[Spice-devel] [PATCH spice-server v2 2/3] reds-stream: Allows to change core interface

Frediano Ziglio fziglio at redhat.com
Wed Aug 30 09:36:37 UTC 2017


When a stream is moved from the main thread to a
secondary one the events are potentially registered
using a different core interface. This cause memory
corruption accessing the watch registered in RedsStream.
This patch allows to always use the right interface.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/reds-stream.c | 18 +++++++++++++-----
 server/reds-stream.h |  1 +
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/server/reds-stream.c b/server/reds-stream.c
index 2ea54756..e5336265 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -98,6 +98,7 @@ struct RedsStreamPrivate {
     ssize_t (*writev)(RedsStream *s, const struct iovec *iov, int iovcnt);
 
     RedsState *reds;
+    SpiceCoreInterfaceInternal *core;
 };
 
 static ssize_t stream_write_cb(RedsStream *s, const void *buf, size_t size)
@@ -170,7 +171,7 @@ static ssize_t stream_ssl_read_cb(RedsStream *s, void *buf, size_t size)
 void reds_stream_remove_watch(RedsStream* s)
 {
     if (s->watch) {
-        reds_core_watch_remove(s->priv->reds, s->watch);
+        s->priv->core->watch_remove(s->priv->core, s->watch);
         s->watch = NULL;
     }
 }
@@ -418,6 +419,7 @@ RedsStream *reds_stream_new(RedsState *reds, int socket)
     stream->priv = (RedsStreamPrivate *)(stream+1);
     stream->priv->info = spice_new0(SpiceChannelEventInfo, 1);
     stream->priv->reds = reds;
+    stream->priv->core = reds_get_core_interface(reds);
     reds_stream_set_socket(stream, socket);
 
     stream->priv->read = stream_read_cb;
@@ -427,6 +429,12 @@ RedsStream *reds_stream_new(RedsState *reds, int socket)
     return stream;
 }
 
+void reds_stream_set_core_interface(RedsStream *stream, SpiceCoreInterfaceInternal *core)
+{
+    reds_stream_remove_watch(stream);
+    stream->priv->core = core;
+}
+
 bool reds_stream_is_ssl(RedsStream *stream)
 {
     return (stream->priv->ssl != NULL);
@@ -511,7 +519,7 @@ static void async_read_handler(G_GNUC_UNUSED int fd,
 {
     AsyncRead *async = (AsyncRead *)data;
     RedsStream *stream = async->stream;
-    RedsState *reds = stream->priv->reds;
+    SpiceCoreInterfaceInternal *core = stream->priv->core;
 
     for (;;) {
         int n = async->end - async->now;
@@ -523,9 +531,9 @@ static void async_read_handler(G_GNUC_UNUSED int fd,
             switch (err) {
             case EAGAIN:
                 if (!stream->watch) {
-                    stream->watch = reds_core_watch_add(reds, stream->socket,
-                                                        SPICE_WATCH_EVENT_READ,
-                                                        async_read_handler, async);
+                    stream->watch = core->watch_add(core, stream->socket,
+                                                    SPICE_WATCH_EVENT_READ,
+                                                    async_read_handler, async);
                 }
                 return;
             case EINTR:
diff --git a/server/reds-stream.h b/server/reds-stream.h
index 2dc39c23..55a82745 100644
--- a/server/reds-stream.h
+++ b/server/reds-stream.h
@@ -67,6 +67,7 @@ void reds_stream_remove_watch(RedsStream* s);
 void reds_stream_set_channel(RedsStream *stream, int connection_id,
                              int channel_type, int channel_id);
 RedsStream *reds_stream_new(RedsState *reds, int socket);
+void reds_stream_set_core_interface(RedsStream *stream, SpiceCoreInterfaceInternal *core);
 bool reds_stream_is_ssl(RedsStream *stream);
 RedsStreamSslStatus reds_stream_ssl_accept(RedsStream *stream);
 int reds_stream_enable_ssl(RedsStream *stream, SSL_CTX *ctx);
-- 
2.13.5



More information about the Spice-devel mailing list