From: Jacek Caban Subject: rpcrt4: Always protect ref access for connections associated with protseq in RPCRT4_ReleaseConnection. Message-Id: Date: Wed, 2 Aug 2017 15:51:09 +0200 Signed-off-by: Jacek Caban --- dlls/rpcrt4/rpc_transport.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index 48def497bb..5735b0f58e 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -3382,20 +3382,24 @@ RpcConnection *RPCRT4_GrabConnection(RpcConnection *connection) void RPCRT4_ReleaseConnection(RpcConnection *connection) { - LONG ref = InterlockedDecrement(&connection->ref); + LONG ref; - if (!ref && connection->protseq) + /* protseq stores a list of active connections, but does not own references to them. + * It may need to grab a connection from the list, which could lead to a race if + * connection is being released, but not yet removed from the list. We handle that + * by synchronizing on CS here. */ + if (connection->protseq) { - /* protseq stores a list of active connections, but does not own references to them. - * It may need to grab a connection from the list, which could lead to a race if - * connection is being released, but not yet removed from the list. We handle that - * by synchronizing on CS here. */ EnterCriticalSection(&connection->protseq->cs); - ref = connection->ref; + ref = InterlockedDecrement(&connection->ref); if (!ref) list_remove(&connection->protseq_entry); LeaveCriticalSection(&connection->protseq->cs); } + else + { + ref = InterlockedDecrement(&connection->ref); + } TRACE("%p ref=%u\n", connection, ref);