From 45e00c7f2d9094de8ac90ea24b3638ca514013fb Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Tue, 3 Jul 2018 13:37:33 +0200 Subject: [PATCH] rpc: Fix deadlock if there is no worker pool available @srv must be unlocked for the call virNetServerProcessMsg otherwise a deadlock can occur. Since the pointer 'srv->workers' will never be changed after initialization and the thread pool has it's own locking we can release the lock of 'srv' earlier. This also fixes the deadlock. Signed-off-by: Marc Hartmayer Reviewed-by: Boris Fiuczynski Reviewed-by: Bjoern Walk Reviewed-by: John Ferlan --- src/rpc/virnetserver.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 5c7f7dd08f..c26637ed03 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -51,6 +51,7 @@ struct _virNetServer { char *name; + /* Immutable pointer, self-locking APIs */ virThreadPoolPtr workers; char *mdnsGroupName; @@ -177,9 +178,11 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque) VIR_FREE(job); } -static void virNetServerDispatchNewMessage(virNetServerClientPtr client, - virNetMessagePtr msg, - void *opaque) + +static void +virNetServerDispatchNewMessage(virNetServerClientPtr client, + virNetMessagePtr msg, + void *opaque) { virNetServerPtr srv = opaque; virNetServerProgramPtr prog = NULL; @@ -196,6 +199,11 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client, break; } } + /* we can unlock @srv since @prog can only become invalid in case + * of disposing @srv, but let's grab a ref first to ensure nothing + * disposes of it before we use it. */ + virObjectRef(srv); + virObjectUnlock(srv); if (srv->workers) { virNetServerJobPtr job; @@ -223,15 +231,16 @@ static void virNetServerDispatchNewMessage(virNetServerClientPtr client, goto error; } - virObjectUnlock(srv); + virObjectUnref(srv); return; error: virNetMessageFree(msg); virNetServerClientClose(client); - virObjectUnlock(srv); + virObjectUnref(srv); } + /** * virNetServerCheckLimits: * @srv: server to check limits on -- GitLab