[libvirt] [PATCH 2/9] Fix receiving of file descriptors from server

Daniel P. Berrange berrange at redhat.com
Fri Dec 21 17:08:25 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

A number of bugs handling file descriptors received from the
server caused the FDs to be lost and leaked.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/rpc/virnetclient.c        | 12 +++++++++---
 src/rpc/virnetclientprogram.c | 10 +++++-----
 src/rpc/virnetmessage.c       |  6 ++++++
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 208e2e9..bdceccf 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -997,6 +997,11 @@ virNetClientCallDispatchReply(virNetClientPtr client)
     thecall->msg->bufferLength = client->msg.bufferLength;
     thecall->msg->bufferOffset = client->msg.bufferOffset;
 
+    thecall->msg->nfds = client->msg.nfds;
+    thecall->msg->fds = client->msg.fds;
+    client->msg.nfds = 0;
+    client->msg.fds = NULL;
+
     thecall->mode = VIR_NET_CLIENT_MODE_COMPLETE;
 
     return 0;
@@ -1290,7 +1295,9 @@ virNetClientIOHandleInput(virNetClientPtr client)
 
                 if (client->msg.header.type == VIR_NET_REPLY_WITH_FDS) {
                     size_t i;
-                    if (virNetMessageDecodeNumFDs(&client->msg) < 0)
+
+                    if (client->msg.nfds == 0 &&
+                        virNetMessageDecodeNumFDs(&client->msg) < 0)
                         return -1;
 
                     for (i = client->msg.donefds ; i < client->msg.nfds ; i++) {
@@ -1313,8 +1320,7 @@ virNetClientIOHandleInput(virNetClientPtr client)
                 }
 
                 ret = virNetClientCallDispatch(client);
-                client->msg.bufferOffset = client->msg.bufferLength = 0;
-                VIR_FREE(client->msg.buffer);
+                virNetMessageClear(&client->msg);
                 /*
                  * We've completed one call, but we don't want to
                  * spin around the loop forever if there are many
diff --git a/src/rpc/virnetclientprogram.c b/src/rpc/virnetclientprogram.c
index a179b8d..9410cff 100644
--- a/src/rpc/virnetclientprogram.c
+++ b/src/rpc/virnetclientprogram.c
@@ -362,18 +362,18 @@ int virNetClientProgramCall(virNetClientProgramPtr prog,
                 goto error;
             }
             for (i = 0 ; i < *ninfds ; i++)
-                *infds[i] = -1;
+                (*infds)[i] = -1;
             for (i = 0 ; i < *ninfds ; i++) {
-                if ((*infds[i] = dup(msg->fds[i])) < 0) {
+                if (((*infds)[i] = dup(msg->fds[i])) < 0) {
                     virReportSystemError(errno,
                                          _("Cannot duplicate FD %d"),
                                          msg->fds[i]);
                     goto error;
                 }
-                if (virSetInherit(*infds[i], false) < 0) {
+                if (virSetInherit((*infds)[i], false) < 0) {
                     virReportSystemError(errno,
                                          _("Cannot set close-on-exec %d"),
-                                         *infds[i]);
+                                         (*infds)[i]);
                     goto error;
                 }
             }
@@ -401,7 +401,7 @@ error:
     virNetMessageFree(msg);
     if (infds && ninfds) {
         for (i = 0 ; i < *ninfds ; i++)
-            VIR_FORCE_CLOSE(*infds[i]);
+            VIR_FORCE_CLOSE((*infds)[i]);
     }
     return -1;
 }
diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c
index b7330de..647fef7 100644
--- a/src/rpc/virnetmessage.c
+++ b/src/rpc/virnetmessage.c
@@ -175,6 +175,12 @@ int virNetMessageDecodeHeader(virNetMessagePtr msg)
     XDR xdr;
     int ret = -1;
 
+    if (msg->bufferLength < VIR_NET_MESSAGE_LEN_MAX) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Unable to decode header until len is received"));
+        return -1;
+    }
+
     msg->bufferOffset = VIR_NET_MESSAGE_LEN_MAX;
 
     /* Parse the header. */
-- 
1.7.11.7




More information about the libvir-list mailing list