[libvirt] [PATCH] remote: Don't leak gnutls session on negotiation error

Matthias Bolte matthias.bolte at googlemail.com
Sat Mar 26 15:44:48 UTC 2011


2011/3/26 Eric Blake <eblake at redhat.com>:
> On 03/26/2011 07:59 AM, Matthias Bolte wrote:
>> ---
>>
>> Found while trying to reproduce another reported memory leak in doRemoteOpen.
>>
>> This leaked 10kb per failing call to negotiate_gnutls_on_connection.
>>
>>  src/remote/remote_driver.c |   28 +++++++++++++++++++---------
>>  1 files changed, 19 insertions(+), 9 deletions(-)
>
> ACK with two changes removed:
>
>>
>> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
>> index b05bbcb..0915548 100644
>> --- a/src/remote/remote_driver.c
>> +++ b/src/remote/remote_driver.c
>> @@ -1331,8 +1331,9 @@ negotiate_gnutls_on_connection (virConnectPtr conn,
>>          GNUTLS_CRT_OPENPGP,
>>          0
>>      };
>> +    bool success = false;
>
> Good.
>
>>      int err;
>> -    gnutls_session_t session;
>> +    gnutls_session_t session = NULL;
>
> This line is not appropriate; gnutls_session_t is an opaque type and
> might be a structure (and thus incompatible with NULL).  It happens to
> be a pointer now, but we shouldn't rely on that.

Well, we already rely on gnutls_session_t being assignment compatible
with NULL as the negotiate_gnutls_on_connection has return type
gnutls_session_t and we return NULL on error. But I agree that your
version needs this assumption in less places.

>>
>>      /* Initialize TLS session
>>       */
>> @@ -1341,7 +1342,7 @@ negotiate_gnutls_on_connection (virConnectPtr conn,
>>          remoteError(VIR_ERR_GNUTLS_ERROR,
>>                      _("unable to initialize TLS client: %s"),
>>                      gnutls_strerror (err));
>> -        return NULL;
>> +        goto cleanup;
>
> This is the one place where session is still undefined, because init
> failed.  Therefore, it is still safe to return NULL at this point rather
> than jumping to cleanup.
>
>>
>> +    success = true;
>> +
>> +cleanup:
>> +    if (!success) {
>> +        gnutls_deinit(session);
>
> If you make the above two changes, then all subsequent locations that
> goto cleanup will now be guaranteed that session was properly
> initialized, and we no longer have to worry about calling
> gnutls_deinit(<uninitialized>) and whether the cleanup function is
> free-like.

Okay, not relying on gnutls_deinit being free-like is a good idea.

I applied you suggested changes and pushed the result.

Matthias




More information about the libvir-list mailing list