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.
This commit is contained in:
Ján Tomko 2016-06-29 07:03:13 +02:00
parent ca5d51df27
commit a3f565b339
3 changed files with 9 additions and 4 deletions

View File

@ -221,7 +221,7 @@ adminClientGetInfo(virNetServerClientPtr client,
int ret = -1; int ret = -1;
int maxparams = 0; int maxparams = 0;
bool readonly; bool readonly;
const char *sock_addr = NULL; char *sock_addr = NULL;
const char *attr = NULL; const char *attr = NULL;
virTypedParameterPtr tmpparams = NULL; virTypedParameterPtr tmpparams = NULL;
virIdentityPtr identity = NULL; virIdentityPtr identity = NULL;
@ -300,6 +300,7 @@ adminClientGetInfo(virNetServerClientPtr client,
cleanup: cleanup:
virObjectUnref(identity); virObjectUnref(identity);
VIR_FREE(sock_addr);
return ret; return ret;
} }

View File

@ -1606,20 +1606,24 @@ virNetServerClientGetTransport(virNetServerClientPtr client)
int int
virNetServerClientGetInfo(virNetServerClientPtr client, virNetServerClientGetInfo(virNetServerClientPtr client,
bool *readonly, const char **sock_addr, bool *readonly, char **sock_addr,
virIdentityPtr *identity) virIdentityPtr *identity)
{ {
int ret = -1; int ret = -1;
const char *addr;
virObjectLock(client); virObjectLock(client);
*readonly = client->readonly; *readonly = client->readonly;
if (!(*sock_addr = virNetServerClientRemoteAddrStringURI(client))) { if (!(addr = virNetServerClientRemoteAddrStringURI(client))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No network socket associated with client")); _("No network socket associated with client"));
goto cleanup; goto cleanup;
} }
if (VIR_STRDUP(*sock_addr, addr) < 0)
goto cleanup;
if (!client->identity) { if (!client->identity) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No identity information available for client")); _("No identity information available for client"));

View File

@ -149,7 +149,7 @@ bool virNetServerClientNeedAuth(virNetServerClientPtr client);
int virNetServerClientGetTransport(virNetServerClientPtr client); int virNetServerClientGetTransport(virNetServerClientPtr client);
int virNetServerClientGetInfo(virNetServerClientPtr client, int virNetServerClientGetInfo(virNetServerClientPtr client,
bool *readonly, const char **sock_addr, bool *readonly, char **sock_addr,
virIdentityPtr *identity); virIdentityPtr *identity);
#endif /* __VIR_NET_SERVER_CLIENT_H__ */ #endif /* __VIR_NET_SERVER_CLIENT_H__ */