From: Oliver Kurth Date: Fri, 26 Oct 2018 17:44:59 +0000 (-0700) Subject: Clear channel restart timer when RPC channel is destroyed. X-Git-Tag: stable-11.0.0~356 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0c0431824dce19770d91143fb9b7176b2f9b77f;p=thirdparty%2Fopen-vm-tools.git Clear channel restart timer when RPC channel is destroyed. Vmusr main loop destroys the RPC channel when it receives SIGUSR1. However, it may have left the restart timer around that would end up accessing the destroyed channel structure. So, we destroy the timer along with the RPC channel to be safe. --- diff --git a/open-vm-tools/lib/rpcChannel/rpcChannel.c b/open-vm-tools/lib/rpcChannel/rpcChannel.c index 5e7eb5680..5e9548ab9 100644 --- a/open-vm-tools/lib/rpcChannel/rpcChannel.c +++ b/open-vm-tools/lib/rpcChannel/rpcChannel.c @@ -63,6 +63,7 @@ typedef struct RpcChannelInt { RpcChannelFailureCb rpcFailureCb; guint rpcMaxFailures; gboolean rpcInInitialized; + GSource *restartTimer; /* Channel restart timer */ #endif } RpcChannelInt; @@ -122,6 +123,8 @@ RpcChannelRestart(gpointer _chan) /* Synchronize with any RpcChannel_Send calls by other threads. */ g_static_mutex_lock(&chan->impl.outLock); + g_source_unref(chan->restartTimer); + chan->restartTimer = NULL; RpcChannelStopNoLock(&chan->impl); @@ -161,7 +164,6 @@ RpcChannelCheckReset(gpointer _chan) /* Check the channel state. */ if (chan->rpcError) { - GSource *src; if (++(chan->rpcResetErrorCount) > channelTimeoutAttempts) { Warning("Failed to reset channel after %u attempts\n", @@ -174,10 +176,10 @@ RpcChannelCheckReset(gpointer _chan) /* Schedule the channel restart for 1 sec in the future. */ Debug(LGPFX "Resetting channel [%u]\n", chan->rpcResetErrorCount); - src = g_timeout_source_new(1000); - g_source_set_callback(src, RpcChannelRestart, chan, NULL); - g_source_attach(src, chan->mainCtx); - g_source_unref(src); + ASSERT(chan->restartTimer == NULL); + chan->restartTimer = g_timeout_source_new(1000); + g_source_set_callback(chan->restartTimer, RpcChannelRestart, chan, NULL); + g_source_attach(chan->restartTimer, chan->mainCtx); goto exit; } @@ -507,6 +509,15 @@ RpcChannelTeardown(RpcChannel *chan) return; } + /* + * Stop the restartTimer. + */ + if (cdata->restartTimer) { + g_source_destroy(cdata->restartTimer); + g_source_unref(cdata->restartTimer); + cdata->restartTimer = NULL; + } + RpcChannel_UnregisterCallback(chan, &cdata->resetReg); for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]); diff --git a/open-vm-tools/services/vmtoolsd/mainPosix.c b/open-vm-tools/services/vmtoolsd/mainPosix.c index c60f0690e..28293c4f5 100644 --- a/open-vm-tools/services/vmtoolsd/mainPosix.c +++ b/open-vm-tools/services/vmtoolsd/mainPosix.c @@ -103,8 +103,8 @@ ToolsCoreSigUsrHandler(const siginfo_t *info, { ToolsCore_DumpState(&gState); - g_info("Shutting down guestrpc on signal USR1 ...\n"); if (TOOLS_IS_USER_SERVICE(&gState.ctx)) { + g_info("Shutting down guestrpc on signal USR1 ...\n"); RpcChannel_Destroy(gState.ctx.rpc); gState.ctx.rpc = NULL; }