[fedora-virt-maint] rpms/qemu/F-11 qemu-vnc-segfault.patch, NONE, 1.1.2.1 qemu.spec, 1.95, 1.95.2.1

Mark McLoughlin markmc at fedoraproject.org
Fri May 22 15:19:59 UTC 2009


Author: markmc

Update of /cvs/pkgs/rpms/qemu/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv14949

Modified Files:
      Tag: private-markmc-bz501131
	qemu.spec 
Added Files:
      Tag: private-markmc-bz501131
	qemu-vnc-segfault.patch 
Log Message:
* Fri May 22 2009 Mark McLoughlin <markmc at redhat.com> - 2:0.10.4-5.1
- Try out a hacky fix for vnc segfault (bug #501131)


qemu-vnc-segfault.patch:

--- NEW FILE qemu-vnc-segfault.patch ---
diff -up qemu-kvm-0.10.4/vnc-auth-sasl.c.segfault qemu-kvm-0.10.4/vnc-auth-sasl.c
--- qemu-kvm-0.10.4/vnc-auth-sasl.c.segfault	2009-05-22 15:41:13.000000000 +0100
+++ qemu-kvm-0.10.4/vnc-auth-sasl.c	2009-05-22 15:41:38.000000000 +0100
@@ -279,8 +279,9 @@ static int protocol_client_auth_sasl_ste
     vnc_write_u32(vs, 1); /* Reject auth */
     vnc_write_u32(vs, sizeof("Authentication failed"));
     vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
-    vnc_flush(vs);
-    vnc_client_error(vs);
+    if (vnc_flush(vs)) {
+        vnc_client_error(vs);
+    }
     return -1;
 
  authabort:
@@ -401,8 +402,9 @@ static int protocol_client_auth_sasl_sta
     vnc_write_u32(vs, 1); /* Reject auth */
     vnc_write_u32(vs, sizeof("Authentication failed"));
     vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
-    vnc_flush(vs);
-    vnc_client_error(vs);
+    if (vnc_flush(vs)) {
+        vnc_client_error(vs);
+    }
     return -1;
 
  authabort:
@@ -621,7 +623,8 @@ void start_auth_sasl(VncState *vs)
     mechlistlen = strlen(mechlist);
     vnc_write_u32(vs, mechlistlen);
     vnc_write(vs, mechlist, mechlistlen);
-    vnc_flush(vs);
+    if (!vnc_flush(vs))
+        return;
 
     VNC_DEBUG("Wait for client mechname length\n");
     vnc_read_when(vs, protocol_client_auth_sasl_mechname_len, 4);
diff -up qemu-kvm-0.10.4/vnc-auth-vencrypt.c.segfault qemu-kvm-0.10.4/vnc-auth-vencrypt.c
diff -up qemu-kvm-0.10.4/vnc.c.segfault qemu-kvm-0.10.4/vnc.c
--- qemu-kvm-0.10.4/vnc.c.segfault	2009-05-22 15:41:13.000000000 +0100
+++ qemu-kvm-0.10.4/vnc.c	2009-05-22 15:50:29.000000000 +0100
@@ -213,9 +213,9 @@ static inline uint32_t vnc_has_feature(V
    3) resolutions > 1024
 */
 
-static void vnc_update_client(void *opaque);
+static int vnc_update_client(VncState *vs);
 
-static void vnc_colordepth(VncState *vs);
+static int vnc_colordepth(VncState *vs);
 
 static inline void vnc_set_bit(uint32_t *d, int k)
 {
@@ -335,7 +335,7 @@ void buffer_append(Buffer *buffer, const
     buffer->offset += len;
 }
 
-static void vnc_resize(VncState *vs)
+static int vnc_resize(VncState *vs)
 {
     DisplayState *ds = vs->ds;
 
@@ -350,7 +350,9 @@ static void vnc_resize(VncState *vs)
 
     if (ds_get_bytes_per_pixel(ds) != vs->serverds.pf.bytes_per_pixel)
         console_color_init(ds);
-    vnc_colordepth(vs);
+    if (!vnc_colordepth(vs)) {
+        return 0;
+    }
     size_changed = ds_get_width(ds) != vs->serverds.width ||
                    ds_get_height(ds) != vs->serverds.height;
     vs->serverds = *(ds->surface);
@@ -361,21 +363,29 @@ static void vnc_resize(VncState *vs)
             vnc_write_u16(vs, 1); /* number of rects */
             vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds),
                                    VNC_ENCODING_DESKTOPRESIZE);
-            vnc_flush(vs);
+            if (!vnc_flush(vs)) {
+                return 0;
+            }
         }
     }
 
     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
     memset(vs->old_data, 42, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
+
+    return 1;
 }
 
 static void vnc_dpy_resize(DisplayState *ds)
 {
     VncDisplay *vd = ds->opaque;
     VncState *vs = vd->clients;
+
     while (vs != NULL) {
+        VncState *next = vs->next;
+
         vnc_resize(vs);
-        vs = vs->next;
+
+        vs = next;
     }
 }
 
