diff mbox series

migration/rdma: Fix qemu_rdma_cleanup null check

Message ID 20190214185351.5927-1-dgilbert@redhat.com (mailing list archive)
State New, archived
Headers show
Series migration/rdma: Fix qemu_rdma_cleanup null check | expand

Commit Message

Dr. David Alan Gilbert Feb. 14, 2019, 6:53 p.m. UTC
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

If the migration fails before the channel is open (e.g. a bad
address) we end up in the cleanup with rdma->channel==NULL.

Spotted by Coverity: CID 1398634
Fixes: fbbaacab2758cb3f32a0
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 migration/rdma.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Peter Xu Feb. 15, 2019, 1:55 a.m. UTC | #1
On Thu, Feb 14, 2019 at 06:53:51PM +0000, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> If the migration fails before the channel is open (e.g. a bad
> address) we end up in the cleanup with rdma->channel==NULL.
> 
> Spotted by Coverity: CID 1398634
> Fixes: fbbaacab2758cb3f32a0
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
>  migration/rdma.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 54a3c11540..9fa3b176eb 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -2321,7 +2321,9 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
>          rdma->connected = false;
>      }
>  
> -    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    if (rdma->channel) {
> +        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    }

IIUC there's no strict ordering constraint on resetting the fd
handler, then how about simply moving this line into the below "if
(rdma->channel)" altogether?

Regards,
Dr. David Alan Gilbert Feb. 15, 2019, 11 a.m. UTC | #2
* Peter Xu (peterx@redhat.com) wrote:
> On Thu, Feb 14, 2019 at 06:53:51PM +0000, Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > 
> > If the migration fails before the channel is open (e.g. a bad
> > address) we end up in the cleanup with rdma->channel==NULL.
> > 
> > Spotted by Coverity: CID 1398634
> > Fixes: fbbaacab2758cb3f32a0
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > ---
> >  migration/rdma.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/migration/rdma.c b/migration/rdma.c
> > index 54a3c11540..9fa3b176eb 100644
> > --- a/migration/rdma.c
> > +++ b/migration/rdma.c
> > @@ -2321,7 +2321,9 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
> >          rdma->connected = false;
> >      }
> >  
> > -    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> > +    if (rdma->channel) {
> > +        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> > +    }
> 
> IIUC there's no strict ordering constraint on resetting the fd
> handler, then how about simply moving this line into the below "if
> (rdma->channel)" altogether?

The logic around the closing of the return path makes that check later a
bit messy; rdma->channel can get set to Null before the other check.

Dave

> Regards,
> 
> -- 
> Peter Xu
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Philippe Mathieu-Daudé Feb. 15, 2019, 11:30 a.m. UTC | #3
On 2/14/19 7:53 PM, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> If the migration fails before the channel is open (e.g. a bad
> address) we end up in the cleanup with rdma->channel==NULL.
> 
> Spotted by Coverity: CID 1398634
> Fixes: fbbaacab2758cb3f32a0
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
>  migration/rdma.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 54a3c11540..9fa3b176eb 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -2321,7 +2321,9 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
>          rdma->connected = false;
>      }
>  
> -    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    if (rdma->channel) {
> +        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    }
>      g_free(rdma->dest_blocks);
>      rdma->dest_blocks = NULL;
>  
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Peter Xu Feb. 15, 2019, 12:01 p.m. UTC | #4
On Fri, Feb 15, 2019 at 11:00:56AM +0000, Dr. David Alan Gilbert wrote:
> * Peter Xu (peterx@redhat.com) wrote:
> > On Thu, Feb 14, 2019 at 06:53:51PM +0000, Dr. David Alan Gilbert (git) wrote:
> > > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > > 
> > > If the migration fails before the channel is open (e.g. a bad
> > > address) we end up in the cleanup with rdma->channel==NULL.
> > > 
> > > Spotted by Coverity: CID 1398634
> > > Fixes: fbbaacab2758cb3f32a0
> > > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> > > ---
> > >  migration/rdma.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/migration/rdma.c b/migration/rdma.c
> > > index 54a3c11540..9fa3b176eb 100644
> > > --- a/migration/rdma.c
> > > +++ b/migration/rdma.c
> > > @@ -2321,7 +2321,9 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
> > >          rdma->connected = false;
> > >      }
> > >  
> > > -    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> > > +    if (rdma->channel) {
> > > +        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> > > +    }
> > 
> > IIUC there's no strict ordering constraint on resetting the fd
> > handler, then how about simply moving this line into the below "if
> > (rdma->channel)" altogether?
> 
> The logic around the closing of the return path makes that check later a
> bit messy; rdma->channel can get set to Null before the other check.

Ah I see, it's the mess by sharing listen_id and channel on
destination side...  Maybe we can clean them up along the way?  I gave
it a shot:

    if (rdma->listen_id && rdma->is_return_path) {
        /*
         * The return path on the destination side, both listen_id and
         * channel are shared with the other context so we skip
         * freeing those but simply clear the pointers no matter what.
         * The main context will help us to clean these.
         */
        rdma->listen_id = NULL;
        rdma->channel = NULL;
    } else {
        /*
         * Either the source side, or the main context of the
         * destination side: we are responsible for listen_id/channel
         */
        if (rdma->listen_id) {
            rdma_destroy_id(rdma->listen_id);
            rdma->listen_id = NULL;
        }
        if (rdma->channel) {
            qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
            rdma_destroy_event_channel(rdma->channel);
            rdma->channel = NULL;
        }
    }

I slightly prefer to clean it up (if someone is still going to
maintain the RDMA code... :), but either way is fine to me.

No matter what you prefer:

Reviewed-by: Peter Xu <peterx@redhat.com>

Thanks,
Dr. David Alan Gilbert March 5, 2019, 1:23 p.m. UTC | #5
* Dr. David Alan Gilbert (git) (dgilbert@redhat.com) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> If the migration fails before the channel is open (e.g. a bad
> address) we end up in the cleanup with rdma->channel==NULL.
> 
> Spotted by Coverity: CID 1398634
> Fixes: fbbaacab2758cb3f32a0
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Queued

> ---
>  migration/rdma.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 54a3c11540..9fa3b176eb 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -2321,7 +2321,9 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
>          rdma->connected = false;
>      }
>  
> -    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    if (rdma->channel) {
> +        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
> +    }
>      g_free(rdma->dest_blocks);
>      rdma->dest_blocks = NULL;
>  
> -- 
> 2.20.1
> 
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox series

Patch

diff --git a/migration/rdma.c b/migration/rdma.c
index 54a3c11540..9fa3b176eb 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -2321,7 +2321,9 @@  static void qemu_rdma_cleanup(RDMAContext *rdma)
         rdma->connected = false;
     }
 
-    qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
+    if (rdma->channel) {
+        qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL);
+    }
     g_free(rdma->dest_blocks);
     rdma->dest_blocks = NULL;