Het Gala <het.g...@nutanix.com> writes: > On 28/11/23 12:46 pm, Markus Armbruster wrote: >> Your commit message is all in one line. You need to format it like >> >> migration: Plug memory leak >> >> 'channel' and 'addr' in qmp_migrate() are not auto-freed. >> migrate_uri_parse() allocates memory which is returned to 'channel', >> which is leaked because there is no code for freeing 'channel' or >> 'addr'. So, free addr and channel to avoid memory leak. 'addr' >> does shallow copying of channel->addr, hence free 'channel' itself >> and deep free contents of 'addr'. >> >> Het Gala<het.g...@nutanix.com> writes: > Yeah, I made the changes in v2 patchset. >>> --- >>> migration/migration.c | 2 ++ >>> 1 file changed, 2 insertions(+) >>> >>> diff --git a/migration/migration.c b/migration/migration.c >>> index 28a34c9068..29efb51b62 100644 >>> --- a/migration/migration.c >>> +++ b/migration/migration.c >>> @@ -2004,6 +2004,8 @@ void qmp_migrate(const char *uri, bool has_channels, >>> MIGRATION_STATUS_FAILED); >>> block_cleanup_parameters(); >>> } >>> + g_free(channel); >>> + qapi_free_MigrationAddress(addr); >>> if (local_err) { >>> if (!resume_requested) { >> 2. hmp_migrate() >> >> hmp_migrate() allocates @channel with migrate_uri_parse(), adds it to >> list @caps, passes @caps to qmp_migrate(), then frees @caps with >> qapi_free_MigrationChannelList(). > > Markus, sorry if I was not able to put point clearly, what I meant is that > the local 'channel' variable used in qmp_migrate() i.e. > > 'MigrationChannel *channel = NULL', is defined in qmp_migrate() and if the > user opts for 'uri' then '@channels' coming from hmp_migrate() will be NULL, > and then migrate_uri_parse() will populate memory into 'channel', and that is > not getting freed after it's use is over. > > I think, that is where memory leak might be happening ?
Aha! if (uri && has_channels) { error_setg(errp, "'uri' and 'channels' arguments are mutually " "exclusive; exactly one of the two should be present in " "'migrate' qmp command "); return; } else if (channels) { /* To verify that Migrate channel list has only item */ if (channels->next) { error_setg(errp, "Channel list has more than one entries"); return; } channel = channels->value; } else if (uri) { /* caller uses the old URI syntax */ if (!migrate_uri_parse(uri, &channel, errp)) { return; } } else { error_setg(errp, "neither 'uri' or 'channels' argument are " "specified in 'migrate' qmp command "); return; } At this point, @channel is either channels->value, or from migrate_uri_parse(). We must not free in the former case, we must free in the latter case, Before your patch, we don't free. Memory leak in the latter case. Afterwards, we free. Double-free in the former case. You could guard the free, like so: if (uri) { qapi_free_MigrationChannel(channel); } By the way, I the conditional shown above is harder to understand than necessary. I like to get the errors out of the way at the beginning, like this: if (uri && has_channels) { error_setg(errp, "'uri' and 'channels' arguments are mutually " "exclusive; exactly one of the two should be present in " "'migrate' qmp command "); return; } if (!uri && !has_channels) { error_setg(errp, "neither 'uri' or 'channels' argument are " "specified in 'migrate' qmp command "); return; } if (channels) { /* To verify that Migrate channel list has only item */ Or even if (!uri == !has_channels) { error_setg(errp, "need either 'uri' or 'channels' argument") return; } Suggestion, not demand. If you do it, separate patch.