From 71de8d92f20a9a9ee76d4d5df77ff477f1b7d441 Mon Sep 17 00:00:00 2001 From: Matthias Bolte Date: Wed, 30 Sep 2009 02:17:27 +0200 Subject: [PATCH] Fix memory leaks in libvirtd's message processing Commit 47cab734995fa9521b1df05d37e9978eedd8d3a2 changed the way how qemud_client_message objects were reused. Before this commit remoteDispatchClientRequest() reused the received message for normal responses and to report non-fatal errors. If a fatal error occurred qemudWorker() frees the message. After this commit non-fatal errors are reported by remoteSerializeReplyError() using a new qemud_client_message object and the original message leaks. To fix this leak the original message has to be freed if remoteSerializeReplyError() succeeds. If remoteSerializeReplyError() fails the original message is freed in qemudWorker(). * daemon/dispatch.c: free qemud_client_message objects that will not be reused and would leak otherwise, also free the allocated qemud_client_message object in remoteSerializeError() if an error occurs (cherry-picked from commit c6f1459eb998619ab21a92d9bb87341f26978181) Fedora-patch: libvirt-fix-libvirtd-leak-in-error-reply.patch --- qemud/dispatch.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diff --git a/qemud/dispatch.c b/qemud/dispatch.c index a60f2f4..ddb3215 100644 --- a/qemud/dispatch.c +++ b/qemud/dispatch.c @@ -191,6 +191,7 @@ remoteSerializeError(struct qemud_client *client, xdr_error: xdr_destroy(&xdr); + VIR_FREE(msg); fatal_error: xdr_free((xdrproc_t)xdr_remote_error, (char *)rerr); return -1; @@ -336,6 +337,7 @@ remoteDispatchClientRequest (struct qemud_server *server, struct qemud_client *client, struct qemud_client_message *msg) { + int ret; remote_error rerr; memset(&rerr, 0, sizeof rerr); @@ -364,7 +366,12 @@ remoteDispatchClientRequest (struct qemud_server *server, } error: - return remoteSerializeReplyError(client, &rerr, &msg->hdr); + ret = remoteSerializeReplyError(client, &rerr, &msg->hdr); + + if (ret >= 0) + VIR_FREE(msg); + + return ret; } @@ -521,8 +528,12 @@ remoteDispatchClientCall (struct qemud_server *server, rpc_error: /* Semi-bad stuff happened, we can still try to send back * an RPC error message to client */ - return remoteSerializeReplyError(client, &rerr, &msg->hdr); + rv = remoteSerializeReplyError(client, &rerr, &msg->hdr); + + if (rv >= 0) + VIR_FREE(msg); + return rv; xdr_error: /* Seriously bad stuff happened, so we'll kill off this client -- 1.6.2.5