If drvNew callback fails, nobody calls drvFree and thus private data of the driver might leak. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/locking/lock_driver_lockd.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c index 2574cd47e2..3012c71eda 100644 --- a/src/locking/lock_driver_lockd.c +++ b/src/locking/lock_driver_lockd.c @@ -377,16 +377,14 @@ static int virLockManagerLockDaemonDeinit(void) return 0; } -static void virLockManagerLockDaemonFree(virLockManagerPtr lock) +static void +virLockManagerLockDaemonPrivateFree(virLockManagerLockDaemonPrivatePtr priv) { - virLockManagerLockDaemonPrivatePtr priv = lock->privateData; size_t i; if (!priv) return; - lock->privateData = NULL; - for (i = 0; i < priv->nresources; i++) { VIR_FREE(priv->resources[i].lockspace); VIR_FREE(priv->resources[i].name); @@ -394,10 +392,18 @@ static void virLockManagerLockDaemonFree(virLockManagerPtr lock) VIR_FREE(priv->resources); VIR_FREE(priv->name); - VIR_FREE(priv); } +static void virLockManagerLockDaemonFree(virLockManagerPtr lock) +{ + if (!lock) + return; + + virLockManagerLockDaemonPrivateFree(lock->privateData); + lock->privateData = NULL; +} + static int virLockManagerLockDaemonNew(virLockManagerPtr lock, unsigned int type, @@ -405,14 +411,14 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock, virLockManagerParamPtr params, unsigned int flags) { - virLockManagerLockDaemonPrivatePtr priv; + virLockManagerLockDaemonPrivatePtr priv = NULL; size_t i; + int ret = -1; virCheckFlags(VIR_LOCK_MANAGER_NEW_STARTED, -1); if (VIR_ALLOC(priv) < 0) return -1; - lock->privateData = priv; switch (type) { 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); } else if (STREQ(params[i].key, "name")) { if (VIR_STRDUP(priv->name, params[i].value.str) < 0) - return -1; + goto cleanup; } else if (STREQ(params[i].key, "id")) { priv->id = params[i].value.iv; } else if (STREQ(params[i].key, "pid")) { @@ -432,24 +438,25 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock, virReportError(VIR_ERR_INTERNAL_ERROR, _("Unexpected parameter %s for object"), params[i].key); + goto cleanup; } } if (priv->id == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing ID parameter for domain object")); - return -1; + goto cleanup; } if (priv->pid == 0) VIR_DEBUG("Missing PID parameter for domain object"); if (!priv->name) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing name parameter for domain object")); - return -1; + goto cleanup; } if (!virUUIDIsValid(priv->uuid)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing UUID parameter for domain object")); - return -1; + goto cleanup; } break; @@ -457,10 +464,14 @@ static int virLockManagerLockDaemonNew(virLockManagerPtr lock, virReportError(VIR_ERR_INTERNAL_ERROR, _("Unknown lock manager object type %d"), type); - return -1; + goto cleanup; } - return 0; + VIR_STEAL_PTR(lock->privateData, priv); + ret = 0; + cleanup: + virLockManagerLockDaemonPrivateFree(priv); + return ret; } -- 2.16.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list