All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] vnc: Fix heap corruption
@ 2011-02-28 21:34 Stefan Weil
  2011-03-01  1:34 ` Wen Congyang
  2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Weil @ 2011-02-28 21:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Corentin Chary, Anthony Liguori

Commit bc2429b9174ac2d3c56b7fd35884b0d89ec7fb02 introduced
a severe bug (heap corruption).

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

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

*** stack smashing detected ***:  terminated
wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...

The bug is not windows specific!

Cc: Corentin Chary <corentincj@iksaif.net>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 ui/vnc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index af55156..89f71da 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2401,7 +2401,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
      */
     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);
+                 (VNC_MAX_WIDTH - ds_get_width(vd->ds)) / 16);
     cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
     guest_row  = vd->guest.ds->data;
     server_row = vd->server->data;
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] vnc: Fix heap corruption
  2011-02-28 21:34 [Qemu-devel] [PATCH] vnc: Fix heap corruption Stefan Weil
@ 2011-03-01  1:34 ` Wen Congyang
  2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
  1 sibling, 0 replies; 9+ messages in thread
From: Wen Congyang @ 2011-03-01  1:34 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Corentin Chary, Anthony Liguori, qemu-devel

At 03/01/2011 05:34 AM, Stefan Weil Write:
> Commit bc2429b9174ac2d3c56b7fd35884b0d89ec7fb02 introduced
> a severe bug (heap corruption).
> 
> bitmap_clear was called with a wrong argument
> which caused out-of-bound writes to width_mask.
> 
> This bug was detected with QEMU running on windows.
> It also occurs with wine:
> 
> *** stack smashing detected ***:  terminated
> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...
> 
> The bug is not windows specific!
> 
> Cc: Corentin Chary <corentincj@iksaif.net>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Stefan Weil <weil@mail.berlios.de>
> ---
>  ui/vnc.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/ui/vnc.c b/ui/vnc.c
> index af55156..89f71da 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2401,7 +2401,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>       */
>      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);
> +                 (VNC_MAX_WIDTH - ds_get_width(vd->ds)) / 16);

The third argument of bitmap_clear() is number of bits to be cleared, but we pass
the end bits to be cleared to bitmap_clear().

I think we can fix this bug like this(I can not reproduce this bug, so I do not
know whether it can fix this bug):

diff --git a/ui/vnc.c b/ui/vnc.c
index fff34af..6d54661 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2404,7 +2404,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
      */
     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);
+                 VNC_DIRTY_WORDS * BITS_PER_LONG - (ds_get_width(vd->ds) / 16));
     cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
     guest_row  = vd->guest.ds->data;
     server_row = vd->server->data;

Thanks
Wen Congyang

>      cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
>      guest_row  = vd->guest.ds->data;
>      server_row = vd->server->data;

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-02-28 21:34 [Qemu-devel] [PATCH] vnc: Fix heap corruption Stefan Weil
  2011-03-01  1:34 ` Wen Congyang
@ 2011-03-03 20:37 ` Stefan Weil
  2011-03-03 20:49   ` [Qemu-devel] " Stefan Weil
                     ` (2 more replies)
  1 sibling, 3 replies; 9+ messages in thread
From: Stefan Weil @ 2011-03-03 20:37 UTC (permalink / raw)
  To: qemu-devel; +Cc: Corentin Chary, Anthony Liguori, Gerhard Wiesinger

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:

*** stack smashing detected ***:  terminated
wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...

The bug is not windows specific!

Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
and width_mask were removed, and bitmap_intersect() was replaced by
!bitmap_empty(). The new operation is much shorter and equivalent to
the old operations.

The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
VNC_DIRTY_WORDS was too small.

Fix both declarations by using the macro which is designed for this
purpose.

Cc: Corentin Chary <corentincj@iksaif.net>
Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Gerhard Wiesinger <lists@wiesinger.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 ui/vnc.c |    6 +-----
 ui/vnc.h |    9 ++++++---
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 610f884..34dc0cd 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
     uint8_t *guest_row;
     uint8_t *server_row;
     int cmp_bytes;
-    unsigned long width_mask[VNC_DIRTY_WORDS];
     VncState *vs;
     int has_dirty = 0;
 
@@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
      * 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;
diff --git a/ui/vnc.h b/ui/vnc.h
index 8a1e7b9..f10c5dc 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
                                 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;
 };
@@ -234,7 +237,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 */
 
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
@ 2011-03-03 20:49   ` Stefan Weil
  2011-03-04  9:02   ` Corentin Chary
  2011-03-10 23:21   ` [Qemu-devel] " Anthony Liguori
  2 siblings, 0 replies; 9+ messages in thread
From: Stefan Weil @ 2011-03-03 20:49 UTC (permalink / raw)
  To: QEMU Developers; +Cc: Corentin Chary, Gerhard Wiesinger, Anthony Liguori

Am 03.03.2011 21:37, schrieb Stefan Weil:
> 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:
>
> *** stack smashing detected ***:  terminated
> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...
>
> The bug is not windows specific!
>
> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
> and width_mask were removed, and bitmap_intersect() was replaced by
> !bitmap_empty(). The new operation is much shorter and equivalent to
> the old operations.
>
> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
> VNC_DIRTY_WORDS was too small.
>
> Fix both declarations by using the macro which is designed for this
> purpose.
>
> Cc: Corentin Chary<corentincj@iksaif.net>
> Cc: Wen Congyang<wency@cn.fujitsu.com>
> Cc: Gerhard Wiesinger<lists@wiesinger.com>
> Cc: Anthony Liguori<aliguori@us.ibm.com>
> Signed-off-by: Stefan Weil<weil@mail.berlios.de>
> ---
>   ui/vnc.c |    6 +-----
>   ui/vnc.h |    9 ++++++---
>   2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 610f884..34dc0cd 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>       uint8_t *guest_row;
>       uint8_t *server_row;
>       int cmp_bytes;
> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>       VncState *vs;
>       int has_dirty = 0;
>
> @@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>        * 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;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 8a1e7b9..f10c5dc 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>                                   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);
>    

Here I forgot a small possible improvement: use VNC_DIRTY_BITS.
This is purely cosmetics, so I don't send a new patch.


>       VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
>       DisplaySurface *ds;
>   };
> @@ -234,7 +237,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 */
>
>    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
  2011-03-03 20:49   ` [Qemu-devel] " Stefan Weil
@ 2011-03-04  9:02   ` Corentin Chary
  2011-03-04 17:12     ` Stefan Weil
  2011-03-10 23:21   ` [Qemu-devel] " Anthony Liguori
  2 siblings, 1 reply; 9+ messages in thread
From: Corentin Chary @ 2011-03-04  9:02 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Gerhard Wiesinger, Anthony Liguori, qemu-devel

On Thu, Mar 3, 2011 at 9:37 PM, Stefan Weil <weil@mail.berlios.de> wrote:
> 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:
>
> *** stack smashing detected ***:  terminated
> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...
>
> The bug is not windows specific!
>
> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
> and width_mask were removed, and bitmap_intersect() was replaced by
> !bitmap_empty(). The new operation is much shorter and equivalent to
> the old operations.
>
> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
> VNC_DIRTY_WORDS was too small.
>
> Fix both declarations by using the macro which is designed for this
> purpose.
>
> Cc: Corentin Chary <corentincj@iksaif.net>
> Cc: Wen Congyang <wency@cn.fujitsu.com>
> Cc: Gerhard Wiesinger <lists@wiesinger.com>
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Stefan Weil <weil@mail.berlios.de>
> ---
>  ui/vnc.c |    6 +-----
>  ui/vnc.h |    9 ++++++---
>  2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 610f884..34dc0cd 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>     uint8_t *guest_row;
>     uint8_t *server_row;
>     int cmp_bytes;
> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>     VncState *vs;
>     int has_dirty = 0;
>
> @@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>      * 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;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 8a1e7b9..f10c5dc 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>                                 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;
>  };
> @@ -234,7 +237,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 */
>
> --
> 1.7.2.3
>
>

Hi,
Thanks, this patch is a lot cleaner that my early port to new
bitmap/bitops operations.
This patch fix all previous bugs, but not the
framebuffer_update_request + !incremental bug right ?

-- 
Corentin Chary
http://xf.iksaif.net

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-04  9:02   ` Corentin Chary
@ 2011-03-04 17:12     ` Stefan Weil
  2011-03-05 13:02       ` Gerhard Wiesinger
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Weil @ 2011-03-04 17:12 UTC (permalink / raw)
  To: Corentin Chary; +Cc: Gerhard Wiesinger, Anthony Liguori, qemu-devel

Am 04.03.2011 10:02, schrieb Corentin Chary:
> On Thu, Mar 3, 2011 at 9:37 PM, Stefan Weil <weil@mail.berlios.de> wrote:
>> 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:
>>
>> *** stack smashing detected ***:  terminated
>> wine: Unhandled illegal instruction at address 0x6115c7 (thread 
>> 0009), starting debugger...
>>
>> The bug is not windows specific!
>>
>> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
>> and width_mask were removed, and bitmap_intersect() was replaced by
>> !bitmap_empty(). The new operation is much shorter and equivalent to
>> the old operations.
>>
>> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
>> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
>> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
>> VNC_DIRTY_WORDS was too small.
>>
>> Fix both declarations by using the macro which is designed for this
>> purpose.
>>
>> Cc: Corentin Chary <corentincj@iksaif.net>
>> Cc: Wen Congyang <wency@cn.fujitsu.com>
>> Cc: Gerhard Wiesinger <lists@wiesinger.com>
>> Cc: Anthony Liguori <aliguori@us.ibm.com>
>> Signed-off-by: Stefan Weil <weil@mail.berlios.de>
>> ---
>>  ui/vnc.c |    6 +-----
>>  ui/vnc.h |    9 ++++++---
>>  2 files changed, 7 insertions(+), 8 deletions(-)
>>
>> diff --git a/ui/vnc.c b/ui/vnc.c
>> index 610f884..34dc0cd 100644
>> --- a/ui/vnc.c
>> +++ b/ui/vnc.c
>> @@ -2383,7 +2383,6 @@ static int 
>> vnc_refresh_server_surface(VncDisplay *vd)
>>     uint8_t *guest_row;
>>     uint8_t *server_row;
>>     int cmp_bytes;
>> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>>     VncState *vs;
>>     int has_dirty = 0;
>>
>> @@ -2399,14 +2398,11 @@ static int 
>> vnc_refresh_server_surface(VncDisplay *vd)
>>      * 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;
>> diff --git a/ui/vnc.h b/ui/vnc.h
>> index 8a1e7b9..f10c5dc 100644
>> --- a/ui/vnc.h
>> +++ b/ui/vnc.h
>> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>>                                 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;
>>  };
>> @@ -234,7 +237,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 */
>>
>> --
>> 1.7.2.3
>>
>>
>
> Hi,
> Thanks, this patch is a lot cleaner that my early port to new
> bitmap/bitops operations.
> This patch fix all previous bugs, but not the
> framebuffer_update_request + !incremental bug right ?

Hi,

I think so, but I'm not sure about the framebuffer_update_request bug.

At least my patch fixes the most urgent failures (stack corruption),
so I hope it will be applied to git master asap.

There remain more vnc related bugs. Just a short summary of those
which I am aware of:

* Screen update in tight mode has problems (wrong colors, parts missing).