@@ -646,7 +656,9 @@ static void send_framebuffer_update(VncS
 
 static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
 {
-    vnc_update_client(vs);
+    if (!vnc_update_client(vs)) {
+        return;
+    }
 
     vnc_write_u8(vs, 0);  /* msg id */
     vnc_write_u8(vs, 0);
@@ -661,12 +673,16 @@ static void vnc_dpy_copy(DisplayState *d
 {
     VncDisplay *vd = ds->opaque;
     VncState *vs = vd->clients;
+
     while (vs != NULL) {
+        VncState *next = vs->next;
+
         if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT))
             vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
         else /* TODO */
             vnc_update(vs, dst_x, dst_y, w, h);
-        vs = vs->next;
+
+        vs = next;
     }
 }
 
@@ -685,9 +701,8 @@ static int find_dirty_height(VncState *v
     return h;
 }
 
-static void vnc_update_client(void *opaque)
+static int vnc_update_client(VncState *vs)
 {
-    VncState *vs = opaque;
     if (vs->need_update && vs->csock != -1) {
 	int y;
 	uint8_t *row;
@@ -734,7 +749,7 @@ static void vnc_update_client(void *opaq
 
 	if (!has_dirty && !vs->audio_cap) {
 	    qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
-	    return;
+	    return 1;
 	}
 
 	/* Count rectangles */
@@ -770,7 +785,9 @@ static void vnc_update_client(void *opaq
 	}
 	vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
 	vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-	vnc_flush(vs);
+	if (!vnc_flush(vs)) {
+            return 1;
+        }
 
     }
 
@@ -778,6 +795,14 @@ static void vnc_update_client(void *opaq
         qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock) + VNC_REFRESH_INTERVAL);
     }
 
+    return 1;
+}
+
+static void vnc_update_client_timer(void *opaque)
+{
+    VncState *vs = opaque;
+
+    vnc_update_client(vs);
 }
 
 /* audio */
@@ -989,10 +1014,13 @@ static long vnc_client_write_plain(VncSt
  * the client socket. Will delegate actual work according to whether
  * SASL SSF layers are enabled (thus requiring encryption calls)
  */
-void vnc_client_write(void *opaque)
+int vnc_flush(VncState *vs)
 {
     long ret;
-    VncState *vs = opaque;
+
+    if (!vs->output.offset) {
+        return 1;
+    }
 
 #ifdef CONFIG_VNC_SASL
     if (vs->sasl.conn &&
@@ -1002,6 +1030,15 @@ void vnc_client_write(void *opaque)
     else
 #endif /* CONFIG_VNC_SASL */
         ret = vnc_client_write_plain(vs);
+
+    return !!ret;
+}
+
+void vnc_client_write(void *opaque)
+{
+    VncState *vs = opaque;
+
+    vnc_flush(vs);
 }
 
 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
@@ -1148,12 +1185,6 @@ void vnc_write_u8(VncState *vs, uint8_t 
     vnc_write(vs, (char *)&value, 1);
 }
 
-void vnc_flush(VncState *vs)
-{
-    if (vs->output.offset)
-	vnc_client_write(vs);
-}
-
 uint8_t read_u8(uint8_t *data, size_t offset)
 {
     return data[offset];
@@ -1189,7 +1220,9 @@ static void check_pointer_type_change(Vn
 	vnc_framebuffer_update(vs, absolute, 0,
 			       ds_get_width(vs->ds), ds_get_height(vs->ds),
                                VNC_ENCODING_POINTER_TYPE_CHANGE);
-	vnc_flush(vs);
+	if (!vnc_flush(vs)) {
+            return;
+        }
     }
     vs->absolute = absolute;
 }
@@ -1591,7 +1624,7 @@ static void vnc_dpy_setdata(DisplayState
     /* We don't have to do anything */
 }
 
-static void vnc_colordepth(VncState *vs)
+static int vnc_colordepth(VncState *vs)
 {
     if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
         /* Sending a WMVi message to notify the client*/
@@ -1601,9 +1634,10 @@ static void vnc_colordepth(VncState *vs)
         vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), 
                                ds_get_height(vs->ds), VNC_ENCODING_WMVi);
         pixel_format_message(vs);
-        vnc_flush(vs);
+        return vnc_flush(vs);
     } else {
         set_pixel_conversion(vs);
+        return 1;
     }
 }
 
