summary refs log tree commit diff stats
path: root/ui/vnc.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2018-03-08 17:18:03 +0100
committerGerd Hoffmann <kraxel@redhat.com>2018-03-12 09:00:59 +0100
commit2e5567c903ad05d312de0c3188cb2d3b856fa4c4 (patch)
tree1b6a308596eb1d796a58fcae729f3ac8f58c45b0 /ui/vnc.c
parentf1bd313264925dfb229a2152eb3f60fe55746b83 (diff)
downloadfocaccia-qemu-2e5567c903ad05d312de0c3188cb2d3b856fa4c4.tar.gz
focaccia-qemu-2e5567c903ad05d312de0c3188cb2d3b856fa4c4.zip
vnc: deal with surface NULL pointers
Secondary displays in multihead setups are allowed to have a NULL
DisplaySurface.  Typically user interfaces handle this by hiding the
window which shows the display in question.

This isn't an option for vnc though because it simply hasn't a concept
of windows or outputs.  So handle the situation by showing a placeholder
DisplaySurface instead.  Also check in console_select whenever a surface
is preset in the first place before requesting an update.

This fixes a segfault which can be triggered by switching to an unused
display (via vtrl-alt-<nr>) in a multihead setup, for example using
-device virtio-vga,max_outputs=2.

Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Message-id: 20180308161803.6152-1-kraxel@redhat.com
Diffstat (limited to 'ui/vnc.c')
-rw-r--r--ui/vnc.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/ui/vnc.c b/ui/vnc.c
index 13c28cabb0..e164eb798c 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -746,9 +746,19 @@ static void vnc_update_server_surface(VncDisplay *vd)
 static void vnc_dpy_switch(DisplayChangeListener *dcl,
                            DisplaySurface *surface)
 {
+    static const char placeholder_msg[] =
+        "Display output is not active.";
+    static DisplaySurface *placeholder;
     VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
     VncState *vs;
 
+    if (surface == NULL) {
+        if (placeholder == NULL) {
+            placeholder = qemu_create_message_surface(640, 480, placeholder_msg);
+        }
+        surface = placeholder;
+    }
+
     vnc_abort_display_jobs(vd);
     vd->ds = surface;