hw/intc/arm_gicv3_dist: Rename 64-bit accessors with 'q' suffix hw/intc/arm_gicv3: Replace mis-used MEMTX_* constants by booleans hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR (CVE-2021-3750) net/colo-compare.c: Check that colo-compare is active
130 lines
4.3 KiB
Diff
130 lines
4.3 KiB
Diff
From 5fa5c68cc2dc4c2dad6272670e84767d7830eb1e Mon Sep 17 00:00:00 2001
|
|
From: Lukas Straub <lukasstraub2@web.de>
|
|
Date: Fri, 22 May 2020 15:53:55 +0800
|
|
Subject: [PATCH 4/4] net/colo-compare.c: Check that colo-compare is active
|
|
|
|
If the colo-compare object is removed before failover and a
|
|
checkpoint happens, qemu crashes because it tries to lock
|
|
the destroyed event_mtx in colo_notify_compares_event.
|
|
|
|
Fix this by checking if everything is initialized by
|
|
introducing a new variable colo_compare_active which
|
|
is protected by a new mutex colo_compare_mutex. The new mutex
|
|
also protects against concurrent access of the net_compares
|
|
list and makes sure that colo_notify_compares_event isn't
|
|
active while we destroy event_mtx and event_complete_cond.
|
|
|
|
With this it also is again possible to use colo without
|
|
colo-compare (periodic mode) and to use multiple colo-compare
|
|
for multiple network interfaces.
|
|
|
|
Signed-off-by: Lukas Straub <lukasstraub2@web.de>
|
|
Tested-by: Lukas Straub <lukasstraub2@web.de>
|
|
Reviewed-by: Zhang Chen <chen.zhang@intel.com>
|
|
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
|
|
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
|
---
|
|
net/colo-compare.c | 35 +++++++++++++++++++++++++++++------
|
|
1 file changed, 29 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/net/colo-compare.c b/net/colo-compare.c
|
|
index 7ee17f2cf8..ca07d3016b 100644
|
|
--- a/net/colo-compare.c
|
|
+++ b/net/colo-compare.c
|
|
@@ -51,6 +51,8 @@ static NotifierList colo_compare_notifiers =
|
|
/* TODO: Should be configurable */
|
|
#define REGULAR_PACKET_CHECK_MS 3000
|
|
|
|
+static QemuMutex colo_compare_mutex;
|
|
+static bool colo_compare_active;
|
|
static QemuMutex event_mtx;
|
|
static QemuCond event_complete_cond;
|
|
static int event_unhandled_count;
|
|
@@ -829,6 +831,12 @@ static void check_old_packet_regular(void *opaque)
|
|
void colo_notify_compares_event(void *opaque, int event, Error **errp)
|
|
{
|
|
CompareState *s;
|
|
+ qemu_mutex_lock(&colo_compare_mutex);
|
|
+
|
|
+ if (!colo_compare_active) {
|
|
+ qemu_mutex_unlock(&colo_compare_mutex);
|
|
+ return;
|
|
+ }
|
|
|
|
qemu_mutex_lock(&event_mtx);
|
|
QTAILQ_FOREACH(s, &net_compares, next) {
|
|
@@ -842,6 +850,7 @@ void colo_notify_compares_event(void *opaque, int event, Error **errp)
|
|
}
|
|
|
|
qemu_mutex_unlock(&event_mtx);
|
|
+ qemu_mutex_unlock(&colo_compare_mutex);
|
|
}
|
|
|
|
static void colo_compare_timer_init(CompareState *s)
|
|
@@ -1119,13 +1128,17 @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
|
|
s->vnet_hdr);
|
|
}
|
|
|
|
+ qemu_mutex_lock(&colo_compare_mutex);
|
|
+ if (!colo_compare_active) {
|
|
+ qemu_mutex_init(&event_mtx);
|
|
+ qemu_cond_init(&event_complete_cond);
|
|
+ colo_compare_active = true;
|
|
+ }
|
|
QTAILQ_INSERT_TAIL(&net_compares, s, next);
|
|
+ qemu_mutex_unlock(&colo_compare_mutex);
|
|
|
|
g_queue_init(&s->conn_list);
|
|
|
|
- qemu_mutex_init(&event_mtx);
|
|
- qemu_cond_init(&event_complete_cond);
|
|
-
|
|
s->connection_track_table = g_hash_table_new_full(connection_key_hash,
|
|
connection_key_equal,
|
|
g_free,
|
|
@@ -1208,12 +1221,19 @@ static void colo_compare_finalize(Object *obj)
|
|
|
|
qemu_bh_delete(s->event_bh);
|
|
|
|
+ qemu_mutex_lock(&colo_compare_mutex);
|
|
QTAILQ_FOREACH(tmp, &net_compares, next) {
|
|
if (tmp == s) {
|
|
QTAILQ_REMOVE(&net_compares, s, next);
|
|
break;
|
|
}
|
|
}
|
|
+ if (QTAILQ_EMPTY(&net_compares)) {
|
|
+ colo_compare_active = false;
|
|
+ qemu_mutex_destroy(&event_mtx);
|
|
+ qemu_cond_destroy(&event_complete_cond);
|
|
+ }
|
|
+ qemu_mutex_unlock(&colo_compare_mutex);
|
|
|
|
/* Release all unhandled packets after compare thead exited */
|
|
g_queue_foreach(&s->conn_list, colo_flush_packets, s);
|
|
@@ -1228,15 +1248,18 @@ static void colo_compare_finalize(Object *obj)
|
|
object_unref(OBJECT(s->iothread));
|
|
}
|
|
|
|
- qemu_mutex_destroy(&event_mtx);
|
|
- qemu_cond_destroy(&event_complete_cond);
|
|
-
|
|
g_free(s->pri_indev);
|
|
g_free(s->sec_indev);
|
|
g_free(s->outdev);
|
|
g_free(s->notify_dev);
|
|
}
|
|
|
|
+static void __attribute__((__constructor__)) colo_compare_init_globals(void)
|
|
+{
|
|
+ colo_compare_active = false;
|
|
+ qemu_mutex_init(&colo_compare_mutex);
|
|
+}
|
|
+
|
|
static const TypeInfo colo_compare_info = {
|
|
.name = TYPE_COLO_COMPARE,
|
|
.parent = TYPE_OBJECT,
|
|
--
|
|
2.27.0
|
|
|