@@ -1760,7 +1794,9 @@ static int protocol_client_init(VncState
 
     vnc_write_u32(vs, size);
     vnc_write(vs, buf, size);
-    vnc_flush(vs);
+    if (!vnc_flush(vs)) {
+        return 0; /* FIXME */
+    }
 
     vnc_read_when(vs, protocol_client_msg, 1);
 
@@ -1796,8 +1832,9 @@ static int protocol_client_auth_vnc(VncS
 	    vnc_write_u32(vs, sizeof(err));
 	    vnc_write(vs, err, sizeof(err));
 	}
-	vnc_flush(vs);
-	vnc_client_error(vs);
+	if (vnc_flush(vs)) {
+            vnc_client_error(vs);
+        }
 	return 0;
     }
 
@@ -1820,14 +1857,15 @@ static int protocol_client_auth_vnc(VncS
 	    vnc_write_u32(vs, sizeof(err));
 	    vnc_write(vs, err, sizeof(err));
 	}
-	vnc_flush(vs);
-	vnc_client_error(vs);
+	if (vnc_flush(vs)) {
+            vnc_client_error(vs);
+        }
     } else {
 	VNC_DEBUG("Accepting VNC challenge response\n");
 	vnc_write_u32(vs, 0); /* Accept auth */
-	vnc_flush(vs);
-
-        start_client_init(vs);
+	if (vnc_flush(vs)) {
+            start_client_init(vs);
+        }
     }
     return 0;
 }
@@ -1837,7 +1875,9 @@ void start_auth_vnc(VncState *vs)
     make_challenge(vs);
     /* Send client a 'random' challenge */
     vnc_write(vs, vs->challenge, sizeof(vs->challenge));
-    vnc_flush(vs);
+    if (!vnc_flush(vs)) {
+        return;
+    }
 
     vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
 }
@@ -1863,7 +1903,9 @@ static int protocol_client_auth(VncState
            VNC_DEBUG("Accept auth none\n");
            if (vs->minor >= 8) {
                vnc_write_u32(vs, 0); /* Accept auth completion */
-               vnc_flush(vs);
+               if (!vnc_flush(vs)) {
+                   return 0; /* FIXME */
+               }
            }
            start_client_init(vs);
            break;
@@ -1922,8 +1964,9 @@ static int protocol_version(VncState *vs
 	 vs->minor != 8)) {
 	VNC_DEBUG("Unsupported client version\n");
 	vnc_write_u32(vs, VNC_AUTH_INVALID);
-	vnc_flush(vs);
-	vnc_client_error(vs);
+	if (vnc_flush(vs)) {
+            vnc_client_error(vs);
+        }
 	return 0;
     }
     /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
