File kvm-qemu-preXX-vnc-Fix-stack-corruption-and-other-bitmap-.patch of Package kvm.853

From 23bfe28fffd6fff12a39c1ff7274b0dfdecbfa38 Mon Sep 17 00:00:00 2001
From: Stefan Weil <weil@mail.berlios.de>
Date: Thu, 3 Mar 2011 21:37:55 +0100
Subject: [PATCH] vnc: Fix stack corruption and other bitmap related bugs

Commit bc2429b9174ac2d3c56b7fd35884b0d89ec7fb02 introduced
a severe bug (stack corruption).

bitmap_clear was called with a wrong argument
which caused out-of-bound writes to the local variable width_mask.

This bug was detected with QEMU running on windows.
It also occurs with wine:

Index: qemu-kvm-0.14.0/ui/vnc.c
===================================================================
--- qemu-kvm-0.14.0.orig/ui/vnc.c
+++ qemu-kvm-0.14.0/ui/vnc.c
@@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(Vn
     uint8_t *guest_row;
     uint8_t *server_row;
     int cmp_bytes;
-    unsigned long width_mask[VNC_DIRTY_WORDS];
     VncState *vs;
     int has_dirty = 0;
 
@@ -2397,14 +2396,11 @@ static int vnc_refresh_server_surface(Vn
      * Check and copy modified bits from guest to server surface.
      * Update server dirty map.
      */
-    bitmap_set(width_mask, 0, (ds_get_width(vd->ds) / 16));
-    bitmap_clear(width_mask, (ds_get_width(vd->ds) / 16),
-                 VNC_DIRTY_WORDS * BITS_PER_LONG);
     cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
     guest_row  = vd->guest.ds->data;
     server_row = vd->server->data;
     for (y = 0; y < vd->guest.ds->height; y++) {
-        if (bitmap_intersects(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
+        if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) {
             int x;
             uint8_t *guest_ptr;
             uint8_t *server_ptr;
Index: qemu-kvm-0.14.0/ui/vnc.h
===================================================================
--- qemu-kvm-0.14.0.orig/ui/vnc.h
+++ qemu-kvm-0.14.0/ui/vnc.h
@@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState
                                 void *last_fg,
                                 int *has_bg, int *has_fg);
 
+/* VNC_MAX_WIDTH must be a multiple of 16. */
 #define VNC_MAX_WIDTH 2560
 #define VNC_MAX_HEIGHT 2048
-#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * BITS_PER_LONG))
+
+/* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
+#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16)
 
 #define VNC_STAT_RECT  64
 #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
@@ -114,7 +117,7 @@ typedef struct VncRectStat VncRectStat;
 struct VncSurface
 {
     struct timeval last_freq_check;
-    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
+    DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
     VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
     DisplaySurface *ds;
 };
@@ -233,7 +236,7 @@ struct VncState
     int csock;
 
     DisplayState *ds;
-    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
+    DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
     uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
                            * vnc-jobs-async.c */