summaryrefslogtreecommitdiff
path: root/src/rpc/virnetmessage.c
diff options
context:
space:
mode:
authorPavel Hrdina <phrdina@redhat.com>2017-09-26 16:47:20 +0200
committerPavel Hrdina <phrdina@redhat.com>2017-09-27 18:56:32 +0200
commit5c52aed174b386f897fce870b2453e6cee5ebbc3 (patch)
tree76f9e5ce9dc9a30c0c9faec23bbec74416e2da46 /src/rpc/virnetmessage.c
parent3685e2dd64f8565d739953bde871860f343436e4 (diff)
downloadlibvirt-5c52aed174b386f897fce870b2453e6cee5ebbc3.tar.gz
rpc: for messages with FDs always decode count of FDs from the message
The packet with passed FD has the following format: -------------------------- | len | header | payload | -------------------------- where "payload" has an additional count of FDs before the actual data: ------------------ | nfds | payload | ------------------ When the packet is received we parse the "header", which as a side effect updates msg->bufferOffset to point to the beginning of "payload". If the message call contains FDs, we need to also parse the count of FDs, which also updates the msg->bufferOffset. The issue here is that when we attempt to read the FDs data from the socket and we receive EAGAIN we finish the reading and call poll() to wait for the data the we need. When the data arrives we already have the packet in our buffer so we read the "header" again but this time we don't read the count of FDs because we already have it stored. That means that the msg->bufferOffset is not updated to point to the actual beginning of the payload data, but it points to the count of FDs. After all FDs are processed we dispatch the message to process it and decode the payload. Since the msg->bufferOffset points to wrong data, we decode the wrong payload and the API call fails with error messages: Domain not found: no domain with matching uuid '67656e65-7269-6300-0c87-5003ca6941f2' () Broken by commit 133c511b527 which fixed a FD and memory leak. Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Diffstat (limited to 'src/rpc/virnetmessage.c')
-rw-r--r--src/rpc/virnetmessage.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c
index 5908b074a8..94c4c89e4f 100644
--- a/src/rpc/virnetmessage.c
+++ b/src/rpc/virnetmessage.c
@@ -327,11 +327,13 @@ int virNetMessageDecodeNumFDs(virNetMessagePtr msg)
goto cleanup;
}
- msg->nfds = numFDs;
- if (VIR_ALLOC_N(msg->fds, msg->nfds) < 0)
- goto cleanup;
- for (i = 0; i < msg->nfds; i++)
- msg->fds[i] = -1;
+ if (msg->nfds == 0) {
+ msg->nfds = numFDs;
+ if (VIR_ALLOC_N(msg->fds, msg->nfds) < 0)
+ goto cleanup;
+ for (i = 0; i < msg->nfds; i++)
+ msg->fds[i] = -1;
+ }
VIR_DEBUG("Got %zu FDs from peer", msg->nfds);