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@xxxxxxxxxx> --- 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 2ea547563..e5336265e 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 2dc39c23c..55a82745e 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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel