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