]> xenbits.xensource.com Git - libvirt.git/commitdiff
remote: fix stream use-after-free
authorOleg Vasilev <oleg.vasilev@virtuozzo.com>
Tue, 4 Jul 2023 07:10:22 +0000 (13:10 +0600)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 24 Jul 2023 12:32:08 +0000 (14:32 +0200)
Inside daemonStreamHandleWrite on stream completion (status=OK) we
reuse msg object to send confirmation.

Only after that, msg is poped from the queue and checked for continue.
By that time, msg might've already been processed for the confirmation
and freed.

Signed-off-by: Oleg Vasilev <oleg.vasilev@virtuozzo.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/remote/remote_daemon_stream.c

index 38a2b6cceb3c8fb757dd9258b3d43164e9ff5325..345c40b48cb2982d9d2aa9b30b22b7dffc5d6ce9 100644 (file)
@@ -740,10 +740,11 @@ static int
 daemonStreamHandleWrite(virNetServerClient *client,
                         daemonClientStream *stream)
 {
+    virNetMessageStatus status = VIR_NET_OK;
     VIR_DEBUG("client=%p, stream=%p", client, stream);
 
     while (stream->rx && !stream->closed) {
-        virNetMessage *msg = stream->rx;
+        virNetMessage *msg = virNetMessageQueueServe(&stream->rx);
         int ret;
 
         if (msg->header.type == VIR_NET_STREAM_HOLE) {
@@ -752,7 +753,8 @@ daemonStreamHandleWrite(virNetServerClient *client,
              * data. */
             ret = daemonStreamHandleHole(client, stream, msg);
         } else if (msg->header.type == VIR_NET_STREAM) {
-            switch (msg->header.status) {
+            status = msg->header.status;
+            switch (status) {
             case VIR_NET_OK:
                 ret = daemonStreamHandleFinish(client, stream, msg);
                 break;
@@ -776,7 +778,6 @@ daemonStreamHandleWrite(virNetServerClient *client,
         if (ret > 0)
             break;  /* still processing data from msg */
 
-        virNetMessageQueueServe(&stream->rx);
         if (ret < 0) {
             virNetMessageFree(msg);
             virNetServerClientImmediateClose(client);
@@ -789,7 +790,7 @@ daemonStreamHandleWrite(virNetServerClient *client,
          * onto the wire, but this causes the client to reset
          * its active request count / throttling
          */
-        if (msg->header.status == VIR_NET_CONTINUE) {
+        if (status == VIR_NET_CONTINUE) {
             virNetMessageClear(msg);
             msg->header.type = VIR_NET_REPLY;
             if (virNetServerClientSendMessage(client, msg) < 0) {