From 425b9f8aa6329365d2af753d97c8d834f1ee78fc Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Thu, 27 Sep 2018 17:41:07 -0400 Subject: [PATCH] libxl: Fix possible object refcnt issue When libxlDomainMigrationDstPrepare adds the @args to an virNetSocketAddIOCallback using libxlMigrateDstReceive as the target of the virNetSocketIOFunc @func with the knowledge that the libxlMigrateDstReceive will virObjectUnref @args at the end thus not needing to Unref during normal processing for libxlDomainMigrationDstPrepare. However, Coverity believes there's an issue with this. The problem is there can be @nsocks virNetSocketAddIOCallback's added, but only one virObjectUnref. That means the first one done will Unref and the subsequent callers may not get the @args (or @opaque) as they expected. If there's only one socket returned from virNetSocketNewListenTCP, then sure that works. However, if it returned more than one there's going to be a problem. To resolve this, since we start with 1 reference from the virObjectNew for @args, we will add 1 reference for each time @args is used for virNetSocketAddIOCallback. Then since libxlDomainMigrationDstPrepare would be done with @args, move it's virObjectUnref from the error: label to the done: label (since error: falls through). That way once the last IOCallback is done, then @args will be freed. Signed-off-by: John Ferlan ACKed-by: Michal Privoznik --- src/libxl/libxl_migration.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index fc7ccb53d0..88d7ecf2ce 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -793,7 +793,7 @@ libxlDomainMigrationDstPrepare(virConnectPtr dconn, if (virNetSocketAddIOCallback(socks[i], VIR_EVENT_HANDLE_READABLE, libxlMigrateDstReceive, - args, + virObjectRef(args), NULL) < 0) continue; @@ -815,7 +815,6 @@ libxlDomainMigrationDstPrepare(virConnectPtr dconn, virObjectUnref(socks[i]); } VIR_FREE(socks); - virObjectUnref(args); if (priv) { virPortAllocatorRelease(priv->migrationPort); priv->migrationPort = 0; @@ -831,6 +830,7 @@ libxlDomainMigrationDstPrepare(virConnectPtr dconn, VIR_FREE(hostname); else virURIFree(uri); + virObjectUnref(args); virDomainObjEndAPI(&vm); virObjectUnref(cfg); return ret;