9ae3a8
From a32c9e8da011b25ba9a056bc41c990694b730566 Mon Sep 17 00:00:00 2001
9ae3a8
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
9ae3a8
Date: Wed, 13 Dec 2017 13:38:51 +0100
9ae3a8
Subject: [PATCH 20/41] dump: Fix dump-guest-memory termination and
9ae3a8
 use-after-close
9ae3a8
MIME-Version: 1.0
9ae3a8
Content-Type: text/plain; charset=UTF-8
9ae3a8
Content-Transfer-Encoding: 8bit
9ae3a8
9ae3a8
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
9ae3a8
Message-id: <20171213133912.26176-21-marcandre.lureau@redhat.com>
9ae3a8
Patchwork-id: 78374
9ae3a8
O-Subject: [RHEL-7.5 qemu-kvm PATCH v3 20/41] dump: Fix dump-guest-memory termination and use-after-close
9ae3a8
Bugzilla: 1411490
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
From: Gonglei <arei.gonglei@huawei.com>
9ae3a8
9ae3a8
dump_iterate() dumps blocks in a loop.  Eventually, get_next_block()
9ae3a8
returns "no more".  We then call dump_completed().  But we neglect to
9ae3a8
break the loop!  Broken in commit 4c7e251a.
9ae3a8
9ae3a8
Because of that, we dump the last block again.  This attempts to write
9ae3a8
to s->fd, which fails if we're lucky.  The error makes dump_iterate()
9ae3a8
return failure.  It's the only way it can ever return.
9ae3a8
9ae3a8
Theoretical: if we're not so lucky, something else has opened something
9ae3a8
for writing and got the same fd.  dump_iterate() then keeps looping,
9ae3a8
messing up the something else's output, until a write fails, or the
9ae3a8
process mercifully terminates.
9ae3a8
9ae3a8
The obvious fix is to restore the return lost in commit 4c7e251a.  But
9ae3a8
the root cause of the bug is needlessly opaque loop control.  Replace it
9ae3a8
by a clean do ... while loop.
9ae3a8
9ae3a8
This makes the badly chosen return values of get_next_block() more
9ae3a8
visible.  Cleaning that up is outside the scope of this bug fix.
9ae3a8
9ae3a8
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
9ae3a8
Signed-off-by: Markus Armbruster <armbru@redhat.com>
9ae3a8
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
9ae3a8
9ae3a8
(cherry picked from commit 08a655be71d0a130a5d9bf7816d096ec31c4f055)
9ae3a8
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 dump.c | 11 ++++-------
9ae3a8
 1 file changed, 4 insertions(+), 7 deletions(-)
9ae3a8
9ae3a8
diff --git a/dump.c b/dump.c
9ae3a8
index 099346a..83b6d20 100644
9ae3a8
--- a/dump.c
9ae3a8
+++ b/dump.c
9ae3a8
@@ -610,10 +610,9 @@ static void dump_iterate(DumpState *s, Error **errp)
9ae3a8
 {
9ae3a8
     GuestPhysBlock *block;
9ae3a8
     int64_t size;
9ae3a8
-    int ret;
9ae3a8
     Error *local_err = NULL;
9ae3a8
 
9ae3a8
-    while (1) {
9ae3a8
+    do {
9ae3a8
         block = s->next_block;
9ae3a8
 
9ae3a8
         size = block->target_end - block->target_start;
9ae3a8
@@ -629,11 +628,9 @@ static void dump_iterate(DumpState *s, Error **errp)
9ae3a8
             return;
9ae3a8
         }
9ae3a8
 
9ae3a8
-        ret = get_next_block(s, block);
9ae3a8
-        if (ret == 1) {
9ae3a8
-            dump_completed(s);
9ae3a8
-        }
9ae3a8
-    }
9ae3a8
+    } while (!get_next_block(s, block));
9ae3a8
+
9ae3a8
+    dump_completed(s);
9ae3a8
 }
9ae3a8
 
9ae3a8
 static void create_vmcore(DumpState *s, Error **errp)
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8