[libvirt] [PATCH 6/9] daemonStreamHandleRead: Rework to follow our coding pattern

John Ferlan jferlan at redhat.com
Wed Apr 20 13:56:51 UTC 2016



On 04/15/2016 09:51 AM, Michal Privoznik wrote:
> Usually, we have this 'if() goto cleanup;' pattern in our new
> code. It is going to be useful here too. Thing is, there was a
> memleak. If there has been an error in
> virNetServerProgramSendStreamError() or
> virNetServerProgramSendStreamData() created message was never
> freed.
> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  daemon/stream.c | 68 ++++++++++++++++++++++++++++-----------------------------
>  1 file changed, 34 insertions(+), 34 deletions(-)
> 
> diff --git a/daemon/stream.c b/daemon/stream.c
> index a2a370c..cf42a10 100644
> --- a/daemon/stream.c
> +++ b/daemon/stream.c
> @@ -709,9 +709,12 @@ static int
>  daemonStreamHandleRead(virNetServerClientPtr client,
>                         daemonClientStream *stream)
>  {
> +    virNetMessagePtr msg = NULL;
> +    virNetMessageError rerr;
>      char *buffer;
>      size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
> -    int ret;
> +    int ret = -1;
> +    int rv;
>  
>      VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
>                client, stream, stream->tx, stream->closed);
> @@ -728,50 +731,47 @@ daemonStreamHandleRead(virNetServerClientPtr client,
>      if (!stream->tx)
>          return 0;
>  
> +    memset(&rerr, 0, sizeof(rerr));
> +
>      if (VIR_ALLOC_N(buffer, bufferLen) < 0)
>          return -1;
>  
> -    ret = virStreamRecv(stream->st, buffer, bufferLen);
> -    if (ret == -2) {
> +    if (!(msg = virNetMessageNew(false)))
> +        goto cleanup;
> +
> +    rv = virStreamRecv(stream->st, buffer, bufferLen);
> +    if (rv == -2) {
>          /* Should never get this, since we're only called when we know
>           * we're readable, but hey things change... */

If for some reason rv == -2, then you later set "msg = NULL" which leaks
it (Coverity found)

I assume 'msg' gets 'eaten' by virNetServerProgramSendStreamError and
virNetServerProgramSendStreamData, so then after successful return from
either that's when the "msg = NULL;" should be done.

John

> -        ret = 0;
> -    } else if (ret < 0) {
> -        virNetMessagePtr msg;
> -        virNetMessageError rerr;
> -
> -        memset(&rerr, 0, sizeof(rerr));
> -
> -        if (!(msg = virNetMessageNew(false)))
> -            ret = -1;
> -        else
> -            ret = virNetServerProgramSendStreamError(remoteProgram,
> -                                                     client,
> -                                                     msg,
> -                                                     &rerr,
> -                                                     stream->procedure,
> -                                                     stream->serial);
> +    } else if (rv < 0) {
> +        if (virNetServerProgramSendStreamError(remoteProgram,
> +                                               client,
> +                                               msg,
> +                                               &rerr,
> +                                               stream->procedure,
> +                                               stream->serial) < 0)
> +            goto cleanup;
>      } else {
> -        virNetMessagePtr msg;
>          stream->tx = false;
> -        if (ret == 0)
> +        if (rv == 0)
>              stream->recvEOF = true;
> -        if (!(msg = virNetMessageNew(false)))
> -            ret = -1;
>  
> -        if (msg) {
> -            msg->cb = daemonStreamMessageFinished;
> -            msg->opaque = stream;
> -            stream->refs++;
> -            ret = virNetServerProgramSendStreamData(remoteProgram,
> -                                                    client,
> -                                                    msg,
> -                                                    stream->procedure,
> -                                                    stream->serial,
> -                                                    buffer, ret);
> -        }
> +        msg->cb = daemonStreamMessageFinished;
> +        msg->opaque = stream;
> +        stream->refs++;
> +        if (virNetServerProgramSendStreamData(remoteProgram,
> +                                              client,
> +                                              msg,
> +                                              stream->procedure,
> +                                              stream->serial,
> +                                              buffer, rv) < 0)
> +            goto cleanup;
>      }
>  
> +    msg = NULL;

^^^^
If (rv == -2) this is leaked.

> +    ret = 0;
> + cleanup:
>      VIR_FREE(buffer);
> +    virNetMessageFree(msg);
>      return ret;
>  }
> 




More information about the libvir-list mailing list