locking: Don't leak private data in virLockManagerLockDaemonNew

If drvNew callback fails, nobody calls drvFree and thus private
data of the driver might leak.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Michal Privoznik 2018-08-22 08:58:32 +02:00
parent db75a8fb9d
commit 20398871fd

View File

@ -377,16 +377,14 @@ static int virLockManagerLockDaemonDeinit(void)
return 0; return 0;
} }
static void virLockManagerLockDaemonFree(virLockManagerPtr lock) static void
virLockManagerLockDaemonPrivateFree(virLockManagerLockDaemonPrivatePtr priv)
{ {
virLockManagerLockDaemonPrivatePtr priv = lock->privateData;
size_t i; size_t i;
if (!priv) if (!priv)
return; return;
lock->privateData = NULL;
for (i = 0; i < priv->nresources; i++) { for (i = 0; i < priv->nresources; i++) {
VIR_FREE(priv->resources[i].lockspace); VIR_FREE(priv->resources[i].lockspace);
VIR_FREE(priv->resources[i].name); VIR_FREE(priv->resources[i].name);
@ -394,10 +392,18 @@ static void virLockManagerLockDaemonFree(virLockManagerPtr lock)
VIR_FREE(priv->resources); VIR_FREE(priv->resources);
VIR_FREE(priv->name); VIR_FREE(priv->name);
VIR_FREE(priv); VIR_FREE(priv);
} }
static void virLockManagerLockDaemonFree(virLockManagerPtr lock)
{
if (!lock)
return;
virLockManagerLockDaemonPrivateFree(lock->privateData);
lock->privateData = NULL;
}
static int virLockManagerLockDaemonNew(virLockManagerPtr lock, static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
unsigned int type, unsigned int type,
@ -405,14 +411,14 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
virLockManagerParamPtr params, virLockManagerParamPtr params,
unsigned int flags) unsigned int flags)
{ {
virLockManagerLockDaemonPrivatePtr priv; virLockManagerLockDaemonPrivatePtr priv = NULL;
size_t i; size_t i;
int ret = -1;
virCheckFlags(VIR_LOCK_MANAGER_NEW_STARTED, -1); virCheckFlags(VIR_LOCK_MANAGER_NEW_STARTED, -1);
if (VIR_ALLOC(priv) < 0) if (VIR_ALLOC(priv) < 0)
return -1; return -1;
lock->privateData = priv;
switch (type) { switch (type) {
case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN: case VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN:
@ -421,7 +427,7 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
memcpy(priv->uuid, params[i].value.uuid, VIR_UUID_BUFLEN); memcpy(priv->uuid, params[i].value.uuid, VIR_UUID_BUFLEN);
} else if (STREQ(params[i].key, "name")) { } else if (STREQ(params[i].key, "name")) {
if (VIR_STRDUP(priv->name, params[i].value.str) < 0) if (VIR_STRDUP(priv->name, params[i].value.str) < 0)
return -1; goto cleanup;
} else if (STREQ(params[i].key, "id")) { } else if (STREQ(params[i].key, "id")) {
priv->id = params[i].value.iv; priv->id = params[i].value.iv;
} else if (STREQ(params[i].key, "pid")) { } else if (STREQ(params[i].key, "pid")) {
@ -432,24 +438,25 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected parameter %s for object"), _("Unexpected parameter %s for object"),
params[i].key); params[i].key);
goto cleanup;
} }
} }
if (priv->id == 0) { if (priv->id == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ID parameter for domain object")); _("Missing ID parameter for domain object"));
return -1; goto cleanup;
} }
if (priv->pid == 0) if (priv->pid == 0)
VIR_DEBUG("Missing PID parameter for domain object"); VIR_DEBUG("Missing PID parameter for domain object");
if (!priv->name) { if (!priv->name) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing name parameter for domain object")); _("Missing name parameter for domain object"));
return -1; goto cleanup;
} }
if (!virUUIDIsValid(priv->uuid)) { if (!virUUIDIsValid(priv->uuid)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing UUID parameter for domain object")); _("Missing UUID parameter for domain object"));
return -1; goto cleanup;
} }
break; break;
@ -457,10 +464,14 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown lock manager object type %d"), _("Unknown lock manager object type %d"),
type); type);
return -1; goto cleanup;
} }
return 0; VIR_STEAL_PTR(lock->privateData, priv);
ret = 0;
cleanup:
virLockManagerLockDaemonPrivateFree(priv);
return ret;
} }