From 8d48dd973a62588760eba14d5f5eb0a6bc6c3b57 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 25 Feb 2019 04:42:58 +1100 Subject: [PATCH] [client] x11: prevent race condition causing double free --- client/clipboard/x11.c | 1 + client/spice/spice.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/client/clipboard/x11.c b/client/clipboard/x11.c index 59b379de..b80f8a24 100644 --- a/client/clipboard/x11.c +++ b/client/clipboard/x11.c @@ -204,6 +204,7 @@ static void x11_cb_wmevent(SDL_SysWMmsg * msg) s->xselection.property = None; XSendEvent(this->display, e.xselectionrequest.requestor, 0, 0, s); XFlush(this->display); + return; } if (e.type == SelectionClear && ( diff --git a/client/spice/spice.c b/client/spice/spice.c index 5b5950ac..11bc4633 100644 --- a/client/spice/spice.c +++ b/client/spice/spice.c @@ -123,6 +123,7 @@ struct Spice bool cbSelection; // clipboard variables + LG_Lock cbLock; bool cbAgentGrabbed; bool cbClientGrabbed; SpiceDataType cbType; @@ -197,6 +198,8 @@ bool spice_connect(const char * host, const unsigned short port, const char * pa DEBUG_INFO("Remote: %s:%u", host, port); } + LG_LOCK_INIT(spice.cbLock); + spice.channelID = 0; if (!spice_connect_channel(&spice.scMain)) { @@ -216,11 +219,14 @@ void spice_disconnect() spice.sessionID = 0; + LG_LOCK(spice.cbLock); if (spice.cbBuffer) free(spice.cbBuffer); spice.cbBuffer = NULL; spice.cbRemain = 0; spice.cbSize = 0; + LG_UNLOCK(spice.cbLock); + LG_LOCK_FREE(spice.cbLock); spice.cbAgentGrabbed = false; spice.cbClientGrabbed = false; @@ -576,6 +582,7 @@ bool spice_on_main_channel_read() DEBUG_INFO("Spice agent disconnected, error: %u", error); spice.hasAgent = false; + LG_LOCK(spice.cbLock); if (spice.cbBuffer) { free(spice.cbBuffer); @@ -583,6 +590,7 @@ bool spice_on_main_channel_read() spice.cbSize = 0; spice.cbRemain = 0; } + LG_UNLOCK(spice.cbLock); return true; } @@ -929,6 +937,7 @@ bool spice_agent_process(uint32_t dataSize) { if (spice.cbRemain) { + LG_LOCK(spice.cbLock); const uint32_t r = spice.cbRemain > dataSize ? dataSize : spice.cbRemain; if (!spice_read_nl(&spice.scMain, spice.cbBuffer + spice.cbSize, r)) { @@ -937,6 +946,7 @@ bool spice_agent_process(uint32_t dataSize) spice.cbBuffer = NULL; spice.cbRemain = 0; spice.cbSize = 0; + LG_UNLOCK(spice.cbLock); return false; } @@ -946,6 +956,7 @@ bool spice_agent_process(uint32_t dataSize) if (spice.cbRemain == 0) spice_agent_on_clipboard(); + LG_UNLOCK(spice.cbLock); return true; } @@ -1045,9 +1056,11 @@ bool spice_agent_process(uint32_t dataSize) if (msg.type == VD_AGENT_CLIPBOARD) { DEBUG_CLIPBOARD("VD_AGENT_CLIPBOARD"); + LG_LOCK(spice.cbLock); if (spice.cbBuffer) { DEBUG_ERROR("cbBuffer was never freed"); + LG_UNLOCK(spice.cbLock); return false; } @@ -1063,6 +1076,7 @@ bool spice_agent_process(uint32_t dataSize) spice.cbBuffer = NULL; spice.cbRemain = 0; spice.cbSize = 0; + LG_UNLOCK(spice.cbLock); return false; } @@ -1072,6 +1086,7 @@ bool spice_agent_process(uint32_t dataSize) if (spice.cbRemain == 0) spice_agent_on_clipboard(); + LG_UNLOCK(spice.cbLock); return true; } else