[libvirt] [PATCH] rpc: for messages with FDs always decode count of FDs from the message
Ján Tomko
jtomko at redhat.com
Wed Sep 27 14:59:46 UTC 2017
On Tue, Sep 26, 2017 at 05:13:37PM +0200, Pavel Hrdina wrote:
>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' ()
>
It would be nice to mention the commit that removed the repeated calling
of virNetMessageDecodeNumFDs because of the memleak.
>Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
>---
> src/rpc/virnetclient.c | 3 +--
> src/rpc/virnetmessage.c | 12 +++++++-----
> src/rpc/virnetserverclient.c | 3 +--
> 3 files changed, 9 insertions(+), 9 deletions(-)
>
ACK regardless of my nosy question below
>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)
Could this leak memory if someone sends us maliciously crafted RPC data
where nfds = 0 and we call the VIR_ALLOC_N multiple times?
Jan
>+ goto cleanup;
>+ for (i = 0; i < msg->nfds; i++)
>+ msg->fds[i] = -1;
>+ }
>
> VIR_DEBUG("Got %zu FDs from peer", msg->nfds);
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170927/5057b4a1/attachment-0001.sig>
More information about the libvir-list
mailing list