* The threaded vnc server obviously has reentrancy problems (corruption
   of malloc'ed memory. I also noticed memory leaks but maybe these were
   fixed by a patch whcih I noticed on qemu-devel recently.

* The vnc server should not abort connections when it gets unknown commands.

* In reverse mode, the gui is no longer accessible if the vnc listener 
terminates.

Regards,
Stefan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-04 17:12     ` Stefan Weil
@ 2011-03-05 13:02       ` Gerhard Wiesinger
  2011-03-05 13:11         ` Corentin Chary
  0 siblings, 1 reply; 9+ messages in thread
From: Gerhard Wiesinger @ 2011-03-05 13:02 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Anthony Liguori, qemu-devel, Corentin Chary

On Fri, 4 Mar 2011, Stefan Weil wrote:

> Am 04.03.2011 10:02, schrieb Corentin Chary:
>> On Thu, Mar 3, 2011 at 9:37 PM, Stefan Weil <weil@mail.berlios.de> wrote:
>>> 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:
>>> 
>>> *** stack smashing detected ***:  terminated
>>> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), 
>>> starting debugger...
>>> 
>>> The bug is not windows specific!
>>> 
>>> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
>>> and width_mask were removed, and bitmap_intersect() was replaced by
>>> !bitmap_empty(). The new operation is much shorter and equivalent to
>>> the old operations.
>>> 
>>> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
>>> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
>>> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
>>> VNC_DIRTY_WORDS was too small.
>>> 
>>> Fix both declarations by using the macro which is designed for this
>>> purpose.
>>> 
>>> Cc: Corentin Chary <corentincj@iksaif.net>
>>> Cc: Wen Congyang <wency@cn.fujitsu.com>
>>> Cc: Gerhard Wiesinger <lists@wiesinger.com>
>>> Cc: Anthony Liguori <aliguori@us.ibm.com>
>>> Signed-off-by: Stefan Weil <weil@mail.berlios.de>
>>> ---
>>>  ui/vnc.c |    6 +-----
>>>  ui/vnc.h |    9 ++++++---
>>>  2 files changed, 7 insertions(+), 8 deletions(-)
>>> 
>>> diff --git a/ui/vnc.c b/ui/vnc.c
>>> index 610f884..34dc0cd 100644
>>> --- a/ui/vnc.c
>>> +++ b/ui/vnc.c
>>> @@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay 
>>> *vd)
>>>     uint8_t *guest_row;
>>>     uint8_t *server_row;
>>>     int cmp_bytes;
>>> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>>>     VncState *vs;
>>>     int has_dirty = 0;
>>> 
>>> @@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay 
>>> *vd)
>>>      * 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;
>>> diff --git a/ui/vnc.h b/ui/vnc.h
>>> index 8a1e7b9..f10c5dc 100644
>>> --- a/ui/vnc.h
>>> +++ b/ui/vnc.h
>>> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>>>                                 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;
>>>  };
>>> @@ -234,7 +237,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 */
>>> 
>>> --
>>> 1.7.2.3
>>> 
>>> 
>> 
>> Hi,
>> Thanks, this patch is a lot cleaner that my early port to new
>> bitmap/bitops operations.
>> This patch fix all previous bugs, but not the
>> framebuffer_update_request + !incremental bug right ?
>
> Hi,
>
> I think so, but I'm not sure about the framebuffer_update_request bug.
>
> At least my patch fixes the most urgent failures (stack corruption),
> so I hope it will be applied to git master asap.
>
> There remain more vnc related bugs. Just a short summary of those
> which I am aware of:
>
> * Screen update in tight mode has problems (wrong colors, parts missing).
>
> * The threaded vnc server obviously has reentrancy problems (corruption
>  of malloc'ed memory. I also noticed memory leaks but maybe these were
>  fixed by a patch whcih I noticed on qemu-devel recently.
>
> * The vnc server should not abort connections when it gets unknown commands.
>
> * In reverse mode, the gui is no longer accessible if the vnc listener 
> terminates.

Can confirm screen update problems (wrong colors, e.g. red blocks).

Ciao,
Gerhard

--
http://www.wiesinger.com/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-05 13:02       ` Gerhard Wiesinger
@ 2011-03-05 13:11         ` Corentin Chary
  0 siblings, 0 replies; 9+ messages in thread
From: Corentin Chary @ 2011-03-05 13:11 UTC (permalink / raw)
  To: Gerhard Wiesinger; +Cc: Anthony Liguori, qemu-devel

> Can confirm screen update problems (wrong colors, e.g. red blocks).

With wich client, encoding, pixel format ? Does using another client
fix the issue ? Could you provide more informations (wireshark dumps,
screenshots, etc...) ?
Thanks,

-- 
Corentin Chary
http://xf.iksaif.net

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs
  2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
  2011-03-03 20:49   ` [Qemu-devel] " Stefan Weil
  2011-03-04  9:02   ` Corentin Chary
@ 2011-03-10 23:21   ` Anthony Liguori
  2 siblings, 0 replies; 9+ messages in thread
From: Anthony Liguori @ 2011-03-10 23:21 UTC (permalink / raw)
  To: Stefan Weil; +Cc: Corentin Chary, Gerhard Wiesinger, qemu-devel

On 03/03/2011 02:37 PM, Stefan Weil wrote:
> 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:
>
> *** stack smashing detected ***:  terminated
> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), starting debugger...
>
> The bug is not windows specific!
>
> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
> and width_mask were removed, and bitmap_intersect() was replaced by
> !bitmap_empty(). The new operation is much shorter and equivalent to
> the old operations.
>
> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
> VNC_DIRTY_WORDS was too small.
>
> Fix both declarations by using the macro which is designed for this
> purpose.
>
> Cc: Corentin Chary<corentincj@iksaif.net>
> Cc: Wen Congyang<wency@cn.fujitsu.com>
> Cc: Gerhard Wiesinger<lists@wiesinger.com>
> Cc: Anthony Liguori<aliguori@us.ibm.com>
> Signed-off-by: Stefan Weil<weil@mail.berlios.de>

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>   ui/vnc.c |    6 +-----
>   ui/vnc.h |    9 ++++++---
>   2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 610f884..34dc0cd 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>       uint8_t *guest_row;
>       uint8_t *server_row;
>       int cmp_bytes;
> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>       VncState *vs;
>       int has_dirty = 0;
>
> @@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>        * 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;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 8a1e7b9..f10c5dc 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>                                   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;
>   };
> @@ -234,7 +237,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 */
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-03-10 23:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-28 21:34 [Qemu-devel] [PATCH] vnc: Fix heap corruption Stefan Weil
2011-03-01  1:34 ` Wen Congyang
2011-03-03 20:37 ` [Qemu-devel] [PATCH] vnc: Fix stack corruption and other bitmap related bugs Stefan Weil
2011-03-03 20:49   ` [Qemu-devel] " Stefan Weil
2011-03-04  9:02   ` Corentin Chary
2011-03-04 17:12     ` Stefan Weil
2011-03-05 13:02       ` Gerhard Wiesinger
2011-03-05 13:11         ` Corentin Chary
2011-03-10 23:21   ` [Qemu-devel] " Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.