@@ -1936,18 +1979,21 @@ static int protocol_version(VncState *vs
 	if (vs->vd->auth == VNC_AUTH_NONE) {
             VNC_DEBUG("Tell client auth none\n");
             vnc_write_u32(vs, vs->vd->auth);
-            vnc_flush(vs);
-	    start_client_init(vs);
+            if (vnc_flush(vs)) {
+                start_client_init(vs);
+            }
        } else if (vs->vd->auth == VNC_AUTH_VNC) {
             VNC_DEBUG("Tell client VNC auth\n");
             vnc_write_u32(vs, vs->vd->auth);
-            vnc_flush(vs);
-            start_auth_vnc(vs);
+            if (vnc_flush(vs)) {
+                start_auth_vnc(vs);
+            }
        } else {
             VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth);
             vnc_write_u32(vs, VNC_AUTH_INVALID);
-            vnc_flush(vs);
-            vnc_client_error(vs);
+            if (vnc_flush(vs)) {
+                vnc_client_error(vs);
+            }
        }
     } else {
 	VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth);
@@ -1972,7 +2018,7 @@ static void vnc_connect(VncDisplay *vd, 
 
     vs->vd = vd;
     vs->ds = vd->ds;
-    vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
+    vs->timer = qemu_new_timer(rt_clock, vnc_update_client_timer, vs);
     vs->last_x = -1;
     vs->last_y = -1;
 
@@ -1981,13 +2027,19 @@ static void vnc_connect(VncDisplay *vd, 
     vs->as.fmt = AUD_FMT_S16;
     vs->as.endianness = 0;
 
-    vnc_resize(vs);
+    if (!vnc_resize(vs)) {
+        return;
+    }
     vnc_write(vs, "RFB 003.008\n", 12);
-    vnc_flush(vs);
+    if (!vnc_flush(vs)) {
+        return;
+    }
     vnc_read_when(vs, protocol_version, 12);
     memset(vs->old_data, 0, ds_get_linesize(vs->ds) * ds_get_height(vs->ds));
     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
-    vnc_update_client(vs);
+    if (!vnc_update_client(vs)) {
+        return;
+    }
     reset_keys(vs);
 
     vs->next = vd->clients;
diff -up qemu-kvm-0.10.4/vnc.h.segfault qemu-kvm-0.10.4/vnc.h
--- qemu-kvm-0.10.4/vnc.h.segfault	2009-05-22 15:41:13.000000000 +0100
+++ qemu-kvm-0.10.4/vnc.h	2009-05-22 15:41:38.000000000 +0100
@@ -276,7 +276,7 @@ void vnc_write_u32(VncState *vs, uint32_
 void vnc_write_s32(VncState *vs, int32_t value);
 void vnc_write_u16(VncState *vs, uint16_t value);
 void vnc_write_u8(VncState *vs, uint8_t value);
-void vnc_flush(VncState *vs);
+int vnc_flush(VncState *vs);
 void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting);
 
 


Index: qemu.spec
===================================================================
RCS file: /cvs/pkgs/rpms/qemu/F-11/qemu.spec,v
retrieving revision 1.95
retrieving revision 1.95.2.1
diff -u -p -r1.95 -r1.95.2.1
--- qemu.spec	19 May 2009 03:00:56 -0000	1.95
+++ qemu.spec	22 May 2009 15:19:29 -0000	1.95.2.1
@@ -1,7 +1,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 0.10.4
-Release: 5%{?dist}
+Release: 5.1%{?dist}
 # Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -37,6 +37,8 @@ Patch21: qemu-make-x86-cpuid-feature-nam
 Patch22: qemu-fix-x86-feature-modifications-for-features-that-set.patch
 Patch23: qemu-trim-cpu-features-not-supported-by-kvm.patch
 
+Patch24: qemu-vnc-segfault.patch
+
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
@@ -241,6 +243,8 @@ such as kvmtrace and kvm_stat.
 #%patch22 -p1
 #%patch23 -p1
 
+%patch24 -p1 -b .segfault
+
 %build
 # systems like rhel build system does not have a recent enough linker so
 # --build-id works. this option is used fedora 8 onwards for giving info
@@ -482,6 +486,9 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Fri May 22 2009 Mark McLoughlin <markmc at redhat.com> - 2:0.10.4-5.1
+- Try out a hacky fix for vnc segfault (bug #501131)
+
 * Mon May 18 2009 Glauber Costa <glommer at redhat.com> - 2:0.10.4-5
 - Backport cpuid trimming from upstream (#499596)
 




More information about the Fedora-virt-maint mailing list