From: "Daniel P. Berrange" <berrange(a)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(a)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