From 8ecab214de08a4f145f8407a04851cea2ee914c6 Mon Sep 17 00:00:00 2001 From: LanceLiu Date: Tue, 19 Nov 2019 19:39:50 +0800 Subject: [PATCH] remote_daemon_stream: Fix @client locking in daemonStreamFilter() When dispatching a message read from client it is first passed through registered filters. If one of the filters consumes the message no further processing of the message is done. However, the filter callbacks are called with the client object locked. This breaks lock ordering in case of virStream filter, we always acquire stream private data lock without the client object locked. In other words, the daemonStreamFilter() does not follow the lock ordering. Signed-off-by: LanceLiu Signed-off-by: Michal Privoznik Reviewed-by: Michal Privoznik --- src/remote/remote_daemon_stream.c | 4 +++- src/rpc/virnetserverclient.h | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_daemon_stream.c b/src/remote/remote_daemon_stream.c index c4f14a27ef..82cadb67ac 100644 --- a/src/remote/remote_daemon_stream.c +++ b/src/remote/remote_daemon_stream.c @@ -286,14 +286,16 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque) * -1 on fatal client error */ static int -daemonStreamFilter(virNetServerClientPtr client G_GNUC_UNUSED, +daemonStreamFilter(virNetServerClientPtr client, virNetMessagePtr msg, void *opaque) { daemonClientStream *stream = opaque; int ret = 0; + virObjectUnlock(client); virMutexLock(&stream->priv->lock); + virObjectLock(client); if (msg->header.type != VIR_NET_STREAM && msg->header.type != VIR_NET_STREAM_HOLE) diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 1c520fef6b..7a3061d1ae 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -40,6 +40,9 @@ typedef void (*virNetServerClientDispatchFunc)(virNetServerClientPtr client, virNetMessagePtr msg, void *opaque); +/* + * @client is locked when this callback is called + */ typedef int (*virNetServerClientFilterFunc)(virNetServerClientPtr client, virNetMessagePtr msg, void *opaque);