From a3f565b3397f198160ef7591d6979fc8630c673a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Wed, 29 Jun 2016 07:03:13 +0200 Subject: [PATCH] Fix possible invalid read in adminClientGetInfo virNetServerClientGetInfo returns the client's remote address as a string, which is a part of the client object. Use VIR_STRDUP to make a copy which can be freely accessed even after the virNetServerClient object is unlocked. To reproduce, put a sleep between virObjectUnlock in virNetServerClientGetInfo and virTypedParamsAddString in adminClientGetInfo, then close the queried connection during that sleep. --- daemon/admin_server.c | 3 ++- src/rpc/virnetserverclient.c | 8 ++++++-- src/rpc/virnetserverclient.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/daemon/admin_server.c b/daemon/admin_server.c index cb9079c1f3..9f24f680be 100644 --- a/daemon/admin_server.c +++ b/daemon/admin_server.c @@ -221,7 +221,7 @@ adminClientGetInfo(virNetServerClientPtr client, int ret = -1; int maxparams = 0; bool readonly; - const char *sock_addr = NULL; + char *sock_addr = NULL; const char *attr = NULL; virTypedParameterPtr tmpparams = NULL; virIdentityPtr identity = NULL; @@ -300,6 +300,7 @@ adminClientGetInfo(virNetServerClientPtr client, cleanup: virObjectUnref(identity); + VIR_FREE(sock_addr); return ret; } diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index 39fe86073e..81da82cab3 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -1606,20 +1606,24 @@ virNetServerClientGetTransport(virNetServerClientPtr client) int virNetServerClientGetInfo(virNetServerClientPtr client, - bool *readonly, const char **sock_addr, + bool *readonly, char **sock_addr, virIdentityPtr *identity) { int ret = -1; + const char *addr; virObjectLock(client); *readonly = client->readonly; - if (!(*sock_addr = virNetServerClientRemoteAddrStringURI(client))) { + if (!(addr = virNetServerClientRemoteAddrStringURI(client))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No network socket associated with client")); goto cleanup; } + if (VIR_STRDUP(*sock_addr, addr) < 0) + goto cleanup; + if (!client->identity) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No identity information available for client")); diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index c243a68825..a53cc00b20 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -149,7 +149,7 @@ bool virNetServerClientNeedAuth(virNetServerClientPtr client); int virNetServerClientGetTransport(virNetServerClientPtr client); int virNetServerClientGetInfo(virNetServerClientPtr client, - bool *readonly, const char **sock_addr, + bool *readonly, char **sock_addr, virIdentityPtr *identity); #endif /* __VIR_NET_SERVER_CLIENT_H__ */ -- GitLab