cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
dc1fe0
From 14582cfec72e52894f16ed5c3fb14adb2d6d8e25 Mon Sep 17 00:00:00 2001
dc1fe0
From: Rao Lei <lei.rao@intel.com>
dc1fe0
Date: Wed, 5 Jan 2022 10:08:08 +0800
dc1fe0
Subject: [PATCH 4/6] ui/vnc.c: Fixed a deadlock bug.
dc1fe0
MIME-Version: 1.0
dc1fe0
Content-Type: text/plain; charset=UTF-8
dc1fe0
Content-Transfer-Encoding: 8bit
dc1fe0
dc1fe0
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
dc1fe0
RH-MergeRequest: 75: fix vnc cut+paste crash
dc1fe0
RH-Commit: [4/4] 5321e447de974d91e9a6c0cf01f4352166ffb7ce (kraxel/centos-qemu-kvm)
dc1fe0
RH-Bugzilla: 2042820
dc1fe0
RH-Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
dc1fe0
RH-Acked-by: Daniel P. Berrangé <berrange@redhat.com>
dc1fe0
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
dc1fe0
dc1fe0
The GDB statck is as follows:
dc1fe0
(gdb) bt
dc1fe0
0  __lll_lock_wait (futex=futex@entry=0x56211df20360, private=0) at lowlevellock.c:52
dc1fe0
1  0x00007f263caf20a3 in __GI___pthread_mutex_lock (mutex=0x56211df20360) at ../nptl/pthread_mutex_lock.c:80
dc1fe0
2  0x000056211a757364 in qemu_mutex_lock_impl (mutex=0x56211df20360, file=0x56211a804857 "../ui/vnc-jobs.h", line=60)
dc1fe0
    at ../util/qemu-thread-posix.c:80
dc1fe0
3  0x000056211a0ef8c7 in vnc_lock_output (vs=0x56211df14200) at ../ui/vnc-jobs.h:60
dc1fe0
4  0x000056211a0efcb7 in vnc_clipboard_send (vs=0x56211df14200, count=1, dwords=0x7ffdf1701338) at ../ui/vnc-clipboard.c:138
dc1fe0
5  0x000056211a0f0129 in vnc_clipboard_notify (notifier=0x56211df244c8, data=0x56211dd1bbf0) at ../ui/vnc-clipboard.c:209
dc1fe0
6  0x000056211a75dde8 in notifier_list_notify (list=0x56211afa17d0 <clipboard_notifiers>, data=0x56211dd1bbf0) at ../util/notify.c:39
dc1fe0
7  0x000056211a0bf0e6 in qemu_clipboard_update (info=0x56211dd1bbf0) at ../ui/clipboard.c:50
dc1fe0
8  0x000056211a0bf05d in qemu_clipboard_peer_release (peer=0x56211df244c0, selection=QEMU_CLIPBOARD_SELECTION_CLIPBOARD)
dc1fe0
    at ../ui/clipboard.c:41
dc1fe0
9  0x000056211a0bef9b in qemu_clipboard_peer_unregister (peer=0x56211df244c0) at ../ui/clipboard.c:19
dc1fe0
10 0x000056211a0d45f3 in vnc_disconnect_finish (vs=0x56211df14200) at ../ui/vnc.c:1358
dc1fe0
11 0x000056211a0d4c9d in vnc_client_read (vs=0x56211df14200) at ../ui/vnc.c:1611
dc1fe0
12 0x000056211a0d4df8 in vnc_client_io (ioc=0x56211ce70690, condition=G_IO_IN, opaque=0x56211df14200) at ../ui/vnc.c:1649
dc1fe0
13 0x000056211a5b976c in qio_channel_fd_source_dispatch
dc1fe0
    (source=0x56211ce50a00, callback=0x56211a0d4d71 <vnc_client_io>, user_data=0x56211df14200) at ../io/channel-watch.c:84
dc1fe0
14 0x00007f263ccede8e in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
dc1fe0
15 0x000056211a77d4a1 in glib_pollfds_poll () at ../util/main-loop.c:232
dc1fe0
16 0x000056211a77d51f in os_host_main_loop_wait (timeout=958545) at ../util/main-loop.c:255
dc1fe0
17 0x000056211a77d630 in main_loop_wait (nonblocking=0) at ../util/main-loop.c:531
dc1fe0
18 0x000056211a45bc8e in qemu_main_loop () at ../softmmu/runstate.c:726
dc1fe0
19 0x000056211a0b45fa in main (argc=69, argv=0x7ffdf1701778, envp=0x7ffdf17019a8) at ../softmmu/main.c:50
dc1fe0
dc1fe0
From the call trace, we can see it is a deadlock bug.
dc1fe0
vnc_disconnect_finish will acquire the output_mutex.
dc1fe0
But, the output_mutex will be acquired again in vnc_clipboard_send.
dc1fe0
Repeated locking will cause deadlock. So, I move
dc1fe0
qemu_clipboard_peer_unregister() behind vnc_unlock_output();
dc1fe0
dc1fe0
Fixes: 0bf41cab93e ("ui/vnc: clipboard support")
dc1fe0
Signed-off-by: Lei Rao <lei.rao@intel.com>
dc1fe0
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
dc1fe0
Message-Id: <20220105020808.597325-1-lei.rao@intel.com>
dc1fe0
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
dc1fe0
(cherry picked from commit 1dbbe6f172810026c51dc84ed927a3cc23017949)
dc1fe0
---
dc1fe0
 ui/vnc.c | 4 ++--
dc1fe0
 1 file changed, 2 insertions(+), 2 deletions(-)
dc1fe0
dc1fe0
diff --git a/ui/vnc.c b/ui/vnc.c
dc1fe0
index af02522e84..b253e85c65 100644
dc1fe0
--- a/ui/vnc.c
dc1fe0
+++ b/ui/vnc.c
dc1fe0
@@ -1354,12 +1354,12 @@ void vnc_disconnect_finish(VncState *vs)
dc1fe0
         /* last client gone */
dc1fe0
         vnc_update_server_surface(vs->vd);
dc1fe0
     }
dc1fe0
+    vnc_unlock_output(vs);
dc1fe0
+
dc1fe0
     if (vs->cbpeer.update.notify) {
dc1fe0
         qemu_clipboard_peer_unregister(&vs->cbpeer);
dc1fe0
     }
dc1fe0
 
dc1fe0
-    vnc_unlock_output(vs);
dc1fe0
-
dc1fe0
     qemu_mutex_destroy(&vs->output_mutex);
dc1fe0
     if (vs->bh != NULL) {
dc1fe0
         qemu_bh_delete(vs->bh);
dc1fe0
-- 
dc1fe0
2.27.0
dc1fe0