]> xenbits.xensource.com Git - libvirt.git/commitdiff
remote_daemon_stream: Fix @client locking in daemonStreamFilter()
authorLanceLiu <liu.lance.89@gmail.com>
Tue, 19 Nov 2019 11:39:50 +0000 (19:39 +0800)
committerMichal Privoznik <mprivozn@redhat.com>
Tue, 19 Nov 2019 15:09:53 +0000 (16:09 +0100)
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 <liu.lance.89@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/remote/remote_daemon_stream.c
src/rpc/virnetserverclient.h

index c4f14a27ef7b64b5817a4126a20b6c76a698ea7e..82cadb67ac0d26050ed75fc14801d9367933a9d8 100644 (file)
@@ -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)
index 1c520fef6bdff91abf865a2f7eae6bd650df26e2..7a3061d1aeb4264f04fea3127b3d0e924481bf51 100644 (file)
@@ -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);