|
|
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 |
|