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:
parent
24bcd8d45a
commit
18937c3ae0
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user