1
0

Fix receiving of file descriptors from server

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@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-12-21 16:49:12 +00:00
parent 24bcd8d45a
commit 18937c3ae0
3 changed files with 20 additions and 8 deletions

View File

@ -997,6 +997,11 @@ virNetClientCallDispatchReply(virNetClientPtr client)
thecall->msg->bufferLength = client->msg.bufferLength; thecall->msg->bufferLength = client->msg.bufferLength;
thecall->msg->bufferOffset = client->msg.bufferOffset; 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; thecall->mode = VIR_NET_CLIENT_MODE_COMPLETE;
return 0; return 0;
@ -1290,7 +1295,9 @@ virNetClientIOHandleInput(virNetClientPtr client)
if (client->msg.header.type == VIR_NET_REPLY_WITH_FDS) { if (client->msg.header.type == VIR_NET_REPLY_WITH_FDS) {
size_t i; size_t i;
if (virNetMessageDecodeNumFDs(&client->msg) < 0)
if (client->msg.nfds == 0 &&
virNetMessageDecodeNumFDs(&client->msg) < 0)
return -1; return -1;
for (i = client->msg.donefds ; i < client->msg.nfds ; i++) { for (i = client->msg.donefds ; i < client->msg.nfds ; i++) {
@ -1313,8 +1320,7 @@ virNetClientIOHandleInput(virNetClientPtr client)
} }
ret = virNetClientCallDispatch(client); ret = virNetClientCallDispatch(client);
client->msg.bufferOffset = client->msg.bufferLength = 0; virNetMessageClear(&client->msg);
VIR_FREE(client->msg.buffer);
/* /*
* We've completed one call, but we don't want to * We've completed one call, but we don't want to
* spin around the loop forever if there are many * spin around the loop forever if there are many

View File

@ -362,18 +362,18 @@ int virNetClientProgramCall(virNetClientProgramPtr prog,
goto error; goto error;
} }
for (i = 0 ; i < *ninfds ; i++) for (i = 0 ; i < *ninfds ; i++)
*infds[i] = -1; (*infds)[i] = -1;
for (i = 0 ; i < *ninfds ; i++) { for (i = 0 ; i < *ninfds ; i++) {
if ((*infds[i] = dup(msg->fds[i])) < 0) { if (((*infds)[i] = dup(msg->fds[i])) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("Cannot duplicate FD %d"), _("Cannot duplicate FD %d"),
msg->fds[i]); msg->fds[i]);
goto error; goto error;
} }
if (virSetInherit(*infds[i], false) < 0) { if (virSetInherit((*infds)[i], false) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("Cannot set close-on-exec %d"), _("Cannot set close-on-exec %d"),
*infds[i]); (*infds)[i]);
goto error; goto error;
} }
} }
@ -401,7 +401,7 @@ error:
virNetMessageFree(msg); virNetMessageFree(msg);
if (infds && ninfds) { if (infds && ninfds) {
for (i = 0 ; i < *ninfds ; i++) for (i = 0 ; i < *ninfds ; i++)
VIR_FORCE_CLOSE(*infds[i]); VIR_FORCE_CLOSE((*infds)[i]);
} }
return -1; return -1;
} }

View File

@ -175,6 +175,12 @@ int virNetMessageDecodeHeader(virNetMessagePtr msg)
XDR xdr; XDR xdr;
int ret = -1; 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; msg->bufferOffset = VIR_NET_MESSAGE_LEN_MAX;
/* Parse the header. */ /* Parse the